# [Python-ideas] For-loop variable scope: simultaneous possession and ingestion of cake

Guido van Rossum guido at python.org
Sat Oct 4 01:06:54 CEST 2008

```On Fri, Oct 3, 2008 at 3:51 PM, Neil Toronto <ntoronto at cs.byu.edu> wrote:
> Guido van Rossum wrote:
>>
>> On Fri, Oct 3, 2008 at 3:37 AM, Greg Ewing <greg.ewing at canterbury.ac.nz>
>> wrote:
>>>
>>> However, it's not lambda that's broken, it's the for loop.
>>
>> I disagree. If you propose to change the for-loop to create new cells,
>> you would also need to introduce new syntax for introducing new cells
>> in other contexts. While it is common (especially when demonstrating
>> the problem) to use a for loop variable in the lambda, the same
>> problem exists when the variable referenced is constructed via other
>> means.
>
> Like this?
>
>    >>> i = 0
>    >>> f = lambda: i
>    >>> i = 1
>    >>> f()
>    1

No, I was thinking of examples like this:

>>> a = []
>>> for i in range(10):
...     j = i**2
...     a.append(lambda: j)
...
>>> for f in a: print f()
81
81
.
.
.
81
>>>

This leads me to reject claims that "the for-loop is broken" and in
particular clamoring for fixing the for-loop without allowing us to
fix this example.

> Whether the for loop is broken really depends on what's meant by "broken".
> Some would say the very idea of cells is broken because *values* ought to be
> closed over. That's bunk, of course. ;) But I think most people are
> comfortable with the above example.
>
> If you unroll the loop, current behavior makes perfect sense:
>
>    >>> f = []
>    >>> for i in [0, 1]: f.append(lambda: i)
>    ...
>    >>> [g() for g in f]
>    [1, 1]
>
>    >>> f = []
>    >>> i = 0
>    >>> f.append(lambda: i)
>    >>> i = 1
>    >>> f.append(lambda: i)
>    >>> [g() for g in f]
>    [1, 1]
>
>
> But the deal with loops is that we don't usually unroll them in our heads
> when we reason about their behavior. We generally consider each iteration in
> isolation, or as an abstract single iteration. (After all, it only appears
> once in the program text.) If iterations need to depend on each other, it's
> almost always done via something that already exists outside the loop.
>
> The semantics that best matches that kind of reasoning is fully scoped
> loops. Python 4000 for scoped blocks?

--