[Python-Dev] Re: PEP 309 misuses the term "currying"
David Abrahams
dave at boost-consulting.com
Fri Feb 20 07:32:45 EST 2004
Gareth McCaughan <gmccaughan at synaptics-uk.com> writes:
> Dave Abrahams wrote:
>
>> The operation performed by the operator described here is actually
>> called "Partial Application". A good definition of currying can be
>> found in http://tinyurl.com/3d6w6 and http://tinyurl.com/ly29.
>
> I disagree. Currying is turning a function that takes its arguments
> all at once as a tuple into a function that takes them one at a time
> by partial application.
> So if f(1,2,3)=64 and F is the curried version
> of f, then F(1)(2)(3)=64.
You've introduced some syntactic confusion.
1. The syntax you show above for the uncurried function
f(1,2,3)
means "pass all the arguments in a single tuple" in some languages
-- the same ones that give "f x" the meaning "invoke f with
argument x". In Python, the parens are part of the function call
operator. It means "pass the arguments one at a time" (internals
and implementation details aside).
2. Whether or not a language supports the syntax you show above for
partial application can be seen as independent of the meaning of
currying.
> The idea of currying arose in a context where functions are
> fundamentally single-argument; it's a way of converting between
> two different ways of building multiple-argument functions
> on top of a single-argument-only base. That's handy for
> mathematicians and theoretical computer scientists, who
> like to keep their underlying concepts as few and as simple
> as possible.
Sure.
> But in Python, and in many other programming
> languages, functions with multiple arguments aren't built on
> a single-argument substrate
Depends how you look at it, but I know what you mean.
> so there are *three* options
> for passing multiple arguments to a function.
> - Collect args into a tuple, pass that.
> - Just pass multiple arguments.
> - Pass arguments one at a time using partial application.
And the language doesn't support the third one by default.
> And the middle one, the one that isn't generally considered
> by mathematicians doing lambda calculus, happens to be the
> *usual* case. How you apply the notion of "currying" to Python,
> then, depends on which pair of argument-passing conventions
> you choose to assimilate; in other words, on which of the two
> distinctions at work here you choose to emphasize. Currying
> is ...
>
> 1. "Turning a function that takes a single tuple argument into
> one that takes multiple arguments."
>
> 2. "Turning a function that takes it arguments all at once into
> one that takes them one at a time."
>
> According to #1, what PEP309 calls currying is no such thing.
> According to #2, what PEP309 calls currying *is* currying.
>
> It looks to me as if the second usage is the dominant one, in
> which case I think PEP309 is fine.
I dont' see how you can make that claim. Curry is a one argument
function that accepts a function and returns a new function; I hope
we can agree on that. If this were currying according to your
description, the result would always be callable with a single
argument (yielding, perhaps, another function object).
>>> from pep309 import curry
>>> def add(a, b):
... return a+b
...
>>> curry(add)
<curry.curry object at 0x008E3430>
>>> curry(add)(1)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "curry.py", line 12, in __call__
return self.fn(*(self.args + args), **d)
TypeError: add() takes exactly 2 arguments (1 given)
>>>
Even if we ignore the syntax issues I brought up earlier, this doesn't
appear to resemble what you've been describing at all.
If Python needs a function like the one being proposed in the PEP (I'm
not convinced it does, since IIUC lambda covers that ability nicely),
it should probably be called "bind" and should use something like the
Boost interface, which doesn't tread on any existing meanings for the
word and has been shown to be flexible, powerful, and useful.
http://www.boost.org/libs/bind
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
More information about the Python-Dev
mailing list