Currying: One Argument at a Time, No Exceptions

A stricter cousin of partial application that only ever accepts one argument per call, where the technique gets its name, and the utility that automates it.

September 13, 20262 min read25 / 27

Partial application locks in however many arguments you hand it, all at once. Currying takes the same goal, specializing a function step by step, and adds one strict rule: exactly one argument per call, every time.

Writing It by Hand

JavaScript
function apiRequest(endpoint) { return function (payload) { return function (callback) { // the actual request }; }; } const getOrder = apiRequest('/orders'); const getCurrentOrder = getOrder({ id: currentOrderId }); getCurrentOrder(renderOrder);

Three nested functions, three separate calls, each one peeling off exactly one input before handing back a function waiting for the next. That's currying, written manually.

Where the Name Comes From

This technique is named after Haskell Curry, a mathematician who helped develop the ideas behind it. It's not a coincidence that a language named Haskell only allows unary functions: every function in that language takes exactly one argument, so currying isn't an optional style choice there, it's the only way a function can ever take more than one input.

JavaScript doesn't have that restriction. Currying here is a deliberate choice, not a language requirement.

Automating It

Writing the nested-function version by hand for every multi-argument function gets old fast. A curry utility does it for you:

JavaScript
function curry(fn, arity = fn.length) { return function curried(...args) { if (args.length >= arity) return fn(...args); return (...more) => curried(...args, ...more); }; } function apiRequest(endpoint, payload, callback) { // the actual request } const curriedRequest = curry(apiRequest); const getOrder = curriedRequest('/orders'); const getCurrentOrder = getOrder({ id: currentOrderId }); getCurrentOrder(renderOrder);

curry takes an ordinary function and returns one that keeps collecting arguments, one call at a time, until it has enough to actually run the original.

ℹ️ Curried functions are sometimes written as chained arrow functions: endpoint => payload => callback => { ... }. If you write it that way, wrap each arrow function in its own parentheses. It costs nothing and saves the next reader from re-parsing three nested arrows to find where one function ends and the next begins.

Currying and Partial Application Are Cousins, Not the Same Thing

Partial application
JavaScript
partial(fn, a, b) // both at once

Locks in as many arguments as you hand it, in one call.

Currying
JavaScript
curried(a)(b) // one at a time

Never accepts more than one argument per call, no exceptions.

Both exist to turn one general function into a chain of increasingly specific ones. Currying trades away partial application's flexibility for a single, predictable shape: every step takes one thing and returns one function, which is exactly why it composes so cleanly with everything else this series has already covered.

That predictability is also why, in practice, most functional codebases lean on currying far more than partial application, even though both get you to the same destination.