I sing the praises of lambda, my friend and savior!

Jeff Shannon jeff at ccvcorp.com
Tue Oct 12 01:47:48 CEST 2004


Dave Benjamin wrote:

>In article <10mlsct69hmtgca at corp.supernews.com>, Jeff Shannon wrote:
>  
>
>Another example is the "after" procedure. If you're familiar with Tcl, you
>may recognize the following idiom:
>
>after(10, lambda: sprite.move(0, 5))
>
>In an (imaginary) event-driven framework, this would wait 10 seconds before
>moving "sprite" down 5 pixels. You might say that this could easily be
>rewritten with a def, and you're right:
>
>def doit():
>    sprite.move(0, 5)
>after(10, doit)
>
>Now, imagine you are setting up an animation this way:
>
>after(10, lambda: sprite.move(0, 5))
>after(15, lambda: sprite2.rotate(30))
>after(20, lambda: sprite.scale(120, 120))
>after(22, lambda: sprite2.move(50, 50))
>after(22, lambda: sound1.play())
>after(23, lambda: sprite.move(0, 0))
>after(26, lambda: sound1.stop())
>  
>

In this case, I'd redefine after to be:

    def after(timeout, func, *args, **kwargs):
        # whatever needs to be done to delay the call, then...
        func(*args, **kwargs)

Then we can do the animation as:

    after(10, sprite.move, 0, 5)
    after(15, sprite2.rotate, 30)
    after(20, sprite.scale, 120, 120)
    # ...

I find this to read slightly better, and the implementation requires one 
less level of indirection.  I'll admit that I haven't explored much in 
the area of function currying and closures, so there *may* be ways in 
which using lambda is preferable to using a generic variable-argument 
closure-returning function, but at least in the cases that spring to my 
mind, lambda's advantage is slim at best.

>As was pointed out already in this thread, decorators break many of the same
>rules. So far, I find anonymous functions much more useful than decorators.
>The only problem is finding a suitable syntax, and I will admit this is
>indeed a problem.
>  
>

And I'm not very happy with the decorator syntax either, to be honest.  
Still, from the examples that cropped up during the Great Decorator 
Syntax Debate (tm), it seems to me that, even though *I* don't 
particularly need them, the potential benefits of decorators are greater 
than the potential benefits of lambda.  That is, I can see things that 
can be done with user-defined descriptors that are difficult to do any 
other way, whereas from what I've seen many/most uses of lambda can be 
re-cast to use normal functions without too much pain.  This provides a 
bit more justification for having special syntax for user-defined 
descriptors (i.e. decorators), though to be honest I'm not terribly 
happy with the chosen syntax.  Of course, this is all theoretical, since 
at this point I've had no call to use either descriptors or lambdas...

>In that case, why stop at functions? Why not make all intermediate values
>have mandatory names? Why not ban this:
>
>c = math.sqrt(a * a + b * b)
>
>And require instead:
>
>a2 = a * a
>b2 = b * b
>tmp = a2 + b2
>c = math.sqrt(tmp)
>  
>

Intermediate anonymous values make sense at a certain level of 
granularity but not at all levels.  Practicality beats purity. 

On the other hand, I'd never write your first example -- I'd be 
explicity about the grouping with extra parens.

   c = math.sqrt( (a*a) + (b*b) )

It's not syntactically necessary, because it's following standard 
operator precedence, but it scans much more quickly for me. 

Indeed, maybe that's what this is all about.  To my mind, when I see a 
lambda, I already have to stop scanning, push a level on my mental 
stack, figure out what the heck is going on with the lambda and what 
it's going to return, and then pop back to the line in progress.  In 
contrast, when I'm scanning something using a (descriptively) named 
function, the name should tell me enough of the purpose of the function 
that I don't need to pause to figure it out.  Thus, it's much quicker 
for me to scan a reference to a named function than to scan a lambda 
definition.


>>I understand that lambdas are very popular in other programming 
>>languages (such as Lisp).  But Python is not those languages, and which 
>>constructs are useful may well be different.  I don't know enough Lisp 
>>to judge how helpful lambdas are there; I do know enough Python to 
>>believe that I should be able to see the advantages if they were as 
>>wonderful as their proponents say.
>>    
>>
>
>Lisp is not the only language that benefits from lambdas. Other languages
>include JavaScript/ActionScript, C# (anonymous delegates), Java (anonymous
>inner classes -- a poor substitute), Ruby, Tcl, Perl, and OCaml. They are
>used in GUI callbacks, iteration patterns, flow control, data processing,
>and in general any function or procedure that needs parts of its logic to be
>parameterized. Only one of the aforementioned languages, OCaml, is
>considered to be a functional language like Lisp or Scheme.
>  
>

ISTM that many of these uses can be accomplished by using named 
functions with variable arguments.   I'll admit that I'm no language 
expert, and TBH haven't used any of those languages.  But my impression 
is that the use of (named) function references, dynamic typing, and 
convenient variable argument syntax can acheive most of the benefits 
that are touted for lambdas. 

>(Yet, somehow, decorators slipped through, even though nobody agreeed on a
>syntax for that either. I don't have a rational explanation for that...)
>  
>

Nor do I .....  *sigh*

Jeff Shannon
Technician/Programmer
Credit International





More information about the Python-list mailing list