[Python-3000] A plea for anonymous functions
Talin
talin at acm.org
Fri Nov 17 10:41:53 CET 2006
Greg Ewing wrote:
> Talin wrote:
>
>> 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.
>
> I don't think it's as simple as that. Back when the with
> statement was first being discussed, I suggested that it
> should be implemented by passing the body as an anonymous
> function. That would have been a very simple way of doing
> it, but there were problems, such as what to do if the
> body contained break or continue statements. In the end,
> Guido rejected the anonymous-function approach, and we
> ended up with something that is rather more elaborate.
>
> So we have a situation where there was no syntactical
> barrier to treating a code block as an anonymous function,
> but we chose not to do so. That seems to cast doubt on
> the idea that first-class code blocks would solve all
> the problems you suggest they would solve.
Well, it seems that my argument about being able to construct the 'with'
statement with anon. code blocks may not be air-tight; However I still
stand by my basic argument that anon. code is a fundamental
building-block of a number of interesting language extensions, and that
I expect to see a series of special-case syntactical work-arounds that
compensate for the lack of such a feature.
To give a concrete example, suppose we decide to add to Python a
special-case syntactical structure to deal with asynchronous events,
similar to the code example that I posted earlier. The simplest possible
example I can think of is an an alarm-clock function:
# Create a callback timer
alarm = Timer()
alarm.SetDuration( 100, Timer.Milliseconds )
upon alarm:
print "It's time to get up, silly-head!"
print "Alarm has been set!"
In the example, the hypothetical 'upon' statement passes a reference to
the following suite to the object resulting from the expression - so in
this case, the suite containing the print statement is passed as a
callable to the 'alarm' object. Thus it is equivalent to:
# Create a callback timer
alarm = Timer()
alarm.SetDuration( 100, Timer.Milliseconds )
def upon_alarm():
print "It's time to get up, silly-head!"
alarm.set_callback( upon_alarm )
print "Alarm has been set!"
The latter approach is a common pattern in Python. However, if we take
the argument presented in the blog entry cited by Fredrik, which
proposes that 'design patterns are symptomatic of a weakness in a
programming language' (an argument which I don't entirely buy - absence
of a feature is not always a weakness), then in order to make the
language 'stronger', we ought to make the design pattern disappear into
the language. In this case, we do so by absorbing the setup of the
function machinery into the syntax of the 'upon' statement.
However, this special-case approach is flawed in this example, because
its use is so narrow. If you think about it for a minute, you
immediately start to imagine all of the things that 'upon' ought to deal
with that it doesn't. For example, it has no way to deal with error
callbacks; It has no way to pass arguments from the asynchronous process
to the code block. It doesn't let me build a hash table of code snippets
(which is my solution to the problem of 'switch' statements in Python.)
But even if we spend the next month writing a PEP for an 'upon'
statement that overcomes all these limitations, I will still most likely
be able to think of some use case that it doesn't handle. No matter what
I add to the PEP, there will eventually be another PEP that adds yet
another special-case solution to some aspect that I haven't covered.
Instead, I'd rather work at a more fundamental level, that solves a
larger class of problems.
(To the folks that would say that this is only a trivial optimization, I
would respond - if that's the case, then why is it used so heavily in
languages which do support it? And why does practically every other
popular scripting language except Python support it at all? And no, the
answer 'you shouldn't be programming in Python' is not an acceptable
response, it's a lame cop-out IMHO.)
-- Talin
More information about the Python-3000
mailing list