On Wed, Jan 6, 2021 at 9:27 PM Steven D'Aprano <steve@pearwood.info> wrote:
I'm glad that things like Perl one-liners, obfuscated C, and sewerage treatment works exist...
:)
Multi-statment anonymous functions are, in my opinion, overrated, and a (slight) code smell. If your lambda is so complex it requires more than a single expression, shouldn't it have documentation and tests?
I don't think this is an example of the Blub paradox. I can see that there are uses for such multi-statement lambdas, but I don't think that the benefits outweigh the costs. The benefits exist in the small niche:
- code that could be an anonymous function; - and the code is complex enough to require multiple statements; - but not so complex that it needs testing or documentation; - or an informative function name for debugging; - and putting it into a named function is a non-trivial burden; - perhaps because there is no appropriate self-descriptive name.
There are some other use-cases, where something is syntactically an anonymous function, but in practice, it's a part of some larger construct. In Python, a lot of those use-cases are handled by some form of function decorator or maybe abuse of class notation, but I wouldn't rule out the possibility that there are cases where those are suboptimal. Consider UI building, for instance. You need to have event handler functions, and you need to build your UI. There are a few possibilities: 1) Magic names within a class. If you have a thing called "btn_frob", and a function called "btn_frob_clicked", then that function will automatically be called when the button is clicked. 2) Objects have function decorators as attributes, so "@btn_frob.clicked" will define the function to be called when the button is clicked. 3) Name all your event handlers and place them out of line, allowing you to use simple function parameters to associate them. 4) Define a dict with attributes, and use lambda functions to handle events eg {"clicked": lambda: ...} Nothing's perfect, and nothing ever will be, but you can see how option 4 would become more viable with multiline lambdas. The function can definitely be anonymous, it's definitely complex enough to require multiple statements (or even just a single statement, which is too much for a current Python lambda), testing and documentation apply to the entire UI rather than to any specific function (it's generally useless to try to unit-test a single event handler function outside of its context), and most importantly, defining it out of line separates relevant and related concepts. All that said, I'm not pushing strongly for multiline lambdas in Python, largely because it's one of those ideas that would stand or fall on its syntax - an ugly multiline lambda won't be better than the alternatives, and would worsen the language. But I would leave the idea on the table; if anyone comes up with a really elegant syntax, I'd love to discuss it and help with PEP authorship. But Paul's recent track record of proposals isn't like that. They're not part of the language. If I start a thread recommending that Python's int type be redefined as a 19-bit signed integer with twos complement semantics, would that be received as a sane proposal, or would people say "no, Python's integer won't change semantics, go make your own fork"? ChrisA