[Python-3000] A plea for anonymous functions

Talin talin at acm.org
Thu Nov 16 07:37:31 CET 2006


 From the beat-that-dead-horse department: I've never really been 
satisfied with the outcome of the discussion on lambda and anonymous 
functions.

As much as I love the use of syntactic indentation in Python, it does 
have one serious drawback, which is that it creates a wall between the 
realms of 'statements' and 'expressions'. Statements are delimited by 
line breaks (generally), while expressions are free-format. The result 
is that while statements can contain expressions, expressions cannot 
contain statements.

None of the scripting languages which are direct competitors to Python 
(in particular, Ruby, Javascript, Perl, Lua, etc.) have this limitation, 
and all of them are able to take very powerful advantage of the ability 
to freely mix statements within expressions.

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.

Now, there are those who say "Just use a named function", but that 
argument doesn't hold - because the *same* argument can be levied 
against generator expressions, the 'with' statement, and a number of 
other recent syntactical innovations in Python.

 From my point of view, both 'with' and generator expressions are 
limited, special-case solutions to a general problem - the desire to be 
able to use and manipulate unnamed blocks of code as first-class 
objects. Conversely, the same arguments that make 'with' important 
enough to change Python syntax - instead of just saying 'use a named 
function' - apply here as well, only in this case we're not talking 
about a specific use case, but rather a whole class of use cases which 
has yet to be fully explored.

There are also those who would claim that, given the lack of use of 
'lambda' in existing Python code, that there's no compelling use case. 
To this, I have two counter-arguments:

1) This is IMHO a chicken-and-egg problem. Anonymous functions aren't a 
solution to an existing problem, so much as they are an opportunity to 
explore new kinds of solutions to new kinds of problems in Python. As 
long as functions must be named (or crippled, as in the case of Lambda), 
people are going to find workarounds.

2) Many of those 'workarounds' are going to come back in the form of 
PEPs to add new language features. I predict that we'll see a 
never-ending parade of enhancement proposals - lazy evaluation 
expressions, asynchronous callback expressions, and so on - all of which 
are in a sense compensating for the lack of the ability to treat code 
like data.

Instead of attempting to address the problem piecemeal, and thereby 
obfuscating the clean, elegant minimalism of Python (more than it 
already has been), I say we cut to the chase and deal with the root problem.

Of course, I realize that this isn't an easy problem to solve - its 
inherent in Python's syntax choices, and certainly I don't want to give 
those up. But I want to specifically argue against the idea that "it's 
hard to solve, and it's not important, so let's not bother with it". My 
argument is that it may be hard, but it *is* important.

I'm going to refrain from adding any hare-brained syntax proposals of my 
own here - I'm more interested in trying to convince people that this is 
a problem worth bothering with.

I would like, however, to be clear in defining the parameters of the 
problem I would like to see addressed. I am not arguing *specifically* 
for anonymous functions of the 'lambda' type, although that would be one 
possible solution to the problem. What I want is "the ability to treat 
anonymous code blocks as first-class objects", which is a larger space 
of solutions than just lambda functions. For example, a solution that 
didn't involve parameter binding would not be a lambda function, but 
would still meet my criteria.

-- Talin


More information about the Python-3000 mailing list