|
I think one key thing is that lambdas are second-class citizens in Python in terms of the kinds of code you can express. Python lambdas can only contain one single expression and nothing else. For more complicated functions, in particular any function that requires statements, you are always required to use nested named functions, e.g. myList = [[1, 2], [3, 4], [5, 6]]
for elem in myList:
del elem[0]
cannot be done using a lambda, as map(lambda elem: del elem[0], myList)
results in an error. Until Python 3, that also meant that map(lambda elem: print elem, myList)
was also a syntax error because of the print statement. For a more elaborate example, consider the following JavaScript function which returns a function that increments a counter every time its called and returns the value before it was incremented: function makeCounter() {
var value = 0;
return function() {
return value ++;
}
}
You would use this as follows: > c = makeCounter();
> c();
0
> c();
1
... and so forth
There is no way to implement this in Python using lambda; the closest equivalent (assuming Python 3 for the nonlocal keyword) is def makeCounter():
value = 0
def count():
nonlocal value
tmp, value = value, value + 1
return tmp
return count
because there's no way to have that assignment take place in a lambda.Of course, Haskell has neither state nor statements, so the above examples don't literally show why Haskell's lambdas are necessarily superior, but the point isn't that Python disallows assignment in lambdas; it's that Python's lambdas can only express a subset of possible functions, while JavaScript and Haskell (and Scheme &al.) don't have that limitation. |
As for your second example, I would consider using "yield".