[Python-Dev] PEP for Better Control of Nested Lexical Scopes

Josiah Carlson jcarlson at uci.edu
Tue Feb 21 08:03:08 CET 2006


"Almann T. Goo" <almann.goo at gmail.com> wrote:
> > Mechanisms which rely on manipulating variables within closures or
> > nested scopes to function properly can be elegant, but I've not yet seen
> > one that *really* is.
> 
> This really isn't a case for or against what I'm proposing since we
> can already do this in today's Python with mutable variables in an
> enclosing scope (see below).  I am proposing a language change to help
> make closures more orthogonal to the scoping constructs that are
> already in place for the global scope.

Actually, it is.  Introducing these two new keywords is equivalent to
encouraging nested scope use.  Right now nested scope use is "limited" or
"fraught with gotchas".  Adding the 'use' and 'scope' keywords to label
levels of scopes for name resolution will only encourage users to write
closures which could have written better or not written at all (see some
of my later examples).  Users who had been using closures to solve
real problems "elegantly" likely have not been affected by the current
state of affairs, so arguably may not gain much in 'use' and 'scope'.


> > You state that using classes can be "heavy handed",
> > but one of the major uses of classes is as a *namespace*. Many desired
> > uses of closures (including the various uses you have outlined)
> > is to hide a *namespace*, and combining both closures with classes can offer
> > that to you, without requiring a language change.
> 
> Closures are also used in more functional styles of programming for
> defining customized control structures (those Ruby folks like them for
> this purpose).

Except that Python does not offer user-defined control structures, so
this is not a Python use-case.


> > Of course using
> > classes directly with a bit of work can offer you everything you want
> > from a closure, with all of the explcitness that you could ever want.
> 
> Really, the easiest way to emulate what I want in today's Python is to
> create a mutable object (like a dict or list) in the enclosing scope
> to work around the semantic that the first assignment in a local scope
> binds a new name.  Doing this seems rather un-natural and forcing the
> use of classes doesn't seem more natural
> 
> def incgen( inc = 1 ) :
>   env = [ 6 ]
>   def incrementor() :
>     env[ 0 ] += inc
>     return env[ 0 ]
>   return incrementor

Indeed, there are other "more natural" ways of doing that right now.

    #for inc=1 cases
    from itertools import count as incgen

    #for limited-range but arbitrary integer inc cases:
    from sys import maxint
    def incgen(env=6, inc=1):
        return iter(xrange(env, (-maxint-1, maxint)[inc>0], inc)).next

Or if you want to get fancier, a generator factory works quite well.

    def mycount(start, inc):
        while 1:
            yield start
            start += inc

    def incgen(env=6, inc=1):
        return mycount(env, inc).next

All of which I find clearer than the closure example... but this isn't a
discussion on how to create counters, it's a discussion about the use of
closures and nested scopes, or more specifically, Python's lack of
orthogonality on lexically nested scopes.  Which brings up a question:
what is your actual use-case for nested scopes and closures which makes
the current "use a mutable or class" awkward?  I would like to see a
non-toy example of its use which would not be clearer through the use of
a class, and which is nontrivially hampered by the current state of
Python's nested scopes and name resolution.

 - Josiah



More information about the Python-Dev mailing list