On Oct 3, 3:44 am, greg <[EMAIL PROTECTED]> 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. -- http://mail.python.org/mailman/listinfo/python-list