update from Peter Harris
This commit is contained in:
parent
fd32ea201c
commit
66588e0862
52
pep-0309.txt
52
pep-0309.txt
|
@ -1,5 +1,5 @@
|
||||||
PEP: 309
|
PEP: 309
|
||||||
Title: Built-in Curry Type
|
Title: Function Currying
|
||||||
Version: $Revision$
|
Version: $Revision$
|
||||||
Last-Modified: $Date$
|
Last-Modified: $Date$
|
||||||
Author: Peter Harris <scav@blueyonder.co.uk>
|
Author: Peter Harris <scav@blueyonder.co.uk>
|
||||||
|
@ -14,13 +14,13 @@ Post-History: 10-Feb-2003, 27-Feb-2003
|
||||||
Abstract
|
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
|
allows a new callable to be constructed from a callable and a
|
||||||
partial argument list (including positional and keyword arguments).
|
partial argument list (including positional and keyword arguments).
|
||||||
|
|
||||||
Note: after feedback on comp.lang.python, I am persuaded that the most
|
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
|
accurate term for this is a 'curry', so the terminology has been
|
||||||
terminology has been amended since the first version of this PEP.
|
amended since the first version of this PEP.
|
||||||
|
|
||||||
I propose a standard library module called "functional", to hold useful
|
I propose a standard library module called "functional", to hold useful
|
||||||
higher-order functions, including the curry() class.
|
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
|
always knows the number of arguments expected and can do the right
|
||||||
thing when presented with a functor and less arguments than expected.
|
thing when presented with a functor and less arguments than expected.
|
||||||
|
|
||||||
Python has more flexible argument-passing, and so curries cannot be
|
Python has more flexible argument-passing, and so function currying cannot
|
||||||
implicit in the same way. Instead of using them, a Python programmer
|
be implicit in the same way. Instead, a Python programmer
|
||||||
will probably either define another named function or use a lambda.
|
will probably either define another named function or use a lambda.
|
||||||
But lambda syntax is horrible, especially when you want to do
|
But lambda syntax is not to everyone's taste, to say the least.
|
||||||
something complex.
|
|
||||||
|
|
||||||
We need something better.
|
We need something better.
|
||||||
|
|
||||||
|
@ -52,22 +51,25 @@ We need something better.
|
||||||
Rationale
|
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):
|
class curry(object):
|
||||||
|
|
||||||
def __init__(self, fn, *args, **kw):
|
def __init__(*args, **kw):
|
||||||
self.fn, self.args, self.kw = (fn, args, kw)
|
self = args[0]
|
||||||
|
self.fn, self.args, self.kw = (args[1], args[2:], kw)
|
||||||
|
|
||||||
def __call__(self, *args, **kw):
|
def __call__(self, *args, **kw):
|
||||||
if self.kw:
|
if kw and self.kw:
|
||||||
d = self.kw.copy()
|
d = self.kw.copy()
|
||||||
d.update(kw)
|
d.update(kw)
|
||||||
else:
|
else:
|
||||||
d = kw
|
d = kw or self.kw
|
||||||
return self.fn(*(self.args + args), **d)
|
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
|
appended to those provided to the constructor, and keyword arguments
|
||||||
override and augment those provided to the constructor.
|
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
|
``curry(Tkinter.Label, fg='blue')`` is a callable like the Tkinter
|
||||||
Label class, but with a blue foreground by default.
|
Label class, but with a blue foreground by default.
|
||||||
|
|
||||||
I think a built-in type called ``curry``, that behaves the same way
|
I think a built-in class called ``curry`` that behaves the same way
|
||||||
but maybe implemented more efficiently, would be very useful.
|
would be very useful.
|
||||||
|
|
||||||
Update: a recipe almost exactly like this has been in the Python
|
Update: a recipe almost exactly like this has been in the Python
|
||||||
Cookbook for quite some time, at
|
Cookbook for quite some time, at
|
||||||
|
@ -122,7 +124,7 @@ Convenience functions ::
|
||||||
|
|
||||||
nextarg = sys.argv.pop@(0)
|
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.
|
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
|
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
|
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
|
calls. For the same reason, a C implementation will be unlikely to be much
|
||||||
case for a builtin coded in C is not very strong.
|
faster, so the case for a built-in coded in C is not very strong.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Summary
|
Summary
|
||||||
=======
|
=======
|
||||||
|
|
||||||
I prefer that curry should be a built-in, with the semantics as
|
I prefer that some means to curry functions should be a built-in, with the
|
||||||
described, whether as a function or a class. However, it should do its
|
semantics as described, whether as a function or a callable class. However,
|
||||||
apprenticeship in the standard library first.
|
it should do its apprenticeship in the standard library first.
|
||||||
|
|
||||||
The standard library module ``functional`` should contain ``curry`` and
|
The standard library module ``functional`` should contain ``curry`` and
|
||||||
``rightcurry`` classes, and any other higher-order functions the community
|
``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.
|
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
|
Copyright
|
||||||
=========
|
=========
|
||||||
|
|
Loading…
Reference in New Issue