<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 1 March 2018 at 06:34, 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"><span class="">On Thu, Mar 1, 2018 at 7:28 AM, Paul Moore <<a href="mailto:p.f.moore@gmail.com">p.f.moore@gmail.com</a>> wrote:<br>
> I've no idea how that would work under statement-local names either, though.<br>
><br>
>     boom = lambda: boom()<br>
>     boom()<br>
><br>
> is just an infinite recursion. I'm less sure that the as version is.<br>
> Or the alternative form<br>
><br>
>     ((lambda: boom()) as boom)()<br>
><br>
> I know you can tell me what the implementation does - but I can't<br>
> reason it out from the spec.<br>
<br>
</span>The only part that isn't yet properly specified is how this interacts<br>
with closures, and that's because I really don't know what makes<br>
sense. Honestly, *any* situation where you're closing over a SLNB is<br>
going to have readability penalties, no matter what the spec says.<br></blockquote><div><br></div><div>My suggestion is to just flat out prohibit it - if closures can capture the reference, then it isn't a statement local name binding any more, and it's reasonable to ask folks to promote it to a regular function local variable.<br><br></div><div>This is another area where syntactic disambiguation on the reference side would help<br></div><div><br>    # prints 12 twice<br>    <span class="gmail-im">x = 12<br>    if (1 as .x) == 1:<br>
        def foo():<br>
</span>            return x<br>        print(foo())<br>    print(foo())<br></div><div><br><div><div>    # prints 1 twice<br></div>    <span class="gmail-im">x = 12<br>    if (1 as .x) == 1:<br></span></div><div><span class="gmail-im">        x = .x<br></span></div><div><span class="gmail-im">
        def foo():<br>
</span>            return x<br>        print(foo())<br>    print(foo())<br><br></div>    # Raises UnboundLocalError<br>    <span class="gmail-im">x = 12<br>    if (1 as .x) == 1:<br>
        def foo():<br>
</span>            return .x<br>        print(foo())<br>    print(foo())<br><br></div><div>That last example could potentially even raise a compile time error during the symbol table analysis pass, since the compiler would *know* there's no statement local by that name in the current lexical scope, and statement local references wouldn't have a runtime fallback to module globals or the builtins the way regular variable references do.<br><br></div><div>Another perk of using the ".NAME" syntax is that we could extend it to allow statement local name bindings in for loops as well:<br><br></div><div>    for .i in range(10):<br></div><div>        print(.i) # This is fine<br></div><div>    print(.i) # This is an error (unless an outer statement also sets .i)<br></div><div></div><div><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>