Currying is a fundamental tool in functional programming, a programming pattern that tries to minimize the number of changes to a program’s state (known as side effects) by using immutable data and pure (no side effects) functions.

Currying

Currying is the process of taking a function with multiple arguments and returning a series of functions that take one argument and eventually resolve to a value.

Here’s a simple example to illustrate it using the _.curry function from Lodash (we’ll build our own curry function shortly):

``````function volume(l, w, h) {
return l * w * h;
}

const curried = _.curry(volume);

volume(2, 3, 4); // 24
curried(2)(3)(4); // 24
``````

The original function `volume` takes three arguments, but once curried we can instead pass in each argument to three nested functions.

In other words, currying has effectively done this:

``````function volume1(length) {
return function(width) {
return function(height) {
return height * width * length;
}
}
}

volume1(2)(3)(4); // 24
``````

Arity

As you may have noticed, it’d be nice to have a way to refer to the number of parameters each function expects. It terms out there’s a fancy word for this: arity. A given function can have zero, one (unary), two (binary), three (ternary), or more (polyadic) parameters it expects.

Now it’s time to write our own curry function, which is a bit tricky. Fortunately ES6’s spread operator and arrow syntax help simplify things.

To start, we know `curry` accepts a function as well as a variable number of parameters:

``````var curry = (fn, ...args) => ...
``````

Next we need to know how many arguments (the “arity”) our function expects. If the number of arguments we already have equals the number expected, we call the function. Otherwise, we return a new function.

We can obtain both values using the `length` property of a function:

``````var curry = (fn, ...args) =>
(fn.length <= args.length) ...
``````

Now the final step. If the value of arguments equals the value expected, we simply call the function `fn(...args)`. But to return a new function and add it to our nested list, we store a series of functions which we can call `...more`.

``````var curry = (fn, ...args) =>
(fn.length <= args.length) ?
fn(...args) :
(...more) => curry(fn, ...args, ...more);
``````

Conclusion

It takes a while to wrap your head around functional programming and currying. But it’s worth the effort.

To learn more, I highly recommend the free book Professor Frisby’s Mostly Adequate Guide to Functional Programming or any talks by its author Brian Lonsdorf. Kyle Simpson, the author of the You Don’t Know JS Series also has an online course, Functional-Light JavaScript, on the topic designed for beginners.

Want to improve your JavaScript? I have a list of recommended JavaScript books.