M
Masklinn
I believe that one's unadulterated BS.In no particular order, and not necessarily exhaustive:
* The risk of obfuscation in your code. That's fairly minimal for
lambdas, because they're just a single expression, but for a large
anonymous code block (ACB) defined inside a named function, it may be
difficult for the reader to easily distinguish which bits are the
outer
function and which are the ACB.
The traceback gives you the line of the anonymous function (even in* Loss of useful debugging information. Take this example from Python:
... return f(3)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in main
... return 2/(n-3)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in main
File "<stdin>", line 2, in my_special_function
ZeroDivisionError: integer division or modulo by zero
If your code has only one anonymous function (whether a lambda or a
full
multi-line block), then it's easy to identify which lambda raised the
exception: there is only one it could be. But if your code uses lots
of
lambdas, the lack of a function name makes it hard to distinguish one
<lambda> from another <lambda>. Anonymity makes identification harder.
python) so unless you have several anonymous functions on the same
line, there's no reason why that would be much of an issue.
Furthermore, Python doesn't provide any more information when the
error happens out of a function (in a `for` or a `with`), so it's not
like there's much of a difference here between Ruby's block-based
approach and Python's statements-based approach.
Yes, that one I can give you though I don't think that's a big issue.* Risk of code-duplication and breaking the principle of Once And Only
Once. Anonymous functions are generally created, used, then
immediately
thrown away -- or at least made more-or-less inaccessible for reuse.
An
anonymous function stored in a callback still exists, but the coder
isn't
able to easily re-use it for another callback somewhere else in the
code.
Consequently, there's a temptation for the coder to write the same
function multiple times:
add_button("Parrot", colour=blue, callback=lambda x: x.stuff('a'))
add_button("Cheese", flavour=tasty, callback=lambda x: x.thing('b'))
add_button("Canary", colour=yellow, callback=lambda x: x.stuff('a'))
instead of:
def bird_callback(x):
return x.stuff('a')
add_button("Parrot", colour=blue, callback=bird_callback)
add_button("Cheese", flavour=tasty, callback=lambda x: x.thing('b'))
add_button("Canary", colour=yellow, callback=bird_callback)
And it's not like it's hard to extract the anonymous function into a
named one and then use that on the third strike, so I really don't
believe that point holds much water.
Code blocks are rarely if ever used recursively. If an operation is* Recursion is more or less impossible without fragile tricks.
(At least for Python. I don't know how recursion operates in Ruby.)
using anonymous functions recursively, then there's often something
very wrong with the idea leading to that code. So I find this
objection irrelevant.