[Python-3000] A plea for anonymous functions

Talin talin at acm.org
Thu Nov 16 09:58:47 CET 2006


Fredrik Lundh wrote:
> Talin wrote:
> 
>> Javascript, for example, doesn't need special syntactical sugar for 
>> generator expressions:
>>
>>     /* Return a list of the square of numbers.
>>       ('map' appears courtesy of Mochikit.js) */
>>
>>     result = map( [1, 2, 3, 4], function (a) {
>>        return a * a;
>>     })
>>
>> No, its not quite as concise as a generator expression, but it is far 
>> more general in what it can do.
> 
> Are you sure you know what a generator expression is?  Mochikit's map is 
> just a JavaScript version of Python's function with the same name; it 
> takes an Array or an Array-like object, maps it though a function, and 
> returns an Array.  Compare

You are correct that 'map' isn't equivalent to a generator expression - 
my mistake. However, replacing 'map' with 'itertools.imap' gives you 
something roughly equivalent.

> To prove that they don't, you *have* to provide use cases, and show how 
> they would look and feel.  Hand-waving arguments and vague promises of 
> "once you reach my level of sophistication, you'll understand" isn't 
> good enough.

The problem with providing use cases is that each one individually 
doesn't carry much weight. When I do Javascript/AJAX programming, I use 
anonymous functions quite a bit, as in the following example:

    do_command( 'get_synset_links', {}, function( response_data ) {
       format_expanded( li.content, response_data.related )
    })

'do_command' calls a function on the server side via an async HTTP 
request, and calls the callback when the data is ready. By using an 
anonymous function as the callback, I can group the request for the data 
and the use of that data together in a logical way.

Could I do the same thing using a named callback? Sure. Would it be as 
easy to read and as clear? Not in my opinion. With a named callback, we 
would have to put the code that uses the data in a different place than 
the code that fetches the data. We would have to write the code so that 
the part that executes later appears earlier in the source file.

But it doesn't matter, because no matter what cases I come up with, 
someone will claim "You're just saving 2 lines of code". The fact that 
it saves 2 lines of code in many different places in my program can't 
easily be illustrated in an email message.

> (And frankly, it would be *wonderful* if someone could come up with a 
> new proposal that actually enabled Python programmers to do things they 
> *cannot* do today, instead of just rehashing old "let's move the sofa 
> over there" threads.  How about doing something along the lines of 
> LINQ's "give me this expression as an AST so I can optimize it myself" 
> model or looking at COmega's parallelization/synchronization stuff or 
> digging deeper into how PJE's RuleDispatch could be fit into Python or 
> stealing some cool idea from some functional research language that I 
> haven't even heard of.  I want to get *new* things when I upgrade from 
> 2.X to 3.0, not just silly syntax tweaks that would only give me the 
> ability to change two lines of Python code to one line of code plus a 
> comment that explains what the heck that line is doing.  Let's do some 
> *hard* stuff, for a change.)

I would disagree with one bit: I think most of those things can be done 
in Python today, they are just complicated and ugly under the current 
syntax. As much as people decry 'syntactic sugar', I would argue that 
those things you mentioned (even the AST example, although it's tricky) 
really just need sugar to make them feasible and useful to ordinary 
programmers, rather than any fundamental change to the execution model.

In my experience, most of the 'hard stuff' is built out of powerful, 
low-level language primitives - most of which Python already has. Those 
low-level primitives don't seem particularly powerful until you start 
combining them in synergetic ways. This is particularly well illustrated 
in Scheme, where many of the modern programming features - such as 
OOP-style single method dispatch - can be 'built up' out of more 
fundamental features like closures.

And I would argue that being able to treat 'code as data' is one of 
those fundamentals. We can already do this to some extent, but there's a 
long way to go still as far as intuitiveness and ease of use goes.

(Although I just read the last paragraph Ivan Krstić's response as I was 
typing this, and I think he says it better than I can, so I'll stop.)

-- Talin


More information about the Python-3000 mailing list