... [Guido] >> We should probably define what happens when you write [p := p for p in >> range(10)]. I propose that this overwrites the loop control variable rather >> than creating a second p in the containing scope -- either way it's probably >> a typo anyway.
[Jacco van Dorp <j.van.d...@deonet.nl>] > My naive assumption would be both. Since this is all about scope, while I'm not 100% sure of what Guido meant, I assumed he was saying "p can only have one scope in the synthetic function: local or non-local, not both, and local is what I propose". For example, let's flesh out his example a bit more: p = 42 [p := p for p in range(10) if p == 3] print(p) # 42? 3? 9? If `p` is local to the listcomp, it must print 42. If `p` is not-local, it must print 9. If it's some weird mixture of both, 3 makes most sense (the only time `p := p` is executed is when the `for` target `p` is 3). > If it's just the insertion of a nonlocal statement like Tim suggested, Then all occurrences of `p` in the listcomp are not-local, and the example above prints 9.. > wouldn't the comprehension blow up to: > > def implicitfunc() > nonlocal p > templist = [] > for p in range(10): > p = p > templist.append(p) > return templist > > ? Yes. > If it were [q := p for p in range(10)], it would be: > > def implicitfunc() > nonlocal q > templist = [] > for p in range(10): > q = p > templist.append(q) > return templist There's no question about that one, because `q` isn't _also_ used as a `for` target. There are two "rules" here: 1. A name appearing as a `for` target is local. That's already the case. 2. All other names (including a name appearing as a binding-expression target) are not local. Clearer? If a name appears as both, which rule applies? "Both" is likely the worst possible answer, since it's incoherent ;-) If a name appears as both a `for` target and as a binding-expression target, that particular way of phrasing "the rules" suggests #1 (it's local, period) is the more natural choice. And, whether Guido consciously knows it or not, that's why he suggested it ;-) > Why would it need to be treated differently ? Because it's incoherent. It's impossible to make the example above print 3 _merely_ by fiddling the scope of `p`. Under the covers, two distinct variables would need to be created, both of which are named `p` as far as the user can see. For my extension of Guido's example: def implicitfunc() nonlocal p templist = [] for hidden_loop_p in range(10): if hidden_loop_p == 3: p = hidden_loop_p templist.append(hidden_loop_p) return templist [Tim] >> A compile-time error would be fine by me too. Creating two meanings >> for `p` is nuts - pick one in case of conflict. I suggested before >> that the first person with a real use case for this silliness should >> get the meaning their use case needs, but nobody bit, so "it's local >> then" is fine. > x = x is legal. Why wouldn't p := p be ? It's easy to make it "legal": just say `p is local, period` or `p is not local, period`. The former will confuse people who think "but names appearing as binding-expression targets are not local", and the latter will confuse people who think "but names appearing as `for` targets are local". Why bother? In the absence of an actual use case (still conspicuous by absence), I'd be happiest refusing to compile such pathological code. Else `p is local, period` is the best pointless choice ;-) _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/