[Python-ideas] Multi Statement Lambdas
Terry Reedy
tjreedy at udel.edu
Sun Oct 21 19:16:02 EDT 2018
On 10/21/2018 12:28 PM, Andreas Winschu wrote
> A def function has to be named.
In general, this is a good thing. It often improves tracebacks.
Perhaps more importantly, name facilitate testing and mocking.
> Wheres a lambda expression can be passed anonymously to any other
> function as an argument.
Except for relatively trivial expressions, this is a bad thing. All
functions created from lambda expressions get the same pseudo-name
'<lambda>'. This can make tracebacks worse. Perhaps more importantly,
proper testing may become harder.
> /map(lambda x: x**2, array)/
It is obvious what this trivial expression does, but without a name or
comment or context indicating intent, how do I know that it is correct?
Trivial examples evade the issues that arise even with multiline
expressions, let alone multiple statements.
>>> for i in map(lambda x: x **
2, 'abc'):
print(i)
Traceback (most recent call last):
File "<pyshell#19>", line 2, in <module>
2, 'abc'):
File "<pyshell#19>", line 2, in <lambda>
2, 'abc'):
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
> vs
> /def powers2(x)/
> / x**2/
> /map(powers2, array)/
>>> def pow2(x):
return (x **
2)
>>> for i in map(pow2, 'abc'): print(i)
Traceback (most recent call last):
File "<pyshell#26>", line 1, in <module>
for i in map(pow2, 'abc'): print(i)
File "<pyshell#24>", line 3, in pow2
2)
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
Given that there might be a hundred functions named '<lambda>', I think
the specific name is a bit helpful.
> Coming up with a name here is not needed, as the operation is expressive
> enough.
It is clear as to the meaning. And testing that pow2(3) equals 9 is
pretty useless. But you are proposing something else: adding anonymous
multiple statement functions, where a name *and testing* is usually
needed. Justification for what we have today is not justification for a
major change.
tkinter uses callbacks with widget commands and scheduling. idlelib has
77 matches for the re '[( ,]command='. 47 are followed by
'self.somemethod'; 26 by other function names, and 4 by lambda
expressions. All four of the latter are trivial calls of a named
method: self.somemethod(value). So when all named non-test functions
are tested, all non-test callbacks will be tested.
In spite of newbie problems with lambda, I am happy to not have to
define trivial test functions like this.
def undoNone(): return d.undo_event(None)
But doubt that I would rather write any of the independent
production-code functions and methods as anonymous lambda constructs.
--
Terry Jan Reedy
More information about the Python-ideas
mailing list