
On Tue, May 08, 2018 at 01:28:59PM -0400, Juancarlo AƱez wrote:
So the way I envision it is that *in the absence of a nonlocal or global
declaration in the containing scope*, := inside a comprehension or genexpr causes the compiler to assign to a local in the containing scope, which is elevated to a cell (if it isn't already). If there is an explicit nonlocal or global declaration in the containing scope, that is honored.
This seems to be getting awfully complicated. Proof? Try to write the docs for the proposed semantics.
Okay, I'll bite. I don't know why you think its complicated: it is precisely the same as ordinary ``=`` assignment scoping rules. It is comprehensions that are the special case. * * * The binding expression ``<name> := <value>`` evaluates the right hand side <value>, binds it to <name>, and then returns that value. Unless explicitly declared nonlocal or global (in which case that declaration is honoured), <name> will belong to the current scope, the same as other assignments such ``name = value``, with one difference. Inside comprehensions and generator expressions, variables created with ``for name in ...`` exist in a separate scope distinct from the usual local/nonlocal/global/builtin scopes, and are inaccessible from outside the comprehension. (They do not "leak".) That is not the case for those created with ``:=``, which belong to the scope containing the comprehension. To give an example: a = 0 x = [b := 10*a for a in (1, 2, 3)] assert x == [10, 20, 30] assert a = 0 assert b = 30
I don't understand why we went so astray from the original requirements, which could all be met by having `if` and `while` accept `as` to bind an expression to a variable that would be local to the structured statement.
That is not the original motivation for binding expressions. The original requirements were specifically for comprehensions. https://mail.python.org/pipermail/python-ideas/2018-February/048971.html This is hardly the only time that something similar has been raised. -- Steve