[Python-ideas] Tweaking closures and lexical scoping to include the function being defined

Nick Coghlan ncoghlan at gmail.com
Mon Sep 26 17:33:47 CEST 2011


On Mon, Sep 26, 2011 at 10:24 AM, Paul Moore <p.f.moore at gmail.com> wrote:
> On 26 September 2011 14:47, Nick Coghlan <ncoghlan at gmail.com> wrote:
>> Adding new keywords is a big, big step that demands a compelling
>> justification. Now that I have come up with a way to make this
>> syntactic sugar for existing usage of nonlocal rather than a new
>> concept, I flatly oppose introduction of a new name for something
>> which is, at a fundamental level, just a variation on existing
>> functionality. I'd rather continue with the status quo indefinitely if
>> people truly find this variant intolerable.
>
> I agree entirely. My point here wasn't to suggest that this needs a
> new keyword, but rather that the proposal uses an unnatural keyword to
> avoid needing a new keyword.
>
> Your argument that this is a simple extension of the semantics of
> "nonlocal" is reasonable when viewing nonlocal in terms of lifetimes.
> My contention is that most people view nonlocal in terms of visibility
> (and in that view, the two uses of nonlocal are jarringly dissimilar).

I agree it's certainly a *new* way of looking at the problem, but I
don't agree that that necessarily makes it a *wrong* way to look at
it. Should we invent a new keyword, or abandon the concept of (more)
elegant syntax for shared internal function state, just to avoid
teaching people that reference locality involves elements of both
visibility *and* lifecycle?

Instead, I contend that it is precisely this aspect of the language
that makes mutable default arguments such a point of confusion. Since
we *don't* separate out the explanations of visibility vs lifetime
when discussing closure references, default arguments become a special
snowflake that people need to learn about without being able to slot
it into a broader framework.

I believe we can actually make the concepts involved in both default
argument lifecycles and the 3.x super() implementation more
semantically coherent by *embracing* nonlocal as influencing both
visibility *and* lifetime and clearly articulating that as a core
language concept in relation to closures.

We *already* have the following possibilities:

    local visibility, local lifetime: 'ordinary' local variable
referenced solely from the executing frame
    local visibility, nonlocal lifetime: default argument expressions,
local variable referenced from inner function that survives current
invocation
    nonlocal visibility, nonlocal lifetime: 3.x __class__ reference,
closure reference to outer lexically containing scope, global
references

My proposed syntax is just a way to explicitly create new entries in
that middle category - variables with local visibility and nonlocal
lifetime. So 'global VAR' and 'nonlocal VAR' would continue to declare
that a NAME belongs in the third category and is initialised somewhere
else, while 'nonlocal VAR from EXPR' would say "this has nonlocal
lifetime, but local visibility, so here's the initial value since it
won't be provided anywhere else".

Regards,
Nick.

P.S. Really nice point about the visibility vs lifecycle distinction.
I think it actually *strengthens* my argument about the current lack
of a coherent semantic framework in this space, though.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list