Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between currying and partial application?

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?

like image 706
SpoonMeiser Avatar asked Oct 20 '08 10:10

SpoonMeiser


People also ask

What is partial application in JavaScript?

Partial application allows us to fix a function's arguments. This lets us derive new functions, with specific behavior, from other, more general functions. Currying transforms a function that accepts multiple arguments “all at once” into a series of function calls, each of which involves only one argument at a time.

What is partial application in programming?

In computer science, partial application (or partial function application) refers to the process of fixing a number of arguments to a function, producing another function of smaller arity. Given a function , we might fix (or 'bind') the first argument, producing a function of type .

What is meant by currying?

to praise someone, especially someone in authority, in a way that is not sincere, in order to get some advantage for yourself: He's always trying to curry favour with the boss.

What does partial function application in Haskell do?

Partial function application refers to calling a multiple parameter function with less than its total number of parameters. This results in a new function taking the remaining number of parameters.


2 Answers

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 
like image 160
Mark Cidade Avatar answered Oct 02 '22 17:10

Mark Cidade


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.

like image 28
Pacerier Avatar answered Oct 02 '22 16:10

Pacerier