What is Currying?
Currying is a technique where you transform a function that takes multiple arguments into a series of functions that each take one argument. Instead of calling f(a, b, c), you call f(a)(b)(c).
// Regular function
function add(a, b) {
return a + b;
}
// Curried version
function curriedAdd(a) {
return function(b) {
return a + b;
};
}
console.log(curriedAdd(3)(5)); // 8
Why Curry Functions?
Currying lets you create specialized functions from general ones. You can "fix" some arguments and get a new function that only needs the remaining arguments.
function log(level, timestamp, message) {
console.log(`[${level}] ${timestamp}: ${message}`);
}
// Create a specialized logger
const errorLog = log("ERROR");
const warnLog = log("WARN");
errorLog(new Date().toISOString(), "Disk full");
warnLog(new Date().toISOString(), "Memory high");
Generic Curry Function
You can write a utility that automatically curries any function. This is common in functional libraries.
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
}
return function(...args2) {
return curried.apply(this, args.concat(args2));
};
};
}
const curriedMultiply = curry((a, b, c) => a * b * c);
console.log(curriedMultiply(2)(3)(4)); // 24
console.log(curriedMultiply(2, 3)(4)); // 24
console.log(curriedMultiply(2, 3, 4)); // 24
Try it Yourself →
Currying in Practice
Currying shines when combined with map, filter, and other higher-order functions. You create reusable, specialized functions on the fly.
const curry = (fn) => (...args) => fn(...args);
const greaterThan = curry((threshold, value) => value > threshold);
const filterGreaterThan5 = Array.prototype.filter.bind([1, 3, 7, 8, 10]);
console.log(filterGreaterThan5(greaterThan(5))); // [7, 8, 10]
Summary
Currying transforms multi-argument functions into chains of single-argument functions. It enables partial application and makes it easy to create specialized functions from general ones.