Basic JavaScript - Use Recursion to Create a Countdown

Hey freeCodeCampers! I am just I think finally understanding this problem for recursion in this example from “Use Recursion to Create a Countdown.”
What I was having trouble with was understanding the countup() function in the example and I think I have pieced it together.

I am posting to make sure I am understanding correctly, and if I am, I think it might help others to understand it who were as dense as me, where reading comment after comment and seeing the diagram I was still missing something.

What I did to help me see what was happening in the countup() example, was type it out in a document so I could physically create the stack so as I worked through the example I could watch it form and then see how it would execute at the end. Again, I may be wrong which is why I am posting here.

So what I understand is that as:

      console.log(countup(5));

is called, it goes to the else statement and runs the code:

      const countArray = countup(5 - 1) ;

AND also puts:

      countArray.push(5);

on the pile or “stack” basically to deal with later (Since the first part of the code can’t complete, it cannot actually run this code, but it places it there to remember it later. Like a sticky note on a desk)

Then the computer will run:

      countup(4); 

which also goes to the else statement and runs:

      const countArray = countup(4-1);

AND puts

      countArray.push(4);

on TOP of the previous sticky note, essentially, so now in the pile you have:

      countArray.push(4);
      countArray.push(5);

Then it goes back to run:

      countup(3);

which will go to else statement again:

      const countArray = countup(3-1)

AND put countArray.push(3) on the stack so now the pile is:

      countArray.push(3);
      countArray.push(4);
      countArray.push(5);

then it goes back to run:

      countup(2);

which will go to the else statement again and run:

      const countArray = countup(2-1);

AND put countArray.push(2) on the stack so now the pile is:

      countArray.push(2);
      countArray.push(3);
      countArray.push(4);
      countArray.push(5);

then it goes back to run:

      countup(1);

which will go to else statement and run:

      const countArray = countup(1-1)

AND put countArray.push(1) on the stack so now the pile is:

      countArray.push(1);
      countArray.push(2);
      countArray.push(3);
      countArray.push(4);
      countArray.push(5);

now when the code goes to run:

      countup(0);

it hits the base case if statement runs:

      return [];

which is an an empty array. BUT there is still the stack of code waiting to execute, so it will now run from top to bottom, pushing all of the numbers into the back of the array:

      countArray.push(1); => [1]
      countArray.push(2); => [1, 2]
      countArray.push(3); => [1, 2, 3]
      countArray.push(4); => [1, 2, 3, 4]
      countArray.push(5); => [1, 2, 3, 4, 5]

I am sure after typing this all out, that it is important to note that it is also returning the value for countArray each time, but it helped to just see it without that for a minute. Or maybe I am not understanding this part correctly, but I figured this was the best way to find out!

Thanks if you have read this, I am going to work to complete this exercise now, as I think I can create what it is asking of me, in the countdown() exercise, but it was driving me BONKERS not understanding how the countup() worked.

Please let me know if I am missing something or if this is generally how it is working.

THANKS AGAIN! :slight_smile:

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36

Challenge Information:

Basic JavaScript - Use Recursion to Create a Countdown

2 Likes

That’s a really nice write-up. It’s pretty close, what you are describing is a bit similar to async execution, when function continues despite of not necessarily having everything already calculated. However that’s more isolated - in the individual function calls. Result of one function will not be available (instead it’s a kind of placeholder) until other calls on which it depends are not available - rather than putting individual lines from multiple functions that are not yet executed into some shared stack.

The actual execution is in certain aspects more straightforward.

Once function executing countup(5) reach this line:

const countArray = countup(5 - 1);

Function stops, because countup(4) is called. The countup(4) is executed. It executes until it reach the equivalent line:

const countArray = countup(4 - 1);

This goes on until countup(0) is called. countup(0) returns [].

At this point the function countup(1) continues execution and pushes 1 to the countArray. And so on all the way back to the countup(5) which pushes 5 to array returned by countup(4) - [1, 2, 3, 4] and returns the final result of the countup(5) call.

There’s a very helpful tool that helps with visualizing code execution:
https://pythontutor.com/javascript.html#mode=edit

3 Likes

Thank you for your reply! Your explanation helps a lot, and so does that visualizer tool. I will be coming back to that many times, I had no idea something like that existed!

So if I understand correctly, after this code:

const countArray = countup( 5 - 1 );

tries to run, it pauses and sort of bookmarks where to come back to since it cannot continue until the next countup(4) is run, but that also pauses because it needs countup(3), and so on and so forth.

Then when it gets to the empty array, it has completed and can go back and finish running each spot where it left off before.

So it isn’t creating those lines of code to run in a pile or a stack, but essentially bookmarking those places once it has what it needs so it can finish running?

I am not sure if that makes sense… but I feel like I am getting closer to understanding this. lol

1 Like

I think you got it already, but want to find a specific term to call it.

What is happening is not really different from normal function call within another function. The calling function is stopped while the called function is executed. Then after that’s finished, calling function resumes.

The part that makes this not look normal is fact it’s the same function called over and over again, until it’s able to get concrete result.