closures and dynamic binding

Terry Reedy tjreedy at udel.edu
Fri Oct 3 22:47:27 CEST 2008


greg 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.

I disagree.  It is one way to evaluate an expression when a function is 
compiled.

> It doesn't work in general, e.g. it fails if the function
> needs to be called with a variable number of arguments.

So?  Many things do not work 'in general'. If one wants multiple 
closures with a variable number of arguments, one should use a def 
statement and some other binding method, such as given below

Here are four ways to get the list of closures desired:
All print 0 ... 9 with for f in lst:  print(f()) #3.0

lst = []
for i in range(10):
     lst.append(eval("lambda: %d" %i))

# use exec instead of eval with def statement instead of lambda expression

lst = []
def f(i): return lambda: i
for i in range(10):
     lst.append(f(i))

#I would most likely use this, with a def instead of lambda inside f for 
any real, non-trivial example.

def populate(n):
   n -= 1
   if n >= 0: return populate(n)+[lambda:n]
   else: return []
lst = populate(10)

# body recursion

def populate(i,n,lst):
     if i < n: return populate(i+1,n,lst+[lambda:i])
     else: return lst
lst = populate(0,10,[])

# tail recursion

Terry Jan Reedy




More information about the Python-list mailing list