siddharth shah
siddharth shah

Reputation: 1147

Debugging recursion in javascript

function fact(n){
  if(n ==1){
    return 1
  } else{
    console.log(fact(n-1))
    return n*fact(n-1)
  }
}

Above is he snippet of the code.

this is the result of debugging recursive factorial code. I don't understand how these 1s are printed, except one last 1 which is returned from the if block

This is the result of debugging recursive factorial code. I don't understand how these 1s are printed, except one last 1 which is returned from the if block.

It would be great if anyone can explain the debugging of this program.

Upvotes: 1

Views: 1237

Answers (4)

Nina Scholz
Nina Scholz

Reputation: 386634

If you like to see what a recursive function is doing, I suggest to use the following pattern to get a valid view of the calling order of the recursion.

  1. Add a level variable, where the depth is counted and maintained.

  2. Use two outputs, one at the beginning of the function and one directly before the return takes place.

  3. Do not call the recursion at the place where you make an output, because this calls the resursion and later on return it calls the recursion again. This leads to more recusions than necessary and looks more complicated than it should be. Take for getting a result of the following recursion a variable and use it for output.


What you get, with this in mind, is the following, the first column denotes the level or depth of the recursion and the second in the first half the funcltion call with the value for n and in the second half the return value.

Same level denotes the same function, which is not ended until the function returns (with or without an explicit value).

Here, the function on level 0 waits for the return value of function with level 1, whereas function with level 2 waits for the result of level 3, and so on until a function returns a value without calling the function again. Basically the recusion ends with this value and all unterminated functions are the terminated by retuning a value, in this case 1, 2, 6, 24 and the final value 120.

level  pos  value                 type          comment
-----  ---  --------------------  ------------  ----------------------------
   0    in    5                   n             wait for result of level 1
   1    in        4               n             wait for level 2
   2    in            3           n             wait for level 3
   3    in                2       n             wait for level 4
   4    in                    1   n             deepest level
   4   out                    1   return value  terminate level 4
   3   out                2       return value  terminate level 3
   2   out            6           return value  terminate level 2
   1   out       24               return value  terminate level 1
   0   out  120                   return value  teminate return final result

function fact(n, level) {
    var returnValue;
    level = level || 0;
    console.log(level, 'in', n);
    if (n == 1) {
        console.log(level, 'out', 1);
        return 1;
    } else {
        returnValue = n * fact(n - 1, level + 1);
        console.log(level, 'out', returnValue);
        return returnValue;
    }
}

console.log(fact(5));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 5

A Khudairy
A Khudairy

Reputation: 1492

This is a strange question .. i wanted to write this as a comment but i thought maybe it is easier to read as answer. The one gets printed (as in @Rickard answer) because your base condition returns 1, and you print the fact(n-1).

Anyways I think it is a big mistake that your log actually calls the function again .. and it doesnt help at all! .. what would be more appropriate is that you do this

var result = n*fact(n-1);
console.log('n: ' + n + ', result: ' + result);
return result;

Then the output would make more sense:

n: 2, result: 2
n: 3, result: 6
n: 4, result: 24
n: 5, result: 120

Upvotes: 1

t.niese
t.niese

Reputation: 40852

You call fact(n - 1) twice in your code, once for the debugging (console.log) and once for its original purpose, that the reasone why you get duplicate values in your debugging output.

To get the correct output you have to save the result of fact(n - 1) in a variable and use that variable for the debug output and the expression.

function fact(n) {
  if (n == 1) {
    return 1
  } else {
    var f = fact(n - 1)
    console.log(f)
    return n * f
  }
}

fact(5)

Upvotes: 0

Rickard Elimää
Rickard Elimää

Reputation: 7591

Put debugger; before if(n ==1){ and step through it in the debugger in the console, and you will notice why.

In short. You return value 1 to console.log(fact(n-1)).

Upvotes: 0

Related Questions