How and why is code waiting (recursion)? feels strange

First of all, i am a beginner and dont have any coding background.

It is about this example:

function countup(n) {
  if (n < 1) {
    return [];
  } else {
    const countArray = countup(n - 1);
    countArray.push(n);
    return countArray;
  }
}
console.log(countup(5));

As far as is understand the code is executing from (countup 5 to 1) and is “waiting” to execute the push command but dont find an an array.

Then countup (0) is happening and a empty array appears.

Now the code can execute the “waiting” push commands to the empty array.

Now i have two questions:

  1. Why is the push command of countup (1) executed first?

and this is the more important question 2) why is code “waiting”? For me it seems very strange, that the push command dont find an array and instead to “fail” or “disappear” its “waiting”?

Till now coding was very logical and followed a structured order (i did only a few hundred hours HTML and CSS before this Javascriptcourse). But with this example it feels strange (no i am not on drugs or anything else :smiley: ), not like the always logic nature of code. Could maybe someone explain how its happening and the inherent logic behind it.

Thanks for answers to this unusual question

The code is ‘waiting’ for the function call to complete. In every single line of Javascript you have written so far, the code runs line by line. Recursion is the same. countup(5) must wait for countup(4) to finish. countup(4) must wait for countup(3)… And so on. Each function call is separate, and each function call must complete before the code can continue.

    const countArray = countup(n - 1); // THIS LINE COMPLETELY FINISHES AND RETURNS AN ARRAY WITH [1, 2, 3, ..., n-1]
    countArray.push(n); // AND THEN THIS LINE RUNS, PUSHING n ONTO THE END OF THE ARRAY
    return countArray; // AND THEN THE ARRAY IS RETURNED (TO WHEREVER IT WAS CALLED, WHICH MAY BE countup(n+1))

When function A calls another function B, A waits until function B completes (and returns a value). So here’s a chain of call.

function zero( ) {
  return [ ];
}

function one( ) {
 const x = zero(); //x is [ ]
 x.push(1); //x is now [1]
 return x;
}

function two() {
  const x = one(); //x is [1]
  x.push(2); //x is now [1, 2]
 return x;
}

const myArray = two();

Here we have a control flow of
→ two → one → zero
We call two, two calls one, one calls zero. And the result goes back from zero to one and one to two and so forth. Does this sequence of function calls and how the values are returned make sense?

Since you cannot keep on writing more functions, to make it more general and practical, we define a function that calls itself, function A calls function A itself. It looks like an infinite calls, but the trick is we pass different value. Function A gets n and calls Function A (its clone) but passes n-1, for example. Because we’re passing different values, we include a test to stop recursive calls. Once the recursion stops, we start passing the result back to the caller.

Sequence of calls for the recursive function would look like this

2 Likes

Thank you guys, i am understanding it, not yet 100% (but i think its not necessary at this point), but a lot more as before your explanations :slight_smile:

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.