Confessions of a Python fanboy
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Fri Jul 31 14:17:05 EDT 2009
On Fri, 31 Jul 2009 18:15:15 +0200, Masklinn wrote:
> > I know, I know, Ruby people swear by
> > anonymous code blocks, and I've read Paul Graham too. But I'm really
> > not so sure that the benefits of anonymous code blocks are great
> > enough to overcome the disadvantages of anonymous code blocks.
> >
> What are the disadvantages of anonymous functions?
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.
* Loss of useful debugging information. Take this example from Python:
>>> def main(f):
... return f(3)
...
>>> main(lambda n: 2/(n-3))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in main
File "<stdin>", line 1, in <lambda>
ZeroDivisionError: integer division or modulo by zero
>>>
>>> def my_special_function(n):
... return 2/(n-3)
...
>>> main(my_special_function)
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.
* 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)
* Recursion is more or less impossible without fragile tricks.
(At least for Python. I don't know how recursion operates in Ruby.)
--
Steven
More information about the Python-list
mailing list