2
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.

2
  • Use a debugger, set a break point at the console.log and step through your code step by step. Then you will see when and why the 1 are shown. Commented Jan 21, 2018 at 10:02
  • 2
    You are printing another call to factorial. So your recursive process is actually generating a tree instead of a linear recursive process. This is what you are not accounting for. Commented Jan 21, 2018 at 10:04

4 Answers 4

6

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; }

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you so much for such a wonderful answer.It was nice to put Levels and, In and out labels. However, i don't understand that after LEVEL 4, how come the counts for the level is decreasing? How come it can go backward? It would be so nice if you can clarify my doubt. Thanks in advance.
you write an output when you get into the function and output when you get out of the function, so first time value is 5 and this is the first call of the function so level is 0, then it makes an inner call to 4 before it types its out statement and so on until you reach level 4, then you exit level 4 back to level 3 which write out statement 3 then out to level 2 then 1 then 0
@siddharthshah every function waits for the result of the calling function. after getting the value, the function itself returns, please see edit. the level is increased by calling with level plus one, here: fact(n - 1, level + 1)
@NinaScholz and @A Khudairy Thank you so much for your help.I really appreciate it. Thanks again
1

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

2 Comments

Hey thanks for answering my question. However, please refer the "Nina Scholz" answer.And Please also refer the added comment. And please answer it again. thank you so much
her answer is perfect
0

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)).

1 Comment

Why the downvote? I explained how to debug in case OP didn't know how to do that, because this issue would had been understood if proper debugging had been done. Then the OP wouldn't write things like "How come it can go backward?".
0

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)

1 Comment

sorry when i answered i didn't see yours :) looks we were writing almost at the same time

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.