Question on Recursion - countDownAndUp example

In the “Decimal to Binary Converter” course, the countDown and countDownAndUp examples are used to teach recursion. I attach the codes for your easy reference.

countDown function (prints “3 2 1 0” on the console)

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

  if (number === 0) {
    return;
  } else {
    countdown(number - 1);
  }
};

countdown(3);

countDownAndUp (prints “3 2 1 0 Reached base case 1 2 3” on the console)

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

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

countDownAndUp(3);

I would like to ask, while both codes look very similar, the difference is the addition of console.log for “if” and “else” in countDownAndUp.

Why did countDown stop at 0 without going back up? Or is it just not printed on the console?
And why did countDownAndUp not print “0” when it goes back up?

Kinda confused here, thanks in advance for your kind help! :slightly_smiling_face:

Let’s break down the behavior of both functions:

  1. countDown Function:
const countdown = (number) => {
  console.log(number);

  if (number === 0) {
    return;
  } else {
    countdown(number - 1);
  }
};

countdown(3);
  • This function counts down from the given number to 0.
  • When countdown(3) is called, it prints:
3
2
1
0
  • The function stops when it reaches 0 because of the base case check (if (number === 0)). At that point, it doesn’t make any further recursive calls, so it returns back through the call stack.
  1. countDownAndUp Function:
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 function also counts down from the given number to 0 and then counts back up to the original number.
  • When countDownAndUp(3) is called, it prints:
3
2
1
0
Reached base case
1
2
3
  • Here, countDownAndUp is a combination of two recursive calls:
    • The first call (countDownAndUp(number - 1)) counts down to 0.
    • After the base case (when number === 0) is reached, it prints “Reached base case” and returns.
    • Then, as the recursion unwinds, it starts printing numbers again in ascending order, as it goes back up the call stack.

So, to address your questions:

  • Why did countDown stop at 0 without going back up? Or is it just not printed on the console?
    • The countDown function did reach 0 and it didn’t continue further because there were no more recursive calls after that. It indeed stopped at 0, and yes, it printed “0” on the console.
  • Why did countDownAndUp not print “0” when it goes back up?
    • The “0” is indeed printed by countDownAndUp. However, it is printed before the “Reached base case” message. After printing “0”, it returns from the base case, then it starts counting up, printing 1, 2, and 3 in sequence.
1 Like

Difference between the two is really just in what is printed to console. In the background both functions get to the same point - base case - and then go back unwinding the recursive calls. However only the second function has anything printed during that part.

To differentiate the console.log(number):

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

  if (number === 0) {
    console.log("Reached base case");
    return;
  } else {
    countDownAndUp(number - 1);
    console.log('b', number);
  }
};
a 3
a 2
a 1
a 0
Reached base case
b 1
b 2
b 3

Thank you @ChaosFunds and @sanity for the explanations! I am starting to understand this.

I have an additional question. In both functions, unwinding of recursive calls occurs. There is console.log(number); in the second line of BOTH functions, so why is the unwinding not printed in the console of countDown function?

Or rather, can you please highlight which line of the code causes the printing of counting up (i.e. “1 2 3”) in the console only for countDownAndUp, but not for countDown?

Thanks~

Take another look at the example from my post, the counting up is printed by console.log('b', number) below the recursive call. countDown simply is not printing anything after that.

The count down before reaching base case is made by console.log() at the first line in function.

@sanity Your usage of ‘a’ and ‘b’ in your example definitely helps! :slightly_smiling_face:

For the unwinding process, can its sequence of code execution be shown?

For example, is its sequence:

console.log("Reached base case");
return;
console.log('b', 1);
countDownAndUp(2);
console.log('b', 2);

and so on?

I just remembered there’s great tool that helps visualizing what happens when, paste to it one of the functions, including function call:
https://pythontutor.com/javascript.html#mode=edit

@sanity Huge thanks for that awesome link! I’ve bookmarked it for future use.

Appreciate your help, I totally understand now :smile: