update from Peter Harris

This commit is contained in:
David Goodger 2004-02-21 16:32:30 +00:00
parent fd32ea201c
commit 66588e0862
1 changed files with 25 additions and 27 deletions

View File

@ -1,5 +1,5 @@
PEP: 309
Title: Built-in Curry Type
Title: Function Currying
Version: $Revision$
Last-Modified: $Date$
Author: Peter Harris <scav@blueyonder.co.uk>
@ -14,13 +14,13 @@ Post-History: 10-Feb-2003, 27-Feb-2003
Abstract
========
This proposal is for a standard curry type for Python that
This proposal is for a curry constructor for Python that
allows a new callable to be constructed from a callable and a
partial argument list (including positional and keyword arguments).
Note: after feedback on comp.lang.python, I am persuaded that the most
accurate term for this is a 'curry' rather than a 'closure', so the
terminology has been amended since the first version of this PEP.
accurate term for this is a 'curry', so the terminology has been
amended since the first version of this PEP.
I propose a standard library module called "functional", to hold useful
higher-order functions, including the curry() class.
@ -40,11 +40,10 @@ In general, languages like that are strongly typed, so the compiler
always knows the number of arguments expected and can do the right
thing when presented with a functor and less arguments than expected.
Python has more flexible argument-passing, and so curries cannot be
implicit in the same way. Instead of using them, a Python programmer
Python has more flexible argument-passing, and so function currying cannot
be implicit in the same way. Instead, a Python programmer
will probably either define another named function or use a lambda.
But lambda syntax is horrible, especially when you want to do
something complex.
But lambda syntax is not to everyone's taste, to say the least.
We need something better.
@ -52,22 +51,25 @@ We need something better.
Rationale
=========
Here is one way to do a curry in Python::
Here is one way to do a create a curried callable in Python. The
implementation below is based on improvements provided by Scott David
Daniels::
class curry(object):
def __init__(self, fn, *args, **kw):
self.fn, self.args, self.kw = (fn, args, kw)
def __init__(*args, **kw):
self = args[0]
self.fn, self.args, self.kw = (args[1], args[2:], kw)
def __call__(self, *args, **kw):
if self.kw:
if kw and self.kw:
d = self.kw.copy()
d.update(kw)
else:
d = kw
d = kw or self.kw
return self.fn(*(self.args + args), **d)
Note that when the curry is called, positional arguments are
Note that when the curried function is called, positional arguments are
appended to those provided to the constructor, and keyword arguments
override and augment those provided to the constructor.
@ -75,8 +77,8 @@ So ``curry(operator.add, 1)`` is a bit like ``(lambda x: 1 + x)``, and
``curry(Tkinter.Label, fg='blue')`` is a callable like the Tkinter
Label class, but with a blue foreground by default.
I think a built-in type called ``curry``, that behaves the same way
but maybe implemented more efficiently, would be very useful.
I think a built-in class called ``curry`` that behaves the same way
would be very useful.
Update: a recipe almost exactly like this has been in the Python
Cookbook for quite some time, at
@ -122,7 +124,7 @@ Convenience functions ::
nextarg = sys.argv.pop@(0)
It has not been well-received, so I am not pursuing this as a serious
It has not been well-received, so I withdraw this part of the
proposal.
@ -201,27 +203,23 @@ I also coded the class in Pyrex::
The performance gain in Pyrex is less than 100% over the nested function
implementation, since to be fully general it has to operate by Python API
calls. Any C implementation will be unlikely to be much faster, so the
case for a builtin coded in C is not very strong.
calls. For the same reason, a C implementation will be unlikely to be much
faster, so the case for a built-in coded in C is not very strong.
Summary
=======
I prefer that curry should be a built-in, with the semantics as
described, whether as a function or a class. However, it should do its
apprenticeship in the standard library first.
I prefer that some means to curry functions should be a built-in, with the
semantics as described, whether as a function or a callable class. However,
it should do its apprenticeship in the standard library first.
The standard library module ``functional`` should contain ``curry`` and
``rightcurry`` classes, and any other higher-order functions the community
want. These other functions fall outside this PEP though.
want. Other functions that might belong there fall outside this PEP though.
The @ syntax proposal is withdrawn.
Since this proposal is now much less ambitious, I'd like to aim for
inclusion in Python 2.3.
Copyright
=========