[Python-Dev] statically nested scopes

Guido van Rossum guido@python.org
Thu, 02 Nov 2000 02:59:47 -0500


> [Guido]
> > [Jeremy and Tim argue about what to do about write access for
> > variables at intermediate levels of nesting, neither local nor
> > module-global.]
> >
> > I'll risk doing a pronouncement, even though I know that Jeremy (and
> > maybe also Tim?) disagree.
> >
> > You don't need "write access" (in the sense of being able to assign)
> > for variables at the intermediate scopes, so there is no need for a
> > syntax to express this.

[Tim]
> I can live with that!  Reference-only access to intermediate scopes would
> address 99% of current gripes.  Of course, future gripes will shift to that
> there's no rebinding access.  If we have to support that someday too, my
> preferred way of spelling it in Python requires explicit new syntax, so
> adding that later would not break anything.

Exactly my point.

> > Assignments are to local variables (normally) or to module-globals (when
> > 'global' is used).  Use references search for a local, then for a local of
> > the containing function definition, then for a local in its container,
> 
> The Pascal standard coined "closest-containing scope" to describe this
> succinctly, and I recommend it for clarity and brevity.

Thanks, that's a good term.  And the principle is totally
uncontroversial.

> > and so forth, until it hits the module globals, and then finally it looks
> > for a builtin.
> >
> > We can argue over which part of this is done statically and which part
> > is done dynamically: currently, locals are done dynamically and
> > everything else is done statically.
> 
> I'm not sure what you're trying to say there, but to the extent that I think
> I grasp it, I believe it's backwards:  locals are static today but
> everything else is dynamic (and not in the sense of "dynamic scoping", but
> in the operational sense of "requires runtime search to resolve non-local
> names", while local names are fully resolved at compile-time today (but in
> the absence of "exec" and "import *")).

Oops, yes, I had it backwards.

As I said elsewhere, in Python 3000 I'd like to do it all more
statically.  So perhaps we should look up nested locals based on
static information too.  Thus:

  x = "global-x"

  def foo():
      if 0:
          x = "x-in-foo"
      def bar():
	  return x
      return bar

  print foo()()

should raise UnboundLocalError, not print "global-x".

--Guido van Rossum (home page: http://www.python.org/~guido/)