Grzegorz Chrupala wrote: ... >> >>> def foo(n): >> ... box = [n] >> ... def foo(i): box[0]+=i; return box[0] >> ... return foo >> ... > > It's still a hack that shows an area where Python has unnecessary > limitations, isn't it? Debatable, and debated. See the "Rebinding names in enclosing scopes" section of http://www.python.org/peps/pep-0227.html . Essentially, Guido prefers classes (and instances thereof) to closures as a way to bundle state and behavior; thus he most emphatically does not want to add _any_ complication at all, when the only benefit would be to have "more than one obvious way to do it". Guido's generally adamant stance for simplicity has been the key determinant in the evolution of Python. Guido is also on record as promising that the major focus in the next release of Python where he can introduce backwards incompatibilities (i.e. the next major-number-incrementing release, 3.0, perhaps, say, 3 years from now) will be the _elimination_ of many of the "more than one way to do it"s that have accumulated along the years mostly for reasons of keeping backwards compatibility (e.g., lambda, map, reduce, and filter, which Guido mildly regrets ever having accepted into the language). > As Paul Graham says (<URL:http://www.paulgraham.com/icad.html>): > >> Python users might legitimately ask why they can't just write >> >> def foo(n): >> return lambda i: return n += i The rule Python currently use to determine whether a variable is local is maximally simple: if the name gets bound (assigned to) in local scope, it's a local variable. Making this rule *any* more complicated (e.g. to allow assignments to names in enclosing scopes) would just allow "more than one way to do it" (making closures a viable alternative to classes in more cases) and therefore it just won't happen. Python is about offering one, and preferably only one, obvious way to do it, for any value of "it". And another key principle of the Zen of Python is "simple is better than complex". Anybody who doesn't value simplicity and uniformity is quite unlikely to be comfortable with Python -- and this should amply answer the question about the motivations for reason number 1 why the above foo is unacceptable in Python (the lambda's body can't rebind name n in an enclosing scope). Python draws a firm distinction between expressions and statements. Again, the deep motivation behind this key distinction can be found in several points in the Zen of Python, such as "flat is better than nested" (doing away with the expression/statement separation allows and indeed encourages deep nesting) and "sparse is better than dense" (that 'doing away' would encourage expression/statements with a very high density of operations being performed). This firm distinction should easily explain other reasons why the above foo is unacceptable in Python: n+=i is a statement (not an expression) and therefore it cannot be held by a 'return' keyword; 'return' is a statement and therefore cannot be in the body of a 'lambda' keyword. >> or even >> >> def foo(n): >> lambda i: n += i And this touches on yet another point of the Zen of Python: explicit is better than implicit. Having a function implicitly return the last expression it computes would violate this point (and is in fact somewhat error-prone, in my experience, in the several languages that adopt this rule). Somebody who is unhappy with this drive for explicitness, simplicity, uniformity, and so on, cannot be happy with Python. If he wants a very similar language from most points of view, BUT with very different philosophies, he might well be quite happy with Ruby. Ruby does away with any expression/statement distinction; it makes the 'return' optional, as a method returns the last thing it computes; it revels in "more than one way to do it", clever and cool hacks, not perhaps to the extent of Perl, but close enough. In Ruby, the spaces of methods and data are separate (i.e., most everything is "an object" -- but, differently from Python, methods are not objects in Ruby), and I do not think, therefore, that you can write a method that builds and returns another method, and bind the latter to a name -- but you can return an object with a .call method, a la: def outer(a) proc do |b| a+=b end end x = outer(23) puts x.call(100) # emits 123 puts x.call(100) # emits 223 [i.e., I can't think of any way you could just use x(100) at the end of such a snippet in Ruby -- perhaps somebody more expert of Ruby than I am can confirm or correct...?] but apart from this it seems closer to what the above quotes appear to be probing for. In particular, it lets you be MUCH, MUCH denser, if that is your purpose in life, easily squeezing that outer function into a (short) line. Python is NOT about making code very dense, indeed, as above mentioned, it sees _sparseness_ as a plus; a typical Pythonista would cringe at the density of that 'outer' and by contrast REVEL at the "sparsity" and "explicitness" (due to the many names involved:-) of, e.g.: def make_accumulator(initial_value): accumulator = Bunch(value=initial_value) def accumulate(addend): accumulator.value += addend return accumulator.value return accumulate accumulate = make_accumulator(23) print accumulate(100) # emits 123 print accumulate(100) # emits 223 (using the popular Bunch class commonly defined as: class Bunch(object): def __init__(self, **kwds): self.__dict__.update(kwds) ). There is, of course, a cultural gulf between this verbose 6-liner [using an auxiliary class strictly for reasons of better readability...!] and the terse Ruby 1-liner above, and no doubt most practitioners of both languages would in practice choose intermediate levels, such as un-densifying the Ruby function into: def outer(a) proc do |b| a+b end end or shortening/densifying the Python one into: def make_accumulator(a): value = [a] def accumulate(b): value[0] += b return value[0] return accumulate but I think the "purer" (more extreme) versions are interesting "tipizations" for the languages, anyway. Alex