views:

1384

answers:

3

I'm not exactly sure how to word this question.

I learnt what currying was in the first year of university, and have been using it where applicable ever since.

However, I quite often see on the Internet various complaints that other peoples examples of currying are not currying, but are actually just partial application.

I've not found a decent explanation of what partial application is, or how it differs from currying. There seems to be a general confusion, with equivalent examples being described as currying in some places, and partial application in others.

Could someone provide me with a definition of both terms, and details of how they differ?

+3  A: 

Interesting question. After a bit of searching, "Partial Function Application is not currying" gave the best explanation I found. I can't say that the practical difference is particularly obvious to me, but then I'm not an FP expert...

Another useful-looking page (which I confess I haven't fully read yet) is "Currying and Partial Application with Java Closures".

It does look like this is widely-confused pair of terms, mind you.

Jon Skeet
Interesting links, although they do offer conflicting ideas of what currying is.
SpoonMeiser
The first link is spot-on about the differences. Here's another one I found useful: http://bit.ly/CurryingVersusPartialApplication
Jason Bunting
+17  A: 

Currying is converting a single function of n arguments into n functions with a single argument each. Given the following function:

function f(x,y,z) { z(x(y));}

When curried, becomes:

function f(x) { lambda(y) { lambda(z) { z(x(y)); } } }

In order to get the full application of f(x,y,z), you need to do this:

f(x)(y)(z);

Many functional languages let you write f x y z. If you only call f x y or f(x)(y) then you get a partially-applied function—the return value is a closure of lambda(z){z(x(y))} with passed-in the values of x and y to f(x,y).

One way to use partial application is to define functions as partial applications of generalized functions, like fold:

function fold(combineFunction, accumalator, list) {/* ... */}
function sum     = curry(fold)(lambda(accum,e){e+accum}))(0);
function length  = curry(fold)(lambda(accum,_){1+accum})(empty-list);
function reverse = curry(fold)(lambda(accum,e){concat(e,accum)})(empty-list);

/* ... */
@list = [1, 2, 3, 4]
sum(list) //returns 10
@f = fold(lambda(accum,e){e+accum}) //f = lambda(accumaltor,list) {/*...*/}
f(0,list) //returns 10
@g = f(0) //same as sum
g(list)  //returns 10
Mark Cidade
You're saying that partial application is when you curry a function, and use some, but not all of the resulting functions?
SpoonMeiser
more or less, yes. If you only supply a subset of the arguments, you'll get back a function that accepts the rest of the arguments
Mark Cidade
Would changing a function f(a, b, c, d) to g(a, b) count as partial application? Or is it only when applied to curried functions? Sorry to be a pain, but I'm angling for an explicit answer here.
SpoonMeiser
g(a,b) would be a partial application only if g == f(a,b) and g(a',b') == f(a,b,a',b'). Partial application has to go in the order the arguments are specified
Mark Cidade
But the same is not true for currying? I could translate f(a, b, c) into g(c) -> h(a) -> i(b), and that would still be currying? And then I couldn't use these functions for partial application?
SpoonMeiser
If you re-arranged the arguments like that, I guess it can still be considered currying. You can then go ahead and call g(x) and get back a function that accepts "a" and then "b" as arguments. Or call "g(c)(a)" and get back a function that accepts "b".
Mark Cidade
Anent your statement: _Currying is converting a single function of n arguments into n functions with a single argument each_ - I understand just the opposite; currying is taking multiple, one-argument functions, then _composing_ a multiple-argument function.Whereas a partially applied function is creating from a function that accepts multiple arguments a function that requires fewer, e.g.`var Add = function(a,b) { return a + b; } var AddOne = partial(Add, 1);`Can you cite sources for your explanation/understanding?Here is one I read: http://bit.ly/CurryingVersusPartialApplication
Jason Bunting
@Jason: Your source says the same thing that I do—in its example, it takes a pre-curried multi-argument function defined using "define/curried" and re-composes it back uisng partial application. For a clearer definition of currying and partial application that are the same as mine, see http://en.wikipedia.org/wiki/Currying .
Mark Cidade
@Mark: I guess this is just one of those concepts that brings out the pedant in me - but an appeal to authoritative sources does little to satisfy, since they all seem to point to one another. Wikipedia is hardly what I consider an authoritative source, but I understand that it's hard to find much else. Suffice it to say that I think we both know that of which we speak and the power thereof, regardless of whether or not we can agree (or disagree) on the particulars of the vernacular! :) Thanks Mark!
Jason Bunting
A: 

Python supports partial application of functions in the standard library. See functools.partial

Also, you may be interested in the justification for functools.partial.

blokeley