Learn Recursion by Building a Decimal to Binary Converter

This step is passing, but I don’t understand how it works. Why does the recursive function print out anything after the return statement? Doesn’t return end the function call?

const countDownAndUp = (number) => {
  console.log(number);

  if (number === 0) {
    console.log("Reached base case");
    return;
  } else {
    countDownAndUp(number - 1);
    console.log(number);
  }
};

countDownAndUp(3);

This is what is output to the console:
3
2
1
0
Reached base case
1
2
3

the return ends the function call, but notice how console.log(number) prints 4 different values, that means you have 4 different function calls here. So, return stops a function, but then it goes to the other function

Thanks for the explanation. It’s still somewhat confusing, but I think I understand

Just to clarify a bit, the way this works is like this?
Initial call: countDownAndUp(3) prints 3 to the console and then calls the inner function recursively.
Recursive calls: countDownAndUp(2), countDownAndUp(1), countDownAndUp(0) (base case). This represents three inner function calls and prints 2, 1, and 0.
During each recursive function call, the outer function and its parameter are added to the call stack (four times): countDownAndUp(3), countDownAndUp(2), countDownAndUp(1), countDownAndUp(0), but they are not yet executed.
The outer function calls remaining on the call stack are executed in first-in-last-out (reverse) order, removing them from the callstack after they’re called:
countDownAndUp(0) returns and prints “Reached base case”
countDownAndUp(1) resumes execution after the recursive call and prints 1.
countDownAndUp(2) resumes execution after the recursive call and prints 2.
countDownAndUp(3) resumes execution after the recursive call and prints 3.

You are generally correct, but let me clarify this further:

The process begins with the invocation of the countDownAndUp(3) function:

  • The value 3 is logged to the console using console.log(3).
  • Since the condition number === 0 is not met, the else block executes.
  • The function is recursively called again with number - 1.

The countDownAndUp(2) function is called inside countDownAndUp(3):

  • The value 2 is logged to the console using console.log(2).
  • Since the condition number === 0 is not met, the else block executes.
  • The function is recursively called again with number - 1.

The countDownAndUp(1) function is called inside countDownAndUp(2):

  • The value 1 is logged to the console using console.log(1).
  • Since the condition number === 0 is not met, the else block executes.
  • The function is recursively called again with number - 1.

The countDownAndUp(0) function is called inside countDownAndUp(1):

  • The value 0 is logged to the console using console.log(0).
  • Since the condition number === 0 is met, the message “Reached base case” is logged to the console, and the function terminates.

Returning to the countDownAndUp(1) function where it left off:

  • The value 1 is logged to the console using console.log(1) inside of else block.
  • Then, the countDownAndUp(1) function completes, and control returns to countDownAndUp(2).

Returning to the countDownAndUp(2) function where it left off:

  • The value 2 is logged to the console using console.log(2).
  • Then, the countDownAndUp(2) function completes, and control returns to countDownAndUp(3).

Returning to the countDownAndUp(3) function where it left off:

  • The value 3 is logged to the console using console.log(3).
  • Finally, the countDownAndUp(3) function completes.

These steps demonstrate that the function operates recursively, accumulating frames on the stack for each call. Each countDownAndUp function call creates a frame on the stack, and these frames are processed in a Last In, First Out (LIFO) manner. Initially, a countdown from 3 to 0 occurs, followed by counting back up from 1 to 3, resulting in each number being logged to the console in sequence.

1 Like

Here is an animation of the steps.
recursion

Happy coding

1 Like