what's wrong with "lambda x : print x/60,x%60"

Antoon Pardon apardon at forel.vub.ac.be
Tue Dec 6 07:11:49 EST 2005


Op 2005-12-06, Fredrik Lundh schreef <fredrik at pythonware.com>:
> Steve Holden wrote:
>
>> One perhaps needs to be a little more careful with instance variables,
>> but again most *temporaries* are simply local to the method in which
>> they're called, they don't exist for the lifetime of the instance.
>
> and more importantly, temporary variables can be reused.  they're only
> bound to a given object until you bind them to some other object.  the
> following is a perfectly good way to define a couple of callbacks:
>
>     def callback():
>         ...
>     b1 = Button(master, command=callback)
>
>     def callback():
>         ...
>     b2 = Button(master, command=callback)
>
>     def callback():
>         ...
>     b3 = Button(master, command=callback)
>
> (three callbacks, a single temporary name)
>
> to refer to variables from the outer scope from inside a callback,
> just use the variable.  to refer to *values* from the outer scope,
> use argument binding:
>
>     def callback(arg=value):
>         ...
>     b3 = Button(master, command=callback)
>
> since "def" is an executable statement, and the argument line is
> part of the def statement, you can bind the same argument to
> different values even for the same function, e.g.
>
>     for i in range(10):
>         def callback(button_index=i):
>             ...
>         b = Button(master, command=callback)
>
> this loop creates ten distinct function objects.

But this seems to defeat the main argument for removing lambda
and using def's instead.

One of the most repeated arguments against using lambda is that
no (meaningfull) name is associated with it, that can help
in tracking bugs in case of a traceback. But if you are
having a lot of functions with the same name you won't get
much usefull information either.

I also don't see such a style being advocated in other cases.
Sure I can write my code like this:

    for i in xrange(10):
        arg = 2 * i + 1
        func(arg)

But nobody is suggestion this is how it should be and that
something is wrong with the following:

    for i in xrange(10):
        func(2 * i + 1)


I have seen a number of suggestion that may reduce the use
of lambda without having to use a def instead.

e.g.

   fivefold = lambda x: x * 5

could be replace by:

  fivefold = types.MethodType(operator.mul, 5)

There is also PEP 309 which introduces a partial class,
with the same kind of functionality. The above would
then become:

  fivefold = partial(operator.mul, 5)

This should work from python 2.5, but a working implemantation
seems to be in the PEP, as well as a reference to the cookbook
with alternative implementations. Partial also seems to
be more general than MethodType.

I doubt this will eliminate the need of lambda but AFAIS
it reduces the need. An idea that may eliminate the need
totaly, would be the introduction of name parameters.

When you call a function with a name parameter, the expression
for the parameter isn't evaluated, but instead an evaluatable
form is created (something like a lambda), that is evaluated
each time the parameter is used. Since the most arguments
in favor of the lambda are the possibility to use an expression
as a parameter, this may be an acceptable alternative for
those who use lambda now

I don't know how well name parameters would fit in with the
rest of python though.

-- 
Antoon Pardon



More information about the Python-list mailing list