javascriptfunctionrecursionnestedmethod-call

JavaScript nested number adder function with an unknown number of chained function calls


I have a nested function that should be able to handle chained function calls, but the number of calls is unknown. The function has to add up numbers until we call it without parameters, in which case it should return the result of all the numbers that were passed as arguments in the chain call.

Description:

Write the makeAdder function, which will return the adder function. The adder function should work on the following pattern: adder(2)(3)(4)(1)(2)(3)(4)() === 19. It will sum all the numbers passed in the parameters until it encounters a call without parameters. When calling without parameters, it will return the result and clear the amount.

Example:

const adder = makeAdder();
adder() === 0
adder(4)(5)() === 9
adder() === 0
adder(5)(5)(5)
adder(4)
adder() === 19
adder() === 0

How can I write this function without knowing how many nested functions I am going to need beforehand?

function makeInfinityAdder() {

  return function adder(a = 0) {
    return (b) => {
      if (b) {
        adder(a + b)
      } else {
        return a + b;
      }
    };
  }
}

I tried this but I get 'adder(...)(...) is not a function'.


Solution

  • A factory function: the return value returns a new Function instance (of itself) or the current value based on the availability of a (valid numeric) argument.

    See also

    const addAll = (a = 0) => b => +b >= 0 ? addAll(a + b) : a;
    
    let add = addAll();
    console.log(`add(8)(9)(10)(15)() => ${add(8)(9)(10)(15)()}`);
    console.log(`add(0)(8)(9)(10)(15)('stop') => ${add(0)(8)(9)(10)(15)('stop')}`);
    
    // reassign if you want to continue later (see comments):
    add = add(5)(5)(5);
    add = add(4);
    console.log(`reassignment (add = add(...)) => ${add()}`);
    
    // if you don't want to reassign
    const addAll2 = (a = 0) => {
      const fn = b => +b >= 0 ? (a += b, fn) : a;
      return fn;
    };
    
    let add2 = addAll2();
    add2(5)(5)(5);
    add2(4);
    console.log(`add2 (multiple add2(...)) => ${add2()}`);