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

Paul Moore p.f.moore at gmail.com
Fri Mar 2 06:50:57 EST 2018


On 2 March 2018 at 11:15, Nick Coghlan <ncoghlan at gmail.com> wrote:
> On 2 March 2018 at 19:05, Paul Moore <p.f.moore at gmail.com> wrote:
>>
>> The problem with statement local variables is that the extent over
>> which the name is in scope is not as clear to the human reader (the
>> rules the *compiler* follows may be precise, but they aren't obvious
>> to the human reader - that's the root of the debate I'm having with
>> Chris over "what the reference implementation does isn't a sufficient
>> spec"). In particular, assignment statements are non-obvious, as shown
>> by the examples that triggered your suggestion of a "." prefix.
>
> Those examples didn't trigger the suggestion: the suggestion was borne from
> the fact that I don't think it should be possible to close over statement
> locals.

Ah, OK. If closing over statement locals isn't allowed, then yes, they
are a different type of name, and you may need to distinguish them. On
the other hand, I'm not sure I agree with you that it shouldn't be
possible to close over statement locals. I can see that there are a
lot of *difficulties* with allowing it, but that's not the same.
What's your logic for saying you shouldn't be able to close over a
statement local name? What is fundamentally different about them that
makes them unsuitable to work like all other names in Python?

> PEP 3150 ended up needing syntactic markers as well, to handle the forward
> references to names set in the `given` clause while staying within the LL(1)
> parsing design constraint imposed on Python's grammar.

Is this basically about forward references then? Certainly the "a = (1
as a)" examples are a problem because of forward references. And the
problem here is that we can't use the normal solution of simply
prohibiting forward references ("Name assigned before declaration"
errors) because - well, I'm not quite sure why, actually. Surely if
you're naming a subexpression that's repeated, you can always just
choose to name the *first* occurrence and use that name for the rest?
I guess the exception is statements that introduce or bind names
(assignments, for, etc). I'd still be inclined to just say prohibit
such cases (if we can't, then we're back into the territory of
implementation difficulties driving the design).

This all still feels to me like an attempt to rescue the proposal from
the issues that arise from not treating statement-local names exactly
like any other name.

> Right, but that extra notation *does* convey useful information to a reader
> that better enables local reasoning about a piece of code. Currently, if
> you're looking at an unfamiliar function and see a name you don't recognise,
> then you need to search the whole module for that name to see whether or not
> it's defined anywhere. Even if it's missing, you may still need to check for
> dynamic injection of module level names via globals().

Hang on, that's how all existing names in Python work (and in pretty
much any language that doesn't require explicit declarations). Surely
no-one is trying to suggest that this is a fundamental flaw?

> Seeing ".name" would be different (both for the compiler and for the human
> reader): if such a reference can't be resolved explicitly within the scope
> of the current statement, then *it's a bug* (and the compiler would be able
> to flag it as such at compile time).

Sorry, but you could use exactly that argument to propose that
function local variables should be prefixed with "$". I don't buy it.

I guess I remain -1 on the proposal, and nothing that's getting said
about how we can make it work is doing anything to persuade me
otherwise (quite the opposite).

Paul


More information about the Python-ideas mailing list