<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 28 February 2018 at 08:27, Chris Angelico <span dir="ltr"><<a href="mailto:rosuav@gmail.com" target="_blank">rosuav@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This is a suggestion that comes up periodically here or on python-dev.<br>
This proposal introduces a way to bind a temporary name to the value<br>
of an expression, which can then be used elsewhere in the current<br>
statement.<br>
<br>
The nicely-rendered version will be visible here shortly:<br>
<br>
<a href="https://www.python.org/dev/peps/pep-0572/" rel="noreferrer" target="_blank">https://www.python.org/dev/<wbr>peps/pep-0572/</a></blockquote><div><br></div><div>Thanks for putting this together!<br></div><div><br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Statement-local name bindings can be used in any context, but should be<br>
avoided where regular assignment can be used, just as `lambda` should be<br>
avoided when `def` is an option.<br>
<br></blockquote><div> </div><div>[snip]<br> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
2. The current implementation [1] implements statement-local names using<br>
a special (and mostly-invisible) name mangling. This works perfectly<br>
inside functions (including list comprehensions), but not at top<br>
level. Is this a serious limitation? Is it confusing?<br></blockquote><div><br></div><div>It isn't clear to me from the current PEP what the intended lifecycle of the bound names actually is, especially for compound statements.<br><br>Using list comprehensions as your example currently hides that confusion, since they create an implicit nested scope anyway, so the references will go away when the list comprehension terminates no matter what.<br><br></div><div>So I think it would be useful to have some other examples in the PEP to more explicitly answer that question:<br><br></div><div> x = (expr as y)<br></div><div> assert x == y # Does this pass? Or raise NameError for 'y'?<br><br></div><div> if (condition as c):<br></div><div> assert c # Does this pass? Or raise NameError for 'c'?<br></div><div> else:<br></div><div><div> assert not c # Does this pass? Or raise NameError for 'c'?<br></div><div> assert c or not c # Does this pass? Or raise NameError for 'c'?<br><br></div><div> class C:<br></div><div> x = (True as y)<br></div><div> assert C.y # Does this pass? Or raise AttributeError for 'y'?<br></div><div><br></div><div>I think it would also be worth explicitly considering a syntactic variant that requires statement local references to be explicitly disambiguated from regular variable names by way of a leading dot:<br><br> result = [[(f(x) as .y), .y] for x in range(5)]<br><br> (.x, (1 as .x), .x) # UnboundLocalError on first subexpression<br></div><div> (x, (1 as .x), .x) # Valid if 'x' is a visible name<br></div><br><div> x = (expr as .y)<br></div><div> assert x == .y # UnboundLocalError for '.y'<br><br></div><div> if (condition as .c):<br></div><div> assert .c # Passes<br></div><div> else:<br></div><div><div> assert not .c # Passes<br></div><div> assert .c or not .c # UnboundLocalError for '.c'<br><br><div> class C:<br></div><div> x = (True as .y)<br></div><div> assert C..y # SyntaxError on the second dot<br></div></div></div><br></div><div>Since ".NAME" is illegal for both variable and attribute names, this makes the fact statement locals are a distinct namespace visible to readers as well as to the compiler, and also reduces the syntactic ambiguity in with statements and exception handlers.<br><br></div><div>Cheers,<br></div><div>Nick.<br clear="all"></div></div><br>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">Nick Coghlan | <a href="mailto:ncoghlan@gmail.com" target="_blank">ncoghlan@gmail.com</a> | Brisbane, Australia</div>
</div></div>