Just why did people start using Python anyway?
ndanger.org
ndanger.org
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.
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.
You really can't overestimate how big a deal this is.
Is there a programming language which doesn't have an Emacs mode?
I thought about writing one, but then came to my senses.
I wrote an ed mode for Emacs once, though...
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.
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.
Ironically, I may be switching from Python to Lua now, for the same reason.
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.
>>> 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.)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.
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.Good to know it's possible, though I'd rather it handle closures / lexical scoping directly.
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!"
enddoHow is that better than Python?
for i in range( 1, 100 ):
print "Python!" (1..100).each do
puts "Ruby"
end 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.(Counting only the loop-related characters, leaving out whitespace.)
Unless anyone has a shorter way of doing something one hundred times?
Look, I'm only too familiar with the annoyances of Fortran, but let's allow it this one thing, okay?
>>> 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?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.
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;