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

Nick Coghlan ncoghlan at gmail.com
Mon Sep 26 15:47:28 CEST 2011

On Mon, Sep 26, 2011 at 7:45 AM, Paul Moore <p.f.moore at gmail.com> wrote:
> On 26 September 2011 12:34, Nick Coghlan <ncoghlan at gmail.com> wrote:
>> On Mon, Sep 26, 2011 at 2:56 AM, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
>>> So, your proposed use of 'nonlocal' would actually be declaring
>>> a name to be *local*. That strikes me as weird and perverse.
>> Ah, but it *wouldn't* be local, that's the point - it would be stored
>> on the function rather than on the frame, and hence be shared across
>> invocations.
> Hmm, its lifetime is non-local, but the visibility is still local. My
> instincts associate the word "(non-)local" with visibility rather than
> lifetime.
> If you want a bikeshed to colour in, maybe "persistent" is a better
> keyword for this:
> def counter():
>    persistent n as 1
>    print(n)
>    n += 1

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.

It may be easier to turn things around and specifically look at it
from the "syntactic sugar" point of view:

# Current syntax

def _outer(): # Boilerplate
    VAR = EXPR
    def FUNC(): # Real function name is hidden
        nonlocal VAR # VAR repeated
        # Do stuff with VAR, including rebinding it
    return f # Boilerplate
FUNC = _outer() # Boilerplate and FUNC repeated

Most of that code is noise: the interesting aspects are that:
1. There is a function called FUNC() available for use
2. VAR survives across invocations of FUNC()
3. At the first invocation of FUNC(), the initial value of VAR will be EXPR

So, let's offer a syntax that just includes those 3 pieces of
interesting information without the boilerplate:

def FUNC(): # Function of interest is not hidden in a nested scope
    nonlocal VAR from EXPR  # Shared variable and initial value
    # Do stuff with VAR

Is anyone going to *guess* what that means without looking it up?
Probably not. But are they going to *forget* what it means once they
learn it? Also probably not.

"I can guess what this means without reading the docs or having
someone explain it to me" is setting the bar too high for what a
single keyword can possibly hope to convey. The bar needs to be
whether or not it serves as a useful mnemonic to recall the
functionality once a user already know what means. For me, 'nonlocal'
fits that bill, especially when the feature is described as syntactic
sugar for a somewhat common use case for the existing lexical scoping


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

More information about the Python-ideas mailing list