a little trap revealed (was Re: Let's Talk About Lambda Functions!)

Alex Martelli aleax at aleax.it
Sat Jul 27 03:11:46 EDT 2002


Jeremy Bowers wrote:
        ...
>> for word in 'fee fie foo fum'.split():
>>     Button(frame, command=lambda: print word)
>> 
>> The poster is typically nonplusses that all buttons print 'fum'.
> 
> Speaking as one who recently posted this, what's the alternative?
> 
> for word in 'fee fie foo fum'.split():
>     def printThing():
>         print word
>     Button(frame, printThing)
> 
> doesn't work any better, you still need
> 
> for word in 'fee fie foo fum'.split():
>     def printThing(word = word):
>         print word
>     Button(frame, printThing)

Not sure why you snipped the closure solution, which looks like
the obvious one to me once one has seen it:

def makePrinter(word):
    def printit(): print word
    return printit

for word in 'fee fie foo fum'.split():
    Button(frame, command=makePrinter(word))


> Lambda wart, or just scoping wart in general?

Not sure if it qualifies as a "wart", just as a little trap which
is empirically observed to catch users of lambdas, not users of
named functions.  I've never met anybody who expected the solution
with 'def' in the loop to somehow snapshot the values in the
surrounding environment (maybe I've just led a sheltered life?),
while several users of lambda seem to expect exactly that.  Given
which, touting the appropriateness of lambda's scoping seems weird!


> (And I'll still take the lambda form; the def statement feels wrong here.)

Guess that's what wrong with having lambda in the language: without
adding any capability, it gives two ways to solve some problems, one
of which feels wrong to you, the other one of which IS wrong.

Because, you see, I put a little trap in this example... and it
seems to me that you fell right into it.

The lambda solution doesn't work.  At all.  It gives you a SyntaxError
if you try it!

lambda cannot include a statement.  print is a statement.  Oooops...!-)

So, if you structure your code with lambda, the moment you want
to add a print statement, boom -- can't do.  You have to restructure
your code to use def instead.  When you remove the print after it's
done its debugging-help job, will you restructure once again to
take the def away in favor of lambda... and again NEXT time you
need to have a statement there too, etc, etc...?  What a lot of
purposeless code churning...!

Use def and avoid all of this silly self-imposed useless work.


Alex




More information about the Python-list mailing list