closures and dynamic binding

Hrvoje Niksic hniksic at xemacs.org
Fri Oct 3 05:42:57 EDT 2008


greg <greg at cosc.canterbury.ac.nz> writes:

> The root of the problem actually has nothing to do with lambdas or
> static vs. non-static scoping. It's the fact that Python's for-loop
> doesn't create a new environment for the loop variable each time
> around, but re-uses a slot in the containing environment.
>
> Contrast this with Scheme, where the equivalent of a for-loop *does*
> create a new environment for each value of the loop variable.

Note that Python's semantics of "for" regarding closures are not
unique to Python.  Common Lisp behaves similar to Python in this
regard:

* (loop for i from 0 to 2 collect (lambda () i))
(#<CLOSURE... {A86F3CD}> #<CLOSURE... {A86F3E5}> #<CLOSURE... {A86F3FD}>)
* (mapcar #'funcall *)
(3 3 3)

Other looping constructs, such as "do", behave in equivalent fashion.

> So if anything were to be done to the language to fix this, it
> really should be focused on fixing the semantics of the
> for-loop. Unfortunately, the fact that the loop variable leaks out
> of the scope of the loop is regarded as a feature, so anything which
> changes that seems to be a non-starter.

I don't think it has anything to do with variable leaking out of the
loop.  Common Lisp doesn't leak the loop variable, and it behaves the
same.  It is more a result of the different views of what iteration
is.  Common Lisp and Python define iteration in terms of repeating the
same instructions over and over, not different from what C does, in
which case it makes sense to reuse the same environment for all loop
passes.  (Python's language ref defines that a standard "assignment"
is done for each new iteration.)  In contrast, Scheme regards
iteration as a special case of recursion, and R5RS "do" prescribes
assigning loop variables to "fresh locations" to match what recursion
normally does.  In most cases both definitions exhibit the same
behavior, but unfortunately not when closures are created inside the
loop.



More information about the Python-list mailing list