update from Peter Harris; minor edits

This commit is contained in:
David Goodger 2004-08-27 13:29:47 +00:00
parent 4957e14b72
commit 867839cff4
1 changed files with 44 additions and 29 deletions

View File

@ -18,8 +18,11 @@ This proposal is for a function or callable class that allows a new
callable to be constructed from a callable and a partial argument list callable to be constructed from a callable and a partial argument list
(including positional and keyword arguments). (including positional and keyword arguments).
I propose a standard library module called "functional", to hold useful I propose a standard library module called "functional", to hold
higher-order functions, including the implementation of partial(). useful higher-order functions, including the implementation of
partial().
An implementation has been submitted to SourceForge [2]_.
Motivation Motivation
@ -52,8 +55,9 @@ 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 does not implement multi-argument functions by currying, so if Python does not implement multi-argument functions by currying, so if
you want a function with partially-applied arguments you would probably you want a function with partially-applied arguments you would
use a lambda as above, or define a named function for each instance. probably use a lambda as above, or define a named function for each
instance.
However, lambda syntax is not to everyone's taste, so say the least. However, lambda syntax is not to everyone's taste, so say the least.
Furthermore, Python's flexible parameter passing using both positional Furthermore, Python's flexible parameter passing using both positional
@ -61,8 +65,8 @@ and keyword presents an opportunity to generalise the idea of partial
application and do things that lambda cannot. application and do things that lambda cannot.
Rationale Example Implementation
========= ======================
Here is one way to do a create a callable with partially-applied Here is one way to do a create a callable with partially-applied
arguments in Python. The implementation below is based on improvements arguments in Python. The implementation below is based on improvements
@ -90,6 +94,9 @@ positional arguments are appended to those provided to the
constructor, and keyword arguments override and augment those provided constructor, and keyword arguments override and augment those provided
to the constructor. to the constructor.
Positional arguments, keyword arguments or both can be supplied at
when creating the object and when calling it.
Examples of Use Examples of Use
=============== ===============
@ -97,8 +104,8 @@ Examples of Use
So ``partial(operator.add, 1)`` is a bit like ``(lambda x: 1 + x)``. So ``partial(operator.add, 1)`` is a bit like ``(lambda x: 1 + x)``.
Not an example where you see the benefits, of course. Not an example where you see the benefits, of course.
Note too, that you could wrap a class in the same way, since Note too, that you could wrap a class in the same way, since classes
classes themselves are callable factories for objects. So in some cases, themselves are callable factories for objects. So in some cases,
rather than defining a subclass, you can specialise classes by partial rather than defining a subclass, you can specialise classes by partial
application of the arguments to the constructor. application of the arguments to the constructor.
@ -117,7 +124,8 @@ callbacks for Tkinter widgets on the fly::
c.pack() c.pack()
for colour in sys.argv[1:]: for colour in sys.argv[1:]:
b = Button(win, text=colour, command=partial(c.config,bg=colour)) b = Button(win, text=colour,
command=partial(c.config, bg=colour))
b.pack(side='left') b.pack(side='left')
win.mainloop() win.mainloop()
@ -129,16 +137,13 @@ Abandoned Syntax Proposal
I originally suggested the syntax ``fn@(*args, **kw)``, meaning the I originally suggested the syntax ``fn@(*args, **kw)``, meaning the
same as ``partial(fn, *args, **kw)``. same as ``partial(fn, *args, **kw)``.
At least there are no backwards-compatibility issues because the @
character isn't a legal operator in any previous versions of Python.
The @ sign is used in some assembly languages to imply register The @ sign is used in some assembly languages to imply register
indirection, and the use here is also a kind of indirection. indirection, and the use here is also a kind of indirection.
``f@(x)`` is not ``f(x)`` , but a thing that becomes ``f(x)`` when you ``f@(x)`` is not ``f(x)``, but a thing that becomes ``f(x)`` when you
call it. call it.
It has not been well-received, so I have withdrawn this part of the It was not well-received, so I have withdrawn this part of the
proposal. proposal. In any case, @ has been taken for the new decorator syntax.
Feedback from comp.lang.python and python-dev Feedback from comp.lang.python and python-dev
@ -199,12 +204,10 @@ Carl Banks posted an implementation as a real functional closure::
return fn(*(cargs + fargs), **d) return fn(*(cargs + fargs), **d)
return call_fn return call_fn
which he assures me is more efficient. You lose introspection and which he assures me is more efficient.
sub-classing that way, but these are maybe only marginal benefits and
not worth a performance hit, so this would also do as a reference
implementation.
I also coded the class in Pyrex:: I also coded the class in Pyrex, to estimate how the performance
might be improved by coding it in C::
cdef class curry: cdef class curry:
@ -241,7 +244,13 @@ implementation of ``partial``, and any other higher-order functions
the community want. Other functions that might belong there fall the community want. Other functions that might belong there fall
outside the scope of this PEP though. outside the scope of this PEP though.
The @ syntax proposal has been withrawn. Patches for the implementation, documentation and unit tests (SF
patches 931005_, 931007_, and 931010_ respectively) have been
submitted but not yet checked in.
A C implementation by Hye-Shik Chang has also been submitted, although
it is not expected to be included until after the Python
implementation has proven itself useful enough to be worth optimising.
References References
@ -249,6 +258,12 @@ References
.. [1] http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549 .. [1] http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549
.. [2] Patches 931005_, 931007_, and 931010_.
.. _931005: http://www.python.org/sf/931005
.. _931007: http://www.python.org/sf/931007
.. _931010: http://www.python.org/sf/931010
Copyright Copyright
========= =========