Hacker News new | past | comments | ask | show | jobs | submit login
Just why did people start using Python anyway? (ndanger.org)
22 points by prakash on Oct 9, 2008 | hide | past | favorite | 44 comments



Because one of the major problems of writing code in collaboration with other programmers is communicating the meaning of existing code. And python is one of the few languages out there that had an explicit goal of being legible.


I'd argue that Python goes beyond legibility of code since most of the Python community seems to have settled on very similar coding standards. Not just silly things like 4-space indents, but the way the code is written. It makes it really easy to pick up foreign Python code.

The explicit over implicit here also helps. Yes, it is a pain when dealing with only your code (why do I have to keep doing self.var_name when Java just lets me say var_name), but when dealing with foreign code, it means you have explicit scope.

I'd also argue that Python's import is just wonderful. Where many languages like their secret-sauce methods, Python's explicit imports makes it incredibly simple to find where a name is coming from. While Java has the convention of import java.util.*, Python has the convention of from math import log - which imports the name log into your file. So, you see log used in the file, you can easily look at the import to see where it's coming from - and yes, it isn't hard to imagine identical names in different libraries and you shouldn't need to know that something with the same name is defined in two places that usually aren't used together. Want the whole math library, just import math and then use math.func() so that you still know where everything is coming from!

For what it's worth, I think Python's syntax is a bit ugly, but it's standard! Python code never looks that foreign and having foreign code look familiar to you is just wonderful. It might not matter when you have your 1-person project, but when dealing with the code of other's, it's wonderful.


It makes it really easy to pick up foreign Python code.

You really can't overestimate how big a deal this is.


I'll point out that it is for this exact reason that we're using Fortress: for scientific code, it's so much more readable it's amazing.


So, Chapel. Erlang, CUDA, etc. aren't as readable as Fortress?


Yes. The baked in use of units is incredibly helpful (best use of any static typing I've seen, I tell you), but the biggest thing is that the LaTeX formatting and larger character set allows code to look like what it does. The code and the formulas look like the very same thing because they are the same thing.


yeah i second this point.

i'm a fairly large perl project at work and it makes me want to poke my eyes out.

python on the other hand always makes me smile. it's simple and elegant.


Python is simple, easy to read, and has been around and active since 1991. Because of that, it also benefits from being a very stable, fast platform (for an interpreted language), and has a huge standard library (http://docs.python.org/modindex.html). If it's not in the standard library, you can probably find it somewhere. A "killer app" is a paradigm that computer people have been using since visicalc, but I'm not sure it applies to every situation.


"Haskell... even has an Emacs mode."

Is there a programming language which doesn't have an Emacs mode?


I don't think there are major modes for brainfuck or unlambda.

I thought about writing one, but then came to my senses.


if you are writing brainfuck code, I doubt you are going to use emacs as your environment. More likely ed or cat...


I know, it was a joke.

I wrote an ed mode for Emacs once, though...


No killer apps? What about this http://www.python.org/about/quotes/ ?


Because other people used it, composed good code and even others adopted it. This resulted in a high-profile Python scene and good code. I think that many new ideas were contributed and it was fun to share ideas. This resulted in a rapid development of toolkits, frameworks and software. If you wanted to be part of this, you had to use Python.

But I think it is the same with JavaScript, Ruby, FreeBSD, PosgreSQL and many more hip foobars; In contrast, Java, PHP, many (not all) Microsoft products, Linux (partly) allured so many bad coders that it is simply boring to work through their code.


The article is mistitled. The question it actually poses is: "Why isn't Haskell as popular as Python yet?"

While I dearly love Python, I don't know enough about Haskell to adequately answer this. The article makes it sound like Haskell is doing all the same right things as Python -- although this apparently isn't paying off yet, so the article must be overlooking some factors.


I tried Python out right when I was getting incredibly frustrated with a Perl program that had grown too large for its own good. Python seemed so much cleaner that I switched immediately. Its standard library is quite nice, though not quite as large as CPAN.

Ironically, I may be switching from Python to Lua now, for the same reason.


In all seriousness, the only reason I use Python over Lua is for the library. Lua is far more flexible and extensible, but it has a very sore lack of standard libraries like you can find with Python. But I keep my fingers crossed, and continue to use Lua as an interpreter inside my C apps, where the lack of libraries is a non-issue because everything I need to use is a custom API exported from C.


> but it has a very sore lack of standard libraries like you can find with Python

Agreed. I find it quite a bit more elegant overall, and I decided to just jump in and do my throwaway scripts in Lua and see how much of a difference that makes. If I like it enough to write a few small libraries along the way, everybody wins.

Lua has tail-call elimination, coroutines, closures, and lambdas. I'm pretty sure Python has none of these, except for (possibly) a limited form of coroutines. (The Python lambda is too crippled, its closures are broken.) Lua is also one of the most deliberately portable languages I've seen, too. I have a hunch it would be a great language for bootstrapping a Lisp or Scheme compiler, though I haven't tried this yet.


Python closures work well. (The lambda is syntactically crippled.)


   >>> def makeAdder(x):
   	def inc(y):
   		return y+x
   	return inc
   
   >>> f = makeAdder(3)
   >>> f(4)
   7
So far, so good.

   >>> def makeAdder2(x):
   	v = x
   	def inc(y):
   		v += y
   		return v
   	return inc
   
   >>> f2 = makeAdder2(3)
   >>> f2(4)
   
   Traceback (most recent call last):
     File "<pyshell#15>", line 1, in <module>
       f2(4)
     File "<pyshell#13>", line 4, in inc
       v += y
   UnboundLocalError: local variable 'v' referenced before assignment
   >>>
It looks like you can't mutate variables in a closure. Am I doing it wrong? If you really can't, that seriously limits their power.

--

In Lua:

  > function adder(x)
      local v = x
      function inc(y)
          v = v + y
          return v
          end
      return inc
      end
  >> >> >> >> >> >> >> > f = adder(3)
  > =f(4)
  7
  > =f(4)
  11
  > =f(4)
  15
  >
Works fine. (Also, the syntax is really clean.)


Python 3.0 fixes this with the nonlocal statement. However, you are correct that this doesn't work in Python 2.5 and earlier.


Ok, thanks.


Argh - I can't get the formatting to work.

def makeAdder2(x):

    v = [x,]
    def inc(y):
        v[0] += y
   	return v[0]
    return inc
works just fine in all pythons with closures (2.0 and above?)

def makeAdder2(x):

    def inc(y, v=[x,]):
        v[0] += y
   	return v[0]
    return inc
Also works and provides a mechanism for resetting the state.


Interesting. So keeping a reference to a list with the value works, but the value directly doesn't? Thanks for the note.

Good to know it's possible, though I'd rather it handle closures / lexical scoping directly.


You may need to add a 'global' statement or something similiar. If you are going to mutate a variable in a function Python assumes that you want to create a new variable in that scope.

Generally I do not mutate variables as far as possible, so I have not hit this problem myself, yet. Perhaps there is someone more knowledgeable about Python to step in.


But it's not a global variable, it's scoped within the closure. So, this means Python doesn't have lexical scoping?


It has. Just the syntax was a bit awkward when modifying variables of higher scope. See sibling comment.


I found Stackless Python while trying to throw together an idea for a massively parallel algorithm... worked beautifully and led me to django. Python's simplicity made me feel like I could hit the ground running, but I'd say the frameworks got me hooked.


I started using Python in 1999, because I was tired of Perl's weirdness and looking for something new. I don't use it much these days, but still have a lot of respect for it.


what do you use these days?


I got more involved with Tcl over time ( http://tcl.apache.org/ and some other stuff) and over the past couple of years have been moving towards Ruby for most of my scripting/web needs.


Wait, you couldn't stand the weirdness of perl, but you like Tcl?

All I can remember about Tcl from my months of using it is the ugly, ugly loops:

  for {set i 1} { $i <= 100 } { incr i } {
   puts "Well, that wasn't ugly syntax!"
  }
Incidentally, Fortran, for all its other ugliness, has the best for loop I know:

  do i = 1, 100
   write(*,*) "Hooray, Fortran!"
  enddo


Tcl is extremely straightforward once you figure it out:

http://antirez.com/articoli/tclmisunderstood.html

'for' is a command that takes 4 arguments:

    {set i 1} - eval'ed once at start time.
    { $i <= 100 } - an expression that is checked each time to determine whether to continue
    { incr i } - eval'ed each time
    { ... the rest ... } the body is eval'ed each time.
Everything in Tcl is like that - it's extremely easy to figure out and there are no surprises. It's also extremely easy to implement. Here's Hecl's for loop:

    case FOR:
    /* The 'for' command. */
    /* start */
    interp.eval(argv[1]);
    /* test */
    while (Thing.isTrue(interp.eval(argv[2]))) {
	try {
	    /* body */
	    interp.eval(argv[4]);
	} catch (HeclException e) {
	    if (e.code.equals(HeclException.BREAK)) {
		break;
	    } else if (e.code.equals(HeclException.CONTINUE)) {
	    } else {
		throw e;
	    }
	}
	/* next */
	interp.eval(argv[3]);
    }
    break;


> Incidentally, Fortran, for all its other ugliness, has the best for loop I know:

How is that better than Python?

    for i in range( 1, 100 ):
        print "Python!"


That's not a good idiom, because it only allows you to loop over small ranges:

  >>> for i in range(1000000000):
  ...     print i
  ... 
  python2.4(1261) malloc: *** vm_allocate(size=4000002048) failed (error code=3)
  python2.4(1261) malloc: *** error: can't allocate region
  python2.4(1261) malloc: *** set a breakpoint in szone_error to debug
  Traceback (most recent call last):
    File "<stdin>", line 1, in ?
  MemoryError
Why attempt to allocate such a large list when you just want to do something several times?


for i in xrange(1000000000): print i

xrange() addresses the problem you describe and has been in Python since, like, forever. However, range() is nicer for learning the language, since it's easy to see how it composes into a list.


Yes, I know. It's just bad that people are taught one way of iterating, and then may or may not learn the right way at some later time.


Ruby's nice and compact too:

    (1..100).each do
      puts "Ruby"
    end


Maybe it's just me, but I like doing it this way in Ruby:

   100.times { puts "Ruby" }
Not that there's anything wrong with your approach, but I just like the way that my code reads almost like English.


Eleven characters! Beats Fortran by four. We have a winner!

(Counting only the loop-related characters, leaving out whitespace.)

Unless anyone has a shorter way of doing something one hundred times?


I think if you want to talk about advantages though, with Fortran you're going to want to talk about the speed, not the brevity. Ruby is quite poky by comparison.


Oh, for sure, but I'd hate to get drawn into the world's Nth general discussion of the advantages and disadvantages of programming languages. That would be dull.


Actually, compared to batty discussions of economics or "politics!!!!!!", it's kind of soothing.


Well, it's shorter by five characters, and you can type it without touching the shift key.

Look, I'm only too familiar with the annoyances of Fortran, but let's allow it this one thing, okay?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: