3
const factorial = function(n, acc = 1){
  if (n < 2) {
    return acc;
  }
  return factorial(n - 1, n * acc); 
};
const factorial_normal = function(n){
  if (n < 2) {
    return 1;
  }
  return n * factorial_normal(n - 1)
};
console.log(factorial(8956)); // RangeError: Maximum call stack size exceeded
console.log(factorial_normal(8960)); // Infinity

It's just a simple factorial function with javascript. But I got a RangeError with the first function, which i do think it was a better solution cause i think it is faster and more stack-save. Is there something different in these two function that i've ever been known. Please help me, thanks.

Okato
  • 35
  • 3
  • ps. i use the node v10.0.0 – Okato Jul 18 '18 at 14:30
  • 'Maximum call stack size exceeded' Welcome the world of recursion. You have just bumped into the error that this site got its name from. – Adam H Jul 18 '18 at 14:34
  • Ah, [see this other question.](https://stackoverflow.com/questions/23260390/node-js-tail-call-optimization-possible-or-not) Looks like the once-available tail call thing has been removed from Node. – Pointy Jul 18 '18 at 14:38
  • You can do this without recursion and use a simple for loop instead, depending on the number passed in this could easily blow the stack. – Adam H Jul 18 '18 at 14:38
  • @AdamH Yeah, I think you're right. The loop-style is ugly but effective. even if factorial(1000000...) also goes well :) – Okato Jul 18 '18 at 14:57
  • There is no such thing as ugly code, there is code that works and then there is code that doesn't work. – Adam H Jul 18 '18 at 15:06

1 Answers1

3

Because Node.js doesn't support tail call optimization, both of these functions will throw the RangeError: Maximum call stack size exceeded error at some point. When this will happen depends on two quantities: the maximum allowed size of the stack and the size of each individual stack frame. By default, the size of the stack is set to some constant value, which you can get by running the following command:

node --v8-options | grep -e '--stack-size' -A 1

So, the only parameter left is the size of the stack frame. factorial stores two variables on the stack on each function call - acc and n. Whereas factorial_normal stores only one - n. It means that factorial will run out of stack space sooner than factorial_normal.

danroshko
  • 466
  • 2
  • 8