Strict vs Loose Currying, and Why Partial Application Survives

The one-line answer to 'what's the difference between currying and partial application,' the version of currying every real library actually ships, and when partial application still wins.

September 13, 20262 min read26 / 27

The last post drew the line between currying and partial application: exactly one argument at a time, versus however many you hand over at once. That line is worth being able to say back on the spot, in an interview or a code review.

Partial application takes some inputs now, the rest later. Currying takes none now, one at a time.

That's the rule as stated. The version you'll actually meet in real code bends it slightly.

The Currying You'll Actually Find in the Wild

The curry utility from the last post technically allows something worth naming: calling it with more than one argument at a time.

JavaScript
const curriedRequest = curry(apiRequest); curriedRequest('/orders')({ id: 42 })(renderOrder); // one at a time curriedRequest('/orders', { id: 42 })(renderOrder); // two at once, still works

The strict, textbook version of currying, the one Haskell actually enforces, only ever accepts exactly one argument per call. What almost every real JavaScript library ships instead is loose currying: still building up arguments step by step, but letting you group more than one together at any step, purely for convenience.

If you're reading someone else's curried code and see a call with two or three arguments at once, that's not a bug or a misunderstanding of currying. It's loose currying, and it's the norm, not the exception.

Why Currying Usually Wins

Set up a curried function once, and every call after that just supplies the next piece, no utility call required. Set up partial application the same way, and specializing further means calling partial again at every step.

Functional libraries lean into this so hard that their functions typically come pre-curried by default. It also lines up with something this series already established: functional programmers favor unary functions, and a curried function is nothing but a chain of them, one input, one output, repeated.

Where Partial Application Still Wins

Currying isn't strictly better in every case, because of what it does to a function's shape.

Say a function takes five inputs, and you want a version with two of them preset, leaving three still open. Curry that function, and you get back a chain of curried single-argument steps, three more calls, one argument each. Partial application gives you back a plain function still expecting all three remaining arguments together, in one call.

When the shape you actually want is "a normal function waiting for its last few arguments," not "a chain of one-at-a-time calls," partial application produces the better fit. That's a narrow case, but it's the reason the tool hasn't disappeared even though currying covers most of the same ground.