On 2 March 2018 at 11:15, Nick Coghlan email@example.com wrote:
On 2 March 2018 at 19:05, Paul Moore firstname.lastname@example.org 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).