The difference between currying and partial application

curryingdefinitionlanguage-agnosticpartial-applicationterminology

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?

Best Answer

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, accumulator, 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(accumulator,list) {/*...*/}
f(0,list) //returns 10
@g = f(0) //same as sum
g(list)  //returns 10