greg <[EMAIL PROTECTED]> 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. -- http://mail.python.org/mailman/listinfo/python-list