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

Nick Coghlan ncoghlan at gmail.com
Tue Sep 27 04:43:38 CEST 2011


On Mon, Sep 26, 2011 at 9:32 PM, Guido van Rossum <guido at python.org> wrote:
> Interesting discussion! Very enlightening.

Indeed! It has certainly clarified many aspects for me.

> But after all that I'm still unconvinced that the new concept should
> be tied to the nonlocal keyword.

<snip>

> For all these reasons, sorry Nick, but I really don't think any syntax
> based on nonlocal will do it, even "nonlocal <var> from <expr>".

Well, the semantics of a 'nonlocal-from' initialised nonlocal variable
would be different from a bare nonlocal declaration (i.e. the new form
would create a new name binding only visible in local scope, so it
wouldn't get shared across functions within the same outer function
and is legal in top-level functions), just as they would be with a new
keyword.

So I'm not prepared to completely give up on this one yet - it took me
years of poking at the issue to come up with the idea of reusing
nonlocal as the keyword, so I hope people will take some time to
consider the idea of using the term to refer to variations in both
visibility and lifecycle rather than strictly limiting it to refer
only to the visibility aspect.

> I see two options open at this point.
>
> 1) Bikeshed until we've come up with the right keyword. I think that
> apart from the keyword the optimal syntax is entirely fixed;
> "<keyword> <variable> = <expression>" is the way to go. (I suppose we
> could argue about how to declare multiple variables this way.) I would
> be okay with using either "static" or "own" for the keyword.
> Personally, I don't really mind all the negative baggage that static
> has, but a Google code search for \bown\s= shows way fewer hits than
> for \bstatic\s= (both with lang:^python$ case:yes).

There have certainly been plenty of proposals over the years. The ones
I recall off the top of my head are:

once
static
persistent
shared
closure
own
atdef
deftime

The baggage something like 'static' brings with it would be even more
misleading than that associated with 'nonlocal', and the others are
either seriously ugly or else aren't particularly suggestive as
mnemonics. At least 'nonlocal' indicates something related to function
closures is in play, even if it isn't the exact same thing as is
currently meant by a bare declaration.

Really, the mechanism suffers from the same problem that led to the
choice of nonlocal for PEP 3104 in the first place: the important part
of the declaration lies in making it clear to the compiler and the
reader that the specified name is *not* a normal local variable.
Exactly what it *is* instead will depend on the specifics of the code
- it may be shared state, it may be something else, the only way to
find out for sure is to look at the code and see how it is used.
Choosing a keyword based on any given use case (such as 'shared')
makes the construct seem odd when used for another use case (such as
early binding).

I agree the two concepts (bare nonlocal and initialised nonlocal) are
not the same. However, I also believe they're close enough that a
slight broadening of the definition of 'nonlocal' is preferable to
trying to come up with a completely new term that is both readable,
usefully mnemonic and not laden down with unrelated baggage either
from Python itself or from other languages.

> 2) Give up, and keep using the default argument hack. You can protect
> your arguments from accidentally being overridden by using a "lone
> star" in the argument list (PEP 3102) and a __private naming
> convention. The lone star prevents accidental overriding when too many
> positional arguments are given. The __private provides sufficient
> protection against misguided attempts to provide a value for such
> "arguments", even if for functions outside a class it is purely
> psychological. (Note that someone who *really* wanted to mess with a
> cell's variable could also do it.)

Despite what I wrote earlier in the thread, I don't think we actually
need to declare the idea *dead* if you don't currently like 'nonlocal'
as the keyword. Perhaps the 'nonlocal' idea will grow on you (it
certainly did on me, the longer I considered the idea), or perhaps you
or someone else will come up with an appropriate keyword that everyone
considers reasonable.

Regards,
Nick.

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



More information about the Python-ideas mailing list