Currying in JavaScript
Source: Dev.to
What is Currying?
Currying is a functional‑programming technique that transforms a function with multiple parameters into a sequence of functions, each accepting a single argument:
f(a, b, c) → f(a)(b)(c)
It relies heavily on closures: every nested function retains access to the arguments supplied in previous calls, allowing values to be accumulated until all required parameters are available. Once the expected number of arguments is collected, the original function executes and returns the final result.
Simple Example
function orderCoffee(type) {
return function (size) {
return function (milk) {
return `You selected ${type} ${size} with ${milk}`;
};
};
}
const orderOne = orderCoffee('Latte')('Medium')('Almond milk');
const orderTwo = orderCoffee('Americano')('Large')('No milk');
const orderThree = orderCoffee('Mocha')('Medium')('Almond milk');
console.log(orderOne); // You selected Latte Medium with Almond milk
console.log(orderTwo); // You selected Americano Large with No milk
console.log(orderThree); // You selected Mocha Medium with Almond milk
Each call captures one piece of information and returns a new function that waits for the next input.
How It Works Internally
-
First call –
orderCoffee('Latte')
Returns a function that expectssize. Thetype('Latte') is remembered via closure. -
Second call –
orderCoffee('Latte')('Medium')
Returns a function that expectsmilk. Bothtypeandsizeare now stored. -
Third call –
orderCoffee('Latte')('Medium')('Almond milk')
Returns the final string, using all three captured values.
Arrow‑Function Version
Arrow functions make the same pattern look more concise:
const orderCoffee = (type) => (size) => (milk) =>
`You selected ${type} ${size} with ${milk}`;
const order = orderCoffee('Latte')('Medium')('Almond milk');
console.log(order); // You selected Latte Medium with Almond milk
Step‑by‑Step Breakdown
| Step | Expression | Returns |
|---|---|---|
| 1 | orderCoffee('Latte') | Function waiting for size |
| 2 | orderCoffee('Latte')('Medium') | Function waiting for milk |
| 3 | orderCoffee('Latte')('Medium')('Almond milk') | Final string "You selected Latte Medium with Almond milk" |
Why Use Currying?
- Reusability – Create partially applied functions that can be reused with different remaining arguments.
- Readability – Break complex calls into smaller, intention‑revealing steps.
- Composition – Works well with other functional techniques like function composition and pipelines.
Conclusion
Currying breaks a multi‑parameter function into a chain of single‑parameter functions, leveraging closures to remember earlier arguments. This pattern can simplify code, promote reuse, and fit naturally into a functional programming style in JavaScript.