A critic of Guido's blog on Python's lambda

brian at sweetapp.com brian at sweetapp.com
Sun May 7 09:54:48 CEST 2006


Bill Atkins wrote:
> Does Python have any support for closures?  If so, ignore this point.
> But if not, what about examples like this:
>
>   (defun make-window (window observer)
>     ;; initialization code here
>     (add-handler window 'close
>                  (lambda (event)
>                     (notify observer event)))
>     ;; more code)
>
> Being able to keep pass around state with functions is useful.

I agree and Python supports this. What is interesting is how
counter-intuitive many programmers find this. For example, one of my
colleges (who is a reasonably average programmer), was completely
stumped by this:

>>> def right_partial(fn, *args):
...     def inner(*innerargs):
...         return fn(*(innerargs + args))
...     return inner
...
>>> square = right_partial(pow, 2)
>>> square(5)
25
>>> cube = right_partial(pow, 3)
>>> cube(5)
125

(for those of you unfamiliar with Python, the '>>>' and '...' means
that I typed this in the interactive shell)

So I try to use this sort of pattern sparingly because many programmers
don't think of closures as a way of saving state. That might be because
it is not possible to do so in most mainstream languages.

There are already some people in the Python community who think that
Python has already gone too far in supporting "complex" language
features and now imposes two steep a learning curve i.e. you now have
to know a lot to be considered a Python expert. And there is a lot of
resistance to adding features that will raise the bar even higher.

> There are also cases where a function is so trivial that the simplest
> way to describe it is with its source code, where giving it a name and
> putting it at the beginning of a function is just distracting and
> time-consuming.  E.g.:
>
>   (remove-if (lambda (name)
>                (find #\- name :test #'char=))
>              list-of-names)

There are some ways to write it in Python (if I understand the code):

# prefered
[name for name in list_of_names if '-' not in name]

OR:

# 2nd choice
def contains_no_dash(name):
    return '-' not in name

filter(contains_no_dash, list_of_names)

# not recommended
filter(lambda name: return '-' not in name, list_of_names)


> What's the sense of giving that function its own name?  It's much
> clearer to simply write it in place.  Yes, it's _possible_ to use
> named functions, but in this case its functionality is so simple that
> it's clearer to simply type it in place.  Why is this expressiveness a
> bad thing, aside from its power to wreck an indentation-significant
> language?

There are a few people in the Python community who think that unnamed
functions are inherently inferior to named ones because the name
provides documentation. The majority probably just don't care about the
issue at all. I will say that I am not sure that I know what your LISP
code does. However, even if you didn't understand the Python code in my
named-function version, the name "contains_no_dash" might provide you
with a small clue.
 
Cheers,
Brian




More information about the Python-list mailing list