Nested scopes: why is it weird?

Scott Long scott at
Fri Sep 7 19:56:25 CEST 2001

Alex Martelli wrote:

> > >>> from __future__ import nested_scopes
> > >>> def a():
> > ...   def b():
> > ...     k = x
> > ...     x = 0
> The x name in procedure b is LOCAL -- the compiler knows it,
> because x is re-bound in b's scope.  (Incidentally, you can
> never rebind a name from a lexically-nested local scope
> in your scope; you CAN rebind a global name, if you use the
> global statement at the start of a function).

The spirit of Python seems to favor binding as late as possible
(sometimes it seems like the binding happens after my script has
finished running ;-)

In this spirit, why not place variables into scopes dynamically as well?
Instead of having the separate LOAD_FAST and LOAD_GLOBAL why not just
LOAD, and the first LOAD executed is what finally scopes the name?
Before raising an objection, read my other comments below (and feel free
to object at that point).

> > My first beef here is, why is the exception called UnboundLocalError?
> Because x is a local name, and it is not yet bound when it is
> first used in b's first instruction.

Ah, this is a semantic misunderstanding for me. In most statically
scoped languages, one speaks of binding a name to a *scope*, not to a

> > But my main concern is that this way of selecting a binding seems very
> > unintuitive. Shouldn't the first statement referencing x be the
> > statement that specifies the binding of x? In this case, shouldn't "k =
> *In general*, how could the compiler tell what the first statement
> IS, that _references_ name x within a given scope?  Assuming you
> mean, "first to execute".  The compiler _might_ assign some
> arbitrary ordering, of course.  But having:
>     if a>b:
>         y=x
>     else:
>         x=y
> have *TOTALLY* different semantics from:
>     if b>=a:
>         x=y
>     else:
>         y=x
> when it SEEMS they're totally equivalent, would be truly weird, so
> I don't think you mean "first in some arbitrary order (such as,
> longest-first, or lower-line-number-first, or whatever)".

The problem doesn't occur if you associate scopes with suites instead of
function defs (equivalent to block scopes in C/C++ for example). A suite
(or block) has a definite "first statement". Yes, I know that isn't how
it works. But my C++ brain keeps wanting it to work that way, so I get
confused a lot.

Well, time to shut up.


More information about the Python-list mailing list