0

I want to make a function which adds arguments. Invoking this function should be

functionAdd(2)(3)(4)...(n);

And the result 2+3+4...+n I'm trying this

function myfunction(num){
  var summ =+ num;
  if(num !== undefined){
    return myfunction(summ);
  }

};

But it doesn't works, an error of ovwerflow. And I don't understand where I should out from this function;

Natalia
  • 37
  • 1
  • 7
  • 2
    So you want a function that returns a function (since it can be called)… except when it's the last time, it returns a number? how can it know that it's the last time? – Touffy Mar 31 '15 at 19:19
  • you should return a function reference, while you're returning the result that `myfunction(summ)` returns. Try to evaluate it manually with a piece of paper. – zerkms Mar 31 '15 at 19:19
  • Btw, the call by itself looks strange - what is the original task? Are you sure that `functionAdd(2)(3)(4)...(n);` is what you have to implement? – zerkms Mar 31 '15 at 19:20
  • Do you mean you should pass `n` to a function, and return the sum of N, until > 1? If so, that's easy. Just make the scope of `summ` be greater than the function, and call it if `num > 0` – cr0ss Mar 31 '15 at 19:21
  • when does this loop end? Now you loop until sun shuts down or memory ends. Memory ends first and you get the overflow error. – mico Mar 31 '15 at 19:22
  • 1
    about tail recursion: http://stackoverflow.com/questions/33923/what-is-tail-recursion – mico Mar 31 '15 at 19:24
  • No, the implement must be exactly functionAdd(2)(3)(4)...(n); – Natalia Mar 31 '15 at 19:27
  • @Natalia and what is the expected result of this call? How `functionAdd` is supposed to know that you're done passing arguments? – zerkms Mar 31 '15 at 19:28
  • @crOss, I pass each number that I want to add to summ in each scope... So the function `summ()();` will implement the function that will be returned by `summ`. – Natalia Mar 31 '15 at 19:33
  • @zerkms, So this is a question... I don't know how many scopes will be. The result will be a summ of each passed argument. I understand how to make this function if it wold be just `function(a,b,c,....,n)`... but it must be `function(a)(b)...(n)` – Natalia Mar 31 '15 at 19:37

2 Answers2

5

You can use the .valueOf to do the trick:

function myfunction(sum){
    var accum = function(val) {
        sum += val;

        return accum;
    };

    accum.valueOf = function() {
        return sum;
    };

    return accum(0);
};

var total = myfunction(1)(2)(3)(4);

console.log(total); // 10

JSFiddle: http://jsfiddle.net/vdkwhxrL/

How it works:

on every iteration you return a reference to the accumulator function. But when you request for the result - the .valueOf() is invoked, that returns a scalar value instead.

Note that the result is still a function. Most importantly that means it is not copied on assignment:

var copy = total
var trueCopy = +total   // explicit conversion to number

console.log(copy)       // 10 ; so far so good
console.log(typeof copy)  // function
console.log(trueCopy)   // 10
console.log(typeof trueCopy)  // number

console.log(total(5))   // 15

console.log(copy)       // 15 too!
console.log(trueCopy)   // 10
Touffy
  • 6,309
  • 22
  • 28
zerkms
  • 249,484
  • 69
  • 436
  • 539
  • Nice trick. Only works if you use the end result in a scalar context, of course. You can force succintly that by using the unary + operator. – Touffy Mar 31 '15 at 19:34
  • @Touffy well, a function that returns a number should be used in a context that requires a scalar :-) Otherwise it makes no sense. – zerkms Mar 31 '15 at 19:35
  • 1
    Still, better to remember that this particular value isn't a number. It has some rather unusual properties for a number, can be called, will be copied or passed by reference rather than copying the value… for example if you assign it to another variable, then call the original variable with a number, it will change the "value" of the other variable too – Touffy Mar 31 '15 at 19:43
  • @zerkms thanks a lot! Now I can go to sleep... – Natalia Mar 31 '15 at 19:45
  • @Touffy that's an extra valid point, indeed :-) Strange tasks require strange solutions (with their limitations) – zerkms Mar 31 '15 at 20:02
  • Life would be boring without JavaScript's quirks :) But I'll add an example of that to your answer if you don't mind. – Touffy Mar 31 '15 at 20:07
0

If last call can be without arguments:

function add(value) {

  var sum = value;

  return function add(value) {
    if(typeof value === 'number') {
      sum += value
      return add
    } else {
      return sum
    }
  }

}



console.log(add(1)(2)(3)(0)()) // 6
Krzysztof Safjanowski
  • 7,292
  • 3
  • 35
  • 47