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


_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to