[Python-Dev] statically nested scopes

Jeremy Hylton jeremy@alum.mit.edu
Wed, 1 Nov 2000 16:18:49 -0500 (EST)


>>>>> "MAL" == M -A Lemburg <mal@lemburg.com> writes:

  MAL> [pre-PEP] This will break code... I'm not sure whether it's
  MAL> worth going down this path just for the sake of being able to
  MAL> define functions within functions.
  >>
  >> How will this break code?  Any code written to use the scoping
  >> rules will not work today.
  >>
  >> Python already allows programs to define functions within
  >> functions.  That's not at issue.  The issue is how hard it is to
  >> use nested functions, including lambdas.

  MAL> The problem is that with nested scoping, a function defined
  MAL> within another function will suddenly reference the variables
  MAL> of the enclosing function as globals and not the module
  MAL> globals... this could break code.

That's right it could, in the unlikely case that someone has existing
code today using nested functions where an intermediate function
defines a local variable that shadows a variable defined in an
enclosing scope.  

It should be straightfoward to build a tool that would detect this
case.

It would be pretty poor programming style, so I think it would be fine
to break backwards compatibility here.

  MAL> Another problem is that you can't reach out for the defining
  MAL> module globals anymore (at least not in an easy way like
  MAL> today).

I think we would want to keep globals implemented just the way they
are.  The compiler would need to determine exactly which variables are
access from enclosing scopes and which are globals.

  MAL> Wouldn't it be a better idea to somehow add native acqusition
  MAL> to Python's objects ?
  >>
  >> Seriously, I don't see how acquistion addresses the same issues
  >> at all.  Feel free to explain what you mean.

  MAL> It's not related to *statically* nested scopes, but is to
  MAL> dynamically nested ones. Acquisition is basically about the
  MAL> same thing: you acquire attributes from containers. The only
  MAL> difference here is that the containment relationships are
  MAL> defined at run-time.

Static scoping and dynamic scoping are entirely different beasts,
useful for different things.  I want to fix, among other things,
lambdas.  That's a static issue.
 
  MAL> We already have a slot which implements the "contains"
  MAL> relationship. All we'd need is a way for a contained object to
  MAL> register itself with the container in a way that doesn't
  MAL> produce cycles.
  >>
  >> The contains relationship has to do with container objects and
  >> their contents.  A function's environment is not a container in
  >> the same sense, so I don't see how this is related.
  >>
  >> As I noted in the PEP, I don't see a compelling reason to avoid
  >> cycles.

  MAL> Ok, we have cycle GC, but why create cycles when you don't have
  MAL> to (Python can also be run without GC and then you'd run into
  MAL> problems...) ?

If we can avoid cycles, sure.  I would prefer a simple design that
allowed cycles to a complicated design that avoided them.  Exactly
where to draw the line between simple and complex is a matter of
taste, of course.

Jeremy