Currying and partial application
It’s extremely common to find definitions and examples of currying that actually refer to partial Function application, or partial application of functions. For those who, like me, are interested in functional programming without actually mastering any purely functional language, usually the two concepts become even more confused. I will try to explain the difference while I take the opportunity to consolidate my own understanding of the subject. All my examples use Javascript, but I imagine they are understandable to those who use C, Java, C#, among other languages.
Partial application
In functional languages, functions are not "invoked", but "applied" to their arguments. Functions are also known as "first-class citizens" of the language, i.e., can be assigned to variables, and interact with other functions can be passed as parameters or returned.
A function is "partially applied" when it is applied to only part of the parameters it expects, and returns another function that expects the remaining parameters. So partial application is a way to take a function and fix (or, like said the Zuul, "enter") certain parameters.
For example, the following function in Javascript expects three parameters:
function soma(a, b, c) {
return a + b + c;
}
// Duas maneiras diferentes de invocar:
soma(1, 2, 3); // 6
soma.apply(null, [1, 2, 3]); // 6
Let’s create a function that applies soma
partially, that is, sets the first parameter and returns a function that expects the other two:
function somap(a) {
return function(b, c) {
return soma(a, b, c)
}
}
// Uso:
var somadois = somap(2);
somadois(3, 4); // 9
This operation can be generalized to any function:
function partial(fn) {
// Guarda argumentos após fn numa array
var args = Array.prototype.slice.call(arguments, 1);
return function() {
return fn.apply(null, args.concat(Array.prototype.slice.call(arguments, 0)));
};
}
var somadois = partial(soma, 2);
somadois(3, 4); // 9
In fact, Javascript already supports this natively with method bind
that the functions have:
var somadois = soma.bind(null, 2);
Currying
The Currying Definition of zuul’s response is accurate and succinct (my griffin):
Currying is the name given to the technique of dividing a function that takes several arguments into a series of functions each dealing with one argument from the initial function.
Note that our example above does not meet this definition because partial(soma, 2)
returns a function that deals with two arguments of soma
, and not one. If our function did currying, we would have to call it so to get the final result:
var somadois = curry(soma, 2);
somadois(3)(4); // 9
The practical usefulness of this in Javascript (among other languages) is debatable. There are examples of justified uses, but in most cases there is not much advantage. Implementations of currying functions sane possible in Javascript, but not without some limitations.
Currying is very useful in languages where functions are always unary, i.e., accept a single argument. In them, currying is just one way to implement functions that accept more than one argument. And certain languages implement multi-parameter functions using currying internally. From this link, the following examples in Ocaml are equivalent:
let foo = fun a b ->
a * a + b * b
and
let foo = fun a ->
fun b ->
a * a + b * b
In Ocaml, the first way to define the function is only syntactic sugar for the second. Both produce identical function objects. And in both cases the call is equal, for example foo 1 2
- that would be foo(1)(2)
javascript.
I found in the Programmers an interesting point of view on this (in free translation):
For me the currying is important as a theoretical construct that allows to consider all functions as unary, since any other function can be reduced to such a function.