Re: PEP 309 misuses the term "currying"
Gareth McCaughan
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(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
On Friday 2004-02-20 12:32, David Abrahams wrote: [I said:]
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 don't 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).
Yow. I've just read PEP309, which (to my shame) I hadn't done when reading your original comment. I thought I could tell from your comments how PEP309 was using the term "currying". I was completely wrong; I misunderstood what you were protesting about, and I now agree: PEP309 misuses the term "curry".
Even if we ignore the syntax issues I brought up earlier, this doesn't appear to resemble what you've been describing at all.
No, you're right. Oops. -- g
participants (2)
-
David Abrahams
-
Gareth McCaughan