Currying Vs Partial application.
In simple words: 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)
.
Example 1
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
*/
Example 2
The easiest way to see how they differ is to consider a real example. Let's assume that we have a function Add
which takes 2 numbers as input and returns a number as output, e.g. Add(7, 5)
returns 12
. In this case:
Partial applying the function Add
with a value 7
will give us a new function as output. That function itself takes 1 number as input and outputs a number. As such:
Partial(Add, 7); // returns a function f2 as output
// f2 takes 1 number as input and returns a number as output
So we can do this:
f2 = Partial(Add, 7);
f2(5); // returns 12;
// f2(7)(5) is just a syntactic shortcut
Currying the function Add
will give us a new function as output. That function itself takes 1 number as input and outputs yet another new function. That third function then takes 1 number as input and returns a number as output. As such:
Curry(Add); // returns a function f2 as output
// f2 takes 1 number as input and returns a function f3 as output
// i.e. f2(number) = f3
// f3 takes 1 number as input and returns a number as output
// i.e. f3(number) = number
So we can do this:
f2 = Curry(Add);
f3 = f2(7);
f3(5); // returns 12
In other words, "currying" and "partial application" are two totally different functions. Currying takes exactly 1 input, whereas partial application takes 2 (or more) inputs.
Even though they both return a function as output, the returned functions are of totally different forms as demonstrated above.