Hmm... In the end I think the language design issue is with functions (and
how they capture variable references rather than values), and fixing it by
changing the for-loop is still just a band-aid, with other problems and
inconsistencies. Agreed that the fix 'x=x' essentially always works, and
that having to write 'for new x in ...' is no better, because you'd still
forget it.

Maybe we should consider introducing a new kind of function that captures
values instead? That would be a much more principled fix.

--Guido

On Thu, Nov 19, 2020 at 4:20 PM Ben Rudiak-Gould <benrud...@gmail.com>
wrote:

> On Wed, Nov 18, 2020 at 9:54 PM Greg Ewing <greg.ew...@canterbury.ac.nz>
> wrote:
>
>> Essentially the idea is this: If the loop body contains a def or lambda
>> that captures the loop variable, then on each iteration, a new binding
>> is created, instead of changing an existing binding.
>>
>> Note that this is *not* the same as introducing a new scope. All the
>> bindings share the same name, and from the perspective of code outside
>> the nested function, nothing changes -- the name is still bound to
>> the most recent value, and can still be accessed after the loop has
>> finished.
>>
>
> The problem I see is that nested functions referring to the same variable
> can be defined outside loops as well. If you define a helper before the
> loop that refers to the loop variable, it won't work inside the loop or
> ever again after the loop has terminated. Even if the helper has nothing to
> do with the loop and just uses the same generic variable name like "item",
> it'll break. It's fairly common to reuse the same identifier for different
> purposes inside functions.
>
> As much as I hate the current behavior, I feel like the proposed behavior
> is too confusing and weird.
>
> Another problem is that the capturing behavior would depend on whether the
> variable is in a function or module or class scope, since cells only exist
> in function scopes.
>
> Also, "while x := get_next_thing():" loops wouldn't behave consistently
> with for loops.
>
>     for new x in some_iterator:
>>        ...
>>
>
> I don't think special syntax would help. I've been bitten by this problem
> fairly often, and 100% of the time I've been able to solve it by adding x=x
> to the argument list to capture by value. I can't imagine I'd ever want to
> capture a loop variable by reference, especially if the cell being
> referenced no longer has a name outside of the nested function when the
> nested function is called. I get in trouble because I forget to write x=x
> where it's necessary, but if I forget to write x=x then I'd forget to write
> "new x" too.
>
> _______________________________________________
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/VKHB722PLUMZJPCMHEM2MB4HBEDI463Y/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/H7S3LEVRHGPLLGVPVSHD54THO2G2PDY3/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to