Currying – or: There Are Only Functions with One Argument
(You can watch the video version of this post on YouTube.)
Now what’s the type of a function that multiplies two integers? I would say maybe $\mathbb{Z}^2\to \mathbb{Z}$, so: ordered pair of two integers going in, one integer coming out.
There’s a different way of looking at it, though. If I only give you the first argument, say “multiply by 2,” that still kind of makes sense right? It’s just that “multiply by 2” is still a function, because we’re missing the second argument – but once we get it, we can multiply it by 2. In this sense, multiply is a function with one argument: it’s just that the result is a function in one argument and it multiplies by that number.
Let’s do this in Python real quick if that was a bit too abstract. The normal way would be something like:
def mul(x,y): return x*y
You call it like mul(2,3)
and it returns 6
. The second way to look at multiplication would be something like this:
def mul(x): lambda y: x*y
Let that sink in for a second. Now you call it as mul(x)(y)
and that still returns 6
, of course. But now you can do fun things like
double = mul(2)
and then double(3)
returns 6
.
This was a silly example, but in general it is quite a powerful idea that you can do this with any function and it’s called “currying,” after the mathematician Haskell Curry. It’s no coincidence that there’s a programming language called Haskell and in it, technically, there are only functions with one argument. In Haskell, the type of multiplying two integers is int -> int -> int
. Without parentheses, by the way: operator precedence means this says int -> (int -> int)
like we want.
I don’t really have a killer application for you in a short post like this, so for now you can just take it as a programming novelty – but it does illustrate the power of first-class functions: being able to have functions as values.