All topics
Functionsadvanced

Function Currying and Partial Application

Transforming a multi-argument function into a sequence of single-argument functions, and pre-filling some arguments ahead of time.

Currying turns a function of several arguments into a chain of single-argument functions.

Currying is like a vending machine that only accepts one coin at a time and won't dispense your snack until you've inserted every coin required — each coin insertion (argument) gives you back the same machine, ready for the next coin, until the final one triggers the drop.

Key Concepts

1
    // ordinary
    const add = (a, b, c) => a + b + c;
    add(1, 2, 3);
2
    // curried
    const curried = a => b => c => a + b + c;
    curried(1)(2)(3);
3
Partial application is the related, looser idea: fix some arguments now, supply the rest later.
4
    const add = (a, b, c) => a + b + c;
    const add1 = add.bind(null, 1);
    add1(2, 3);    // 6
5
Currying is a strict one-at-a-time chain. Partial application just means pre-filling some arguments.
6
Why anyone does this. It makes specialised functions out of general ones:
7
    const multiply = a => b => a * b;
    const double = multiply(2);
    const triple = multiply(3);
8
    [1, 2, 3].map(double);    // [2, 4, 6]
9
And it lets a configuration be supplied once and reused:
10
    const logger = level => module => message =>
      console.log(`[${level}] ${module}: ${message}`);
[${level}] ${module}: ${message}
11
    const errorLog = logger('ERROR');
    const dbError = errorLog('database');
    dbError('connection lost');
12
Each stage fixes what is known at that point.
13
Where it pays off in real code: composition.
    const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
14
    const process = pipe(
      filterActive,
      sortByName,
      take(10)          // curried, so it is a single-argument function
    );
15
Composition needs every function to take one argument and return one value. Currying is what turns a two-argument function into something composable.
16
The honest caveat. Deep currying makes stack traces and error messages worse, and it is unfamiliar to many readers.
17
    curried(1)(2)(3)      // what failed, and where?
    add(1, 2, 3)          // obvious
18
Use it where it earns its place — building specialised functions, and composing pipelines. Currying everything by default makes ordinary code harder to read for no gain, which is the judgement the question is usually probing.
19
What the interviewer is probing.1. "What is the difference between currying and partial application?" Probing: precision between two conflated terms. Stalls: "The same thing." Moves up: currying turns an n-argument function into a chain of single-argument ones; partial application fixes some arguments and returns a function taking the rest.
20
2. "Where is currying genuinely useful?" Probing: practice over theory. Stalls: "It is academic." Moves up: building specialised functions from a general one for pipelines and event handlers, where argument order is chosen to make partial application natural.
21
3. "How does bind relate to this?" Probing: the built-in. Stalls: "It is different." *Moves up:* bind is partial application that also fixes this.
22
4. "What is the cost?" Probing: honesty. Stalls: "None." Moves up: a closure per level, which is irrelevant in most code and measurable in a hot loop.