# [Python-Dev] Lexical scoping in Python 3k

Guido van Rossum guido at python.org
Mon Jul 3 23:00:38 CEST 2006

```On 7/3/06, Andrew Koenig <ark at acm.org> wrote:
> > Much though the Algol 60 tickles my nostalgia (it was my first
> > programming language!) I don't think that it's a particularly strong
> > argument. I like to think that we have better ways these days.
>
> Even if so, that's not the point I was trying to make.  The point is that
> there is a programming technique that is widely used, works in many
> languages, and has been around for 45 years; and when you try to use it in
> Python, it fails.

That's true for lots of things that have been around for a long time.

Can you provide a better example? (The use of += is not particularly
relevant to the example; it could just as well have said "result =
result + i".)

> I believe that such failures, even if there are alternative ways of solving
> the problems that engender them, are barriers to learning that should be
> removed if it is possible to do so without substantial cost.

And that is of course the crucial question.

Probably the only proposal that has any chance of succeeding is to
extend the 'global' statement so that it also applies to variables in
intermediate outer scopes; or perhaps a new keyword (since "global" is
not a very good name for the extended semantics). We would have to
decide what this example would do:

def outer():
def inner1(x):
global a
a = x
def inner2():
return a
return inner1, inner2
f1, f2 = outer()
g1, g2 = outer()
f1(42)
g1(0)
print f2()    # Does it print 0 or 42 ???

In current Python this prints 0: there's only one (global) variable a,
and the call to g1(0) overrides the value that was stored by f1(42).
If global were changed to mean "nonlocal" what should it do? The
question the example poses is that a is not initialized except in
inner1() -- we somehow have to decide whether this is an error, or
whether it chooses some well-defined outer scope, with the choices
being the nearest enclosing scope or the outermost (truly global)
scope. We have one guideline: if there is exactly one outer scope that
defines a variable named a, we would like it to be referenced (by the
'global a') statement and the variable references governed by it
automatically. Also, of there's more than one such scope, we'd like it
to reference the innermost one. But this doesn't have a natural
extension to what should happen if there's no such scope!

Perhaps the best solution would be to make it an error if there wasn't
a visible variable named a in an outer scope. That would suit me fine
because I'd like to migrate towards more static analysis of variables
anyway. If that means equipping modues with traps for attempts to
store arbitrary variables into their namespaces, that's fine with me
(as long as there's some escape -- and of course instancs and classes
remain fully dynamic).

--