[Python-Dev] Lexical scoping in Python 3k (original) (raw)

Ka-Ping Yee python-dev at zesty.ca
Sat Jul 1 01:03:14 CEST 2006


On Fri, 30 Jun 2006, Guido van Rossum wrote:

On 6/30/06, Ka-Ping Yee <python-dev at zesty.ca> wrote: > On Fri, 30 Jun 2006, Andrew Koenig wrote: > > I hope Py3000 has lexical scoping a la Scheme... > > Me too -- that would be really nice.

That's not a very constructive proposal (especially since I don't know Scheme). Perhaps you could elaborate on what needs to change?

Sorry! I should have been more clear.

Right now, Python supports the existence of nested scopes:

a = 3
def f():
    a = 4
    def g():
        a = 5
        print a     # prints 5
    g()
    print a         # prints 4
f()
print a             # prints 3

The above example shows that there are three distinct scopes, and that each one has a distinct binding named 'a' -- assigning to one doesn't affect the others.

a = 3
def f():
    b = 4
    def g():
        c = 5
        print a, b, c       # i can see all three
    g()
f()

The above example shows that all of the scopes can be read. But in today's Python, not all of the scopes can be written.

a = 3
def f():
    b = 4
    def g():
        c = 5
        a, b, c = 0, 1, 2   # changes local c, not outer a and b
    g()
f()

The code in g() can affect its own local, 'c', and it can affect the global variable 'a' if it declares 'global a', but no matter what you write in g(), it cannot assign to 'b' (or to any other intermediate scope).

This is a strange limitation and it would be nice to remove it. The asymmetry comes from Python having one foot in the new paradigm of nested lexical scopes and one foot still in the older paradigm of only two scopes, local and global.

Most other languages that support lexical scoping (including Scheme, JavaScript, Ruby, Perl, E, Java, Smalltalk) provide a uniform way to read and write to scopes at all levels. This is done by letting programmers specify the scope in which they want a variable bound (usually with a keyword like "var" in JavaScript, "my" in Perl, or "define" in E).

So here are some thoughts on how Python might be adjusted to support this. I'm not saying these would be the only ways, but at least they're some ideas to start with.

In JavaScript, the "var" keyword is required whenever you want to declare a local variable. Anything without "var" is assumed to be a global name. The cleanest and most consistent solution that comes to mind would be to adopt exactly this for Python.

Without "var":

a = 3                       # global
def f():
    b = 4                   # global
    def g():
        c = 5               # global
        a, b, c = 0, 1, 2   # changes all three globals
    g()
f()
print a, b, c               # prints 0, 1, 2

With "var":

var a = 3                   # global
def f():
    var b = 4               # local to f
    def g():
        var c = 5           # local to g
        a, b, c = 0, 1, 2   # changes outer a, outer b, and c
        print c             # prints 2
    g()
    print b                 # prints 1
f()
print a                     # prints 0
print b                     # no such name
print c                     # no such name

But that is a big change. Perhaps it would be too unpythonic to suddenly require declarations for all local variables. So an alternative would be to retain the default assumption that undeclared variables are local. Here's what we'd get:

Without "var":

a = 3
def f():
    b = 4
    def g():
        c = 5
        a, b, c = 0, 1, 2   # changes local c, not outer a and b
    g()
f()

With "var":

var a = 3
def f():
    var b = 4
    def g():
        var c = 5
        a, b, c = 0, 1, 2   # changes outer a, outer b, and c
    g()
f()

Now i think this is a little bit weird, because the statement "var b = 4" in an outer scope changes the meaning of "b" in an inner scope. But it does have the virtue of retaining behaviour compatible with today's Python, while offering a way to get proper lexical scopes for those who want to use them.

Thoughts? Other ideas?

-- ?!ng



More information about the Python-Dev mailing list