Search code examples
javascriptfunctionclosureslexical-closures

Identify how the function has been called in closure javascript


Recently i faced one problem in hackerrank which has to calculate multiplication operation and has to return the answer. For example

function multiply(a,b) {
     return a*b;
}

Now here is the problem the function might call in different ways such as

multiply(4,5);
multiply(4)(5);
multiply(4)(5)(6);

I know we have to closure apporach for the second one which is multiply(4)(5). I had written code for that

function multiply(a,b) {
  return function(b) {
    return a*b;
  }
}

Now what if its been multiply function has been called with 3 arguments multiply(4)(5)(6). How can i identify how the function has been called and how can i write a common solution for all the inputs.

Any help is appreciated. Thanks


Solution

  • To have an unlimited callchain you need some js trick:

    function multiply(...args){
      //make the chain endless through using some recursive like stuff:
      const func = (...args2) => multiply(...args,...args2);
      //the chains endpoint:
      func.valueOf = function(){
         return args.reduce((a,b) => a*b);
      };
      return func;
    }
    

    The problem of such variable currying is that its infinite, so theres ( usually ) no way to end it.

    multiply(1) // func :/
    

    However in javascript its possible to assign methods to functions so we can easily somewhen call the method instead of the function to end the chain:

    multiply(1)(2)(3).valueOf()
    

    So you can simply do:

     console.log(
      +multiply(1,2,3)(4)(5),
      +multiply(1,2)
    );
    

    The + is equal to valueOf and is therefore neccessary to end the chain, however this call to valueOf is inferred by many operations in javascript ( all math operations like - * /).