← All concepts
A Closer Look at Functions

Currying

Turning a multi-argument function into a chain of one-argument functions.

Loading visual…

Definition

Currying transforms a function that takes several arguments into a sequence of functions that each take one argument, returning a new function after every call until enough arguments have arrived, at which point the result computes. A curried `add` called as `add(1)(2)(3)` works like this: `add(1)` returns a function that remembers 1 and is waiting for the next argument; calling that with `2` returns another function that remembers 1 and 2; calling that with `3` finally has all three arguments, so instead of returning another function it computes and returns `6`. Each step works because of closures, every returned function keeps a reference to the arguments captured so far. Currying does not change what gets computed, `add(1)(2)(3)` and `add(1, 2, 3)` can produce the same sum, it changes the shape of the calls, splitting one call with three arguments into three calls with one argument each. That shape is useful on its own: you can call a curried function partway, hold onto the result, and reuse it later with different final arguments, which is how currying enables partial application.

Examples

function add(a) {
  return function (b) {
    return function (c) {
      return a + b + c;
    };
  };
}
add(1)(2)(3); // 6

Each call returns a new function that closes over the arguments seen so far. Only the third call has enough arguments to compute a result.

const addTo10 = add(10);
addTo10(20)(5); // 35
addTo10(1)(1);  // 12

Stopping after the first call keeps a reusable function with 10 already captured, which can be finished off with different remaining arguments later.

function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) return fn(...args);
    return (...more) => curried(...args, ...more);
  };
}
const curriedAdd = curry((a, b, c) => a + b + c);
curriedAdd(1)(2)(3); // 6
curriedAdd(1, 2)(3); // 6

A generic curry helper checks fn.length, the declared arity, against how many arguments have arrived, and only calls the original function once enough are collected.

Where you see this

Practice this

Further reading