[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?
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-ideas
mailing list