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

Nick Coghlan ncoghlan at gmail.com
Thu Sep 29 15:30:35 CEST 2011

On Tue, Sep 27, 2011 at 4:38 PM, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> With regard to "own" or "static", my feeling is that this
> kind of feature (i.e. mutable shared state visible only to
> one function) is an anti-pattern in language design. We
> have much better ways nowadays of sharing state without
> making it completely global, such as modules and classes.

In explaining to someone why I think this issue of function state
variables is worth exploring, I described it as being important for
the same reason as closures are important. That's also why I've been
describing it as syntactic sugar for a particular *kind* of closure
usage. The reason I think closures themselves are important is that
gets back into the 'algorithm with state' vs 'data with behaviour'
contrasting views of a problem. Sometimes one view is more productive,
sometimes the other, and there's blurry ground in the middle where
either can work. As programmers, our best bet is to learn both
modelling tools and then judge which is most appropriate for the
problem at hand.

One thing I definitely got out of this thread is that I think we need
better tools for introspecting closure and generator internal state,
so I'd be interested in seeing proposals for additions to the inspect
module on that front.

However, getting back to the original topic, the @nonlocal suggestion
is definitely growing on me, since it seems to combine all the
elements of the current equivalent that I'd like to shorten into one
concise syntax:

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

would become:

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

It's presence in the decorator list hints that this is something
happening outside the functions ordinary local scope, as well as
indicating when the initialisation happens. The 'nonlocal' then ties
in with how they behave from the point of view of the code in the
function body.


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

More information about the Python-ideas mailing list