← →

Python’s lambda is broken!

Andrej Bauer



I quite like Python for teaching. And people praise it for the lambda construct which is a bit like $\lambda$-abstraction in functional languages. However, it is broken!

To see how

lambda is broken, try generating a list of functions $[f_0, …, f_9]$ where $f_i(n) = i + n$. First attempt:

>>> fs = [(lambda n: i + n) for i in range(10)] >>> fs[3](4) 13

Wait a minute, fs[3](4) ought to be 3 + 4 = 7 ! It looks like all 10 functions share the same “last” value of i , which is 9 . Indeed:

>>> [f(4) for f in fs] [13, 13, 13, 13, 13, 13, 13, 13, 13, 13]

This is certainly unexpected. Let us try to get around the problem by not using lambda :

>>> fs = [] >>> for i in range(10): ... def f(n): return i+n ... fs.append(f) ... >>> [f(4) for f in fs] [13, 13, 13, 13, 13, 13, 13, 13, 13, 13]

Still not working, so the reason is deeper, probably in the way environments are handled. Maybe like this:

>>> fs = [] >>> for i in range(10): ... def f(n, i=i): return i+n ... fs.append(f) ... >>> [f(4) for f in fs] [4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

Victory! But try explaining to students what is going on.

Just to be sure, Haskell does the right thing, of course!

Prelude> let fs = [(

-> i + n) | i <- [0..9]] Prelude> [f(4) | f <- fs] [4,5,6,7,8,9,10,11,12,13]

What were the implementors of Python thinking?!