Currying vs. Partial Application

I feel like there’s a lot of confusion as to the difference between currying and partial application, especially as they’re often brought up together in similar contexts.

Partial application addresses the following: given that we have multi-parameter functions, we want to fix certain parameters of a function.

Explicit partial application is possible in almost any language. In C:

int foo(int a, int b, int c) {
  return a + b + c;

int foo23(int a, int c) {
  return foo(a, 23, c);

foo23 is essentially a partial application of foo, with the parameter b fixed to the value 23.

Of course, explicit partial application like this isn’t all that useful; we’d generally want our language to support some kind of partial application for us.

In python, for example, we can do

from functools import partial

def foo(a,b,c):
  return a + b + c

foo23 = partial(foo, b=23)

foo23(a = 1, c = 3)  # => 27

Currying addresses an ostensibly fairly different issue: Given that we have only single parameter functions, and we’re in a language with first-class functions, how can we implement multi-parameter functions? Currying is a way of implementing multi-parameter functions.

Here’s a single-parameter javascript function:

var foo = function(a) {
  return a * a;

If we we’re only allowed to write single-parameter functions, we could simulate a multi-parameter function like this:

var foo = function(a) {
  return function(b) {
    return a * a + b * b;

and call it by doing (foo(3))(4), or just foo(3)(4).

Note that currying offers a very natural way to implement certain partial applications. If I want to partially apply foo by fixing its first parameter to 5, all I need to do is var foo5 = foo(5). There – done. foo5 is our partially applied foo. Note, though, that there isn’t much of a natural way to partially apply foo’s second parameter (without first applying its first parameter).

Of course, javascript does support multi-parameter functions

var bar = function(a, b) {
  return a * a + b * b;

bar, as we’ve defined it, is not a curried function. Calling bar(5), for example, won’t return a function that we can then apply 12 to. We can only call bar as bar(5,12).

Other languages, though, like Haskell and OCaml, implement all multi-parameter functions via currying.

Here’s foo from above translated to OCaml:

let foo = fun a ->
  fun b ->
    a * a + b * b

and here’s bar translated into OCaml:

let bar = fun a b ->
  a * a + b * b

We might call the first function “explicitly curried” and the second one “implicitly curried”.

Unlike in the javascript case, in OCaml, foo and bar are really exactly the same thing. We call them in the exact same way

# foo 3 4;;
- : int = 25
# bar 3 4;;
- : int = 25

and both can be called with just one argument to create a partial application

# let foo5 = foo 5;;
val foo5 : int -> int = <fun>
# let bar5 = bar 5;;
val bar5 : int -> int = <fun>
# foo5 12;;
- : int = 169
# bar5 12;;
- : int = 169

In fact, we can consider the anonymous function form

fun arg1 arg2 ... argN -> exp

as syntactic sugar for

fun arg1 -> fun arg2 -> ... -> fun argN -> exp