[Python-ideas] PEP 572: Statement-Local Name Bindings

Nick Coghlan ncoghlan at gmail.com
Thu Mar 1 00:08:09 EST 2018


On 1 March 2018 at 06:34, Chris Angelico <rosuav at gmail.com> wrote:

> On Thu, Mar 1, 2018 at 7:28 AM, Paul Moore <p.f.moore at gmail.com> wrote:
> > I've no idea how that would work under statement-local names either,
> though.
> >
> >     boom = lambda: boom()
> >     boom()
> >
> > is just an infinite recursion. I'm less sure that the as version is.
> > Or the alternative form
> >
> >     ((lambda: boom()) as boom)()
> >
> > I know you can tell me what the implementation does - but I can't
> > reason it out from the spec.
>
> The only part that isn't yet properly specified is how this interacts
> with closures, and that's because I really don't know what makes
> sense. Honestly, *any* situation where you're closing over a SLNB is
> going to have readability penalties, no matter what the spec says.
>

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.

This is another area where syntactic disambiguation on the reference side
would help

    # prints 12 twice
    x = 12
    if (1 as .x) == 1:
        def foo():
            return x
        print(foo())
    print(foo())

    # prints 1 twice
    x = 12
    if (1 as .x) == 1:
        x = .x
        def foo():
            return x
        print(foo())
    print(foo())

    # Raises UnboundLocalError
    x = 12
    if (1 as .x) == 1:
        def foo():
            return .x
        print(foo())
    print(foo())

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.

Another perk of using the ".NAME" syntax is that we could extend it to
allow statement local name bindings in for loops as well:

    for .i in range(10):
        print(.i) # This is fine
    print(.i) # This is an error (unless an outer statement also sets .i)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180301/d311c321/attachment-0001.html>


More information about the Python-ideas mailing list