← All concepts
A Closer Look at Functions

Currying

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

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.

Common mistakes

  • Confusing currying with plain partial application; currying specifically breaks a function into a chain of one-argument calls.
  • Assuming a curried function only ever accepts one argument per call; a generic curry helper can still accept several arguments at once if enough have arrived.
  • Forgetting that each intermediate call returns a new function instead of a result, so calling add(1) alone does not compute anything yet.

Key takeaways

  • Currying turns f(a, b, c) into f(a)(b)(c), returning a new function after each argument until enough have arrived.
  • Every intermediate function is a closure that remembers the arguments captured so far.
  • Currying enables partial application: stopping partway keeps a reusable function with some arguments already filled in.
Check your understanding

In a curried add, what does add(1)(2) return before add(1)(2)(3) is called?

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.

Practice this

Further reading

Previous
Higher-Order Functions
Next
call, apply, and bind