Currying converts a multi argument function to sequence of function calls with single arguments. Like below
//In normal function syntax
const multiply = function (a, b){
return a * b;
};
const output = multiply(2, 3);
console.log(output);
//In Arrow function syntax
const multiply = (a, b) => a * b;
const output = multiply(2, 3);
console.log(output);
To
//In normal function syntax
cont multiply = function (a) {
return function (b) {
return a * b;
};
};
const output = multiply(2)(3);
console.log(output);
// 6
//In Arrow function syntax
const multiply = a => b => a * b;
const output = multiply(2)(3);
console.log(output);
// 6
To the naked eye currying looks like converting a very simple function like in the first function to a little complex function unnecessarily. But there are usecases which will make this very useful.
Lets dive in. Lets say, I have a function requirement with three arguments. And the first argument remains same for few calls. In that case, I will have to pass the same argument again and again for each call. Currying can be a great way to avoid that.
Lets take the example of logging a series of messages into console with time after an even is fired. Obviously I would like to log the same time for all the logging in the series.
Lets code that
const logData = time => id => message => {
console.log(`Time is ${time} and data is ${id} and ${message}`);
};
const logDataWithTime = logData(new Date());
logDataWithTime(1234)('Dummy Message 1');
logDataWithTime(1235)('Dummy Message 2');
logDataWithTime(1236)('Dummy Message 3');
/*
Time is Wed Jan 05 2022 06:25:49 GMT+0530 (India Standard Time) and data is 1234 and Dummy Message 1
Time is Wed Jan 05 2022 06:25:49 GMT+0530 (India Standard Time) and data is 1235 and Dummy Message 2
Time is Wed Jan 05 2022 06:25:49 GMT+0530 (India Standard Time) and data is 1236 and Dummy Message 3
*/
As you can see in the above example we do not have to pass the date/time to the function again and again for each call.
How does this work?
Its simple to understand if you take one function at a time. If you look into the first function it creates a lexical scope for the variable a
and returns another function like below. As the returned function has access to variable a, it will be like below to understand.
return function (b) {
return 2 * b;
};
//2 inplace of a that was passed in the first function
There many applications of currying in JavaScript like in events, logging etc.