DEV Community

Sharu
Sharu

Posted on

Currying in Javascript

Currying in javascript is utilized to process a function with varying parameter list as shown below:

add(1)(3)
add(7)(29)(41)
add(0)(1)(2)(3)(5)

Adding two numbers can be achieved as shown in the following code snippet

Snip a - Function to add 2 numbers

let add2 = (a) => (b) => b ? add2(a + b) : a;
console.log(add2(1)(3)());
Enter fullscreen mode Exit fullscreen mode

But this is not scalable when we have to add more than 2 numbers and becomes cumbersome to create a solution with increasing parameters.

Snip b - Function to accept 4 arguments

function sum(a) {
  return function (b) {
    return function (c) {
      return function (d) {
        return a + b + c + d;
      };
    };
  };
}

console.log(sum(1)(2)(3)(4));
Enter fullscreen mode Exit fullscreen mode

Hence solution here is to come up with a generic way to curry this. As we observe in the above snip b, we return a function (function(b) from function(a)) which can accept a parameter ( the next parameter which is b). The cycle continues, until we have exhausted all the parameters in curried function call stack in the execution context and final value gets returned back to the caller as the function calls gets popped off the stack.

function(a)(b)(c)....(n)

What we see above is similar to a recursive function call to exhaust (in a way to fetch) the parameters from a curried call

So to make this task generic we can build a function which can help us consolidate the parameters into an object(array)

function testCurrying(func) {
  let firstArgument = null;
  let innerFunc = (...args) => {
    firstArgument = args[0];
    console.log(`Build Array : ${args}`);
    return (innerArg) => {
      if (!innerArg) return func(args);
      console.log(`innerArg = ${innerArg}`);
      return innerFunc(...args, innerArg);
    };
  };
  return innerFunc;
}

let testFunction = (x) => console.log("final array = ", x);
testCurrying(testFunction)(3)(4)(6)();

$ node function.js 
Build Array : 3
innerArg = 4
Build Array : 3,4
innerArg = 6
Build Array : 3,4,6
final array =  [ 3, 4, 6 ]
Enter fullscreen mode Exit fullscreen mode

As shown below, A curry requires

  • tadka : A function which either adds or multiplies or divides etc a given list of array

  • tava : A inner function to consider varying list of parameters to either add or multiply or divide etc

  • gravy : An argument list which needs to be built / accumulated into an array overtime with the items(values)

  • item : Each parameter thats passed from the parameter list

Snip c - Currying 'n' parameter list

let curry = (tadka) => {
  const tava =
    (...gravy) =>
    (item) =>
      item ? tava(...gravy, item) : tadka(gravy);
  return tava;
};

let sum = (arr) => arr.reduce((acc, val) => acc + val, 0);
let curriedSum1 = curry(sum);
console.log(curriedSum1(1)(2)(3)(4)(6)(5)(100)());
Enter fullscreen mode Exit fullscreen mode

Top comments (0)