Saturday, October 20, 2007

python closure problem


>>> def acc_gen(initial_value):
... total = initial_value
... def acc(to_add):
... total += to_add
... return total
... return acc
...
>>> a = acc_gen(5)
>>> a(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in acc
UnboundLocalError: local variable 'total' referenced before assignment
I'm shocked! That doesn't make sense to me. Cfr:

[1]> (defun acc-gen (total) (lambda (to_add) (incf total to_add)))
ACC-GEN
[2]> (setf a (acc-gen 5))
#
[3]> (funcall a 3)
8
[4]> (funcall a 3)
11

I'm a little bit clueless, but I'm pretty sure that this is what they mean with "python doesn't support proper lexical closures"

2 comments:

Anonymous said...

I get the same bad feeling, but thanks to Peter Norvig (http://www.norvig.com/python-lisp.html), you can do that:
>>> def acc_gen(initial_value):
... total = [initial_value]
... def acc(to_add):
... total[0] = total[0] + to_add
... return total[0]
... return acc

I think that's because Python lists are mutable but integers are not.

jvdneste said...

interesting! thanks!