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

Nick Coghlan ncoghlan at gmail.com
Thu Sep 29 14:00:14 CEST 2011


On Thu, Sep 29, 2011 at 2:27 AM, Matthew J Tretter <matthew at exanimo.com> wrote:
> So has Jan's post-** argument list proposal from June
> (http://mail.python.org/pipermail/python-ideas/2011-June/010479.html) been
> definitively nixed? It seemed the perfect answer given that its similarity
> to the default argument hack makes it intuitive when the evaluation is
> taking place.

It has in my mind. As Guido noted, default argument *names* refer to
ordinary locals, and hence exhibit the same rebinding behaviour as
pre-nonlocal closure references (i.e. reassignments don't persist
across calls, only mutations do). Since we expressly *don't* want that
behaviour, anything directly in the argument list (even after **)
would be inappropriate.

I'm still mulling over the idea of '@state' either as a keyword in its
own right or else as a 'known to the compiler' builtin like super so
that the following would work (as several people have suggested):

    @state(n=0, lock=threading.Lock())
    def global_counter():
        n += 1
        return n

The special casing of super() is something that annoys me though, and
making 'state' a keyword would be extraordinarily disruptive, so I'm
also intrigued by the suggestion of reusing 'nonlocal' for the same
purpose:

    @nonlocal(n=0, lock=threading.Lock())
    def global_counter():
        n += 1
        return n

With that spelling, the nonlocal statement would declare references to
pre-existing closure variables in an outer scope, while the nonlocal
decorator would declare new function state variables, implicitly
creating the outer scope without all the boilerplate.

I must admit, the 'some kind of decorator' syntax is growing on me,
especially the nonlocal variant.

Cheers,
Nick.

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



More information about the Python-ideas mailing list