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); // 6Each 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); // 12Stopping 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); // 6A 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
- Pre-configuring a reusable function, like fixing a tax rate once and reusing calculateTax(rate) across many amounts.
- Building small variants of a general function, such as deriving double and triple from a single curried multiply.
- Composing pipelines of transformations where each stage is set up once with its configuration and reused per item.
- Creating event handlers bound to specific data, like handleClick(id) returning the actual listener for that id.