# 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

```