closures and dynamic binding

Aaron "Castironpi" Brady castironpi at gmail.com
Fri Oct 3 13:11:04 EDT 2008


On Oct 3, 3:44 am, greg <g... at cosc.canterbury.ac.nz> wrote:
> jhermann wrote:
> > I didn't see this mentioned in the thread yet: the double-lambda is
> > unnecessary (and a hack).
>
> Well, the alternative -- abusing default argument values --
> is seen by many to be a hack as well, possibly a worse one.
> It doesn't work in general, e.g. it fails if the function
> needs to be called with a variable number of arguments.
>
> The double lambda is conceptually more sound in some
> ways, and can be made to work correctly in all cases.
>
> The root of the problem actually has nothing to do with
> lambdas or static vs. non-static scoping. It's the fact
> that Python's for-loop doesn't create a new environment
> for the loop variable each time around, but re-uses a
> slot in the containing environment.
>
> Contrast this with Scheme, where the equivalent of a
> for-loop *does* create a new environment for each
> value of the loop variable. Effectively it's using a
> double lambda, except that one of the lambdas is
> folded into the syntax of the loop, so you don't
> notice it.
>
> So if anything were to be done to the language to
> fix this, it really should be focused on fixing the
> semantics of the for-loop. Unfortunately, the
> fact that the loop variable leaks out of the scope
> of the loop is regarded as a feature, so anything
> which changes that seems to be a non-starter.
>
> --
> Greg

I agree that the default argument syntax is an abuse, but it
accomplishes exactly what I want: to create a copy of a namespace.  I
don't think there's a way to create a closure in Python without
another function, so you might need new syntax if you wanted to.

Otherwise, using function syntax, I want a new namespace on each
iteration that nests inside the old one, except for one variable which
overrides the outer scope.  I agree that a new variable isn't the
obviously correct meaning of a for loop, and functions are the same as
a new scope, just you have to call them, so why not use them as is?

(untested)
for i in range( 3 ):
  def f( n ):
    def g( ):
      return n
  return g
  closures[ i ]= f( i )

Or:

(non-standard)
for i in range( 3 ):
  closure f( i ):
    def g( ):
      return i
  return g
  closures[ i ]= f

Here the only difference is whether you call 'f' or not.  'closure'
would theoretically "call itself", and make a copy of its scope upon
execution of the definition, overriding the arguments.  So, functions
are the same.



More information about the Python-list mailing list