Have you ever wondered how to make your JavaScript functions more flexible and reusable? Let's explore function currying with something we all love (or at least need) i.e. coffee.
The Usual Way: All Ingredients at Once
Normally, if we want to make coffee with milk and sugar, we'd just write a function that takes all the ingredients as arguments:
function makeCoffee(milk, coffee, sugar) {
return `${milk} + ${coffee} + ${sugar}`;
}
console.log(makeCoffee("Milk", "Coffee", "Sugar"));
// Milk + Coffee + Sugar
This works fine. But what if you don't know all the ingredients right away? Or you want to reuse parts of the function for different variations?
That's where currying shines.
Enter Function Currying
Currying is the process of transforming a function with multiple arguments into a series of functions that take one argument at a time.
Let's curry our makeCoffee function:
function makeCoffee(milk) {
return function (coffee) {
return function (sugar) {
return `${milk} + ${coffee} + ${sugar}`;
};
};
}
console.log(makeCoffee("Milk")("Coffee")("Sugar"));
// Milk + Coffee + Sugar
Instead of passing everything at once, we build the coffee step by step, just like in real life.
Reusability: Brewing Your Favorites
With currying, you can partially apply arguments and reuse them later:
const withMilk = makeCoffee("Milk");
const withMilkAndCoffee = withMilk("Coffee");
console.log(withMilkAndCoffee("Sugar")); // Milk + Coffee + Sugar
console.log(withMilkAndCoffee("Honey")); // Milk + Coffee + Honey
Here:
-
withMilk
is a function that always starts with milk. -
withMilkAndCoffee
always adds coffee to milk. - The last ingredient (sugar, honey, etc.) is left flexible.
This makes your function modular and customizable.
Why Currying is Useful
Reusability : You can store intermediate functions (
withMilk
,withMilkAndCoffee
) for later.Flexibility : You don’t need all arguments upfront.
Clarity : Each step represents a logical unit in the process.
Currying is especially useful in functional programming and scenarios like event handlers, configuration setups, or pipelines.
Final Sip
Currying transforms the way we think about functions: from "give me everything now" to "let's build things step by step."
Next time you're structuring your code, think: Can I make this function more reusable, like brewing coffee one ingredient at a time?
Top comments (0)