Help with recursion to create a range of numbers

So, here’s my solution to the problem:

function rangeOfNumbers(startNum, endNum) {

  if (startNum > endNum) {

    return [];

  }

  else {

    const countArray = rangeOfNumbers (startNum + 1, endNum);

    countArray.unshift(startNum);

    return countArray;

  }

};

My solution is different from the solutions provided but it passes and is all fine, and I nearly understand why it works, even though recursive functions have taken me a while to understand.

There is one line of the code I don’t understand:


 const countArray = rangeOfNumbers (startNum + 1, endNum);

Why does our variable need to be assigned to the function with different values?
Is this the line of code that calls the function again with different values? If so, why do we need to assign to a variable?

Hope someone can help me with that, still new to JavaScript so I apologize if it’s a dumb question.

Thank you

It’s the exact opposite actually: you don’t assign variables, you assign values to variables. (or you bind values to varaibles if you prefer).

So what’s happening in that line is that you are binding the returned value of the function to a variable.

So you are using in your code block whatever value is returned by calling the function.
For example:

 const countArray = rangeOfNumbers (6, 3); // []
// countArray is an empty array in this case, as the function will return [].

Hope this helps.

1 Like

@Marmiz Thank you for your reply. It is a little more clear how it works.

Something I still don’t get is the WHY.

Why do I need to do that? Couldn’t I just call the function with different values and return the new results? Why do I need to declare a variable and bind the value of the function to it?

again, this might be a stupid question but I feel like I need to ask all of my stupid questions until I run out :laughing:

I’m on my phone so it was long to type. Can you try to understand this. I would really love to explain it to you if you don’t get it later on when I get on my laptop knowing how I struggled a lot myself in the beginning while trying to understand recursion.

I even had made a video in youtube but it’s in my language otherwise I would have shared. I can make one in English if you still don’t understand till the end later on.

1 Like

@ankurchaulagain Thank you for your help! the diagram does help! still not clear 100% though. If you can write it out for me a little more clearly later when you have time that would be very helpful! thank you

1 Like

@valeriocipolla92, no question are stupid, don’t apologize for being curious :slight_smile:

In your mind, how such a process would work?

I’ll explain how it is working now, and hopefully you’ll get why you cannot “just call the function”.

When the engine execute a function, it will add it to the the stack.
You can imagine the stack like a pile of dishes waiting to be cleaned.
You keep adding dished on top, and you start cleaning from top.
(last in, first out).

Imagine I have called the function with these values:

rangeOfNumbers(1, 3)

The computer will reach the point where in your body you want to call

rangeOfNumbers (startNum + 1, endNum);

This means that a new function (a “dish” in the pile) is added on top.
So now it moves to the top “dish” rangeOfNumbers (2, 3);

This cycle continue as all this function keep adding stuff to the pile,
Until you finally reach the “dish” rangeOfNumbers(4,3).

That function, will return a value: [].
This means no more piling stuff, but actually be able to finally remove from it.

So now, the 2nd “dish” will finally receive:

const countArray = []

Meaning that it can go on with its execution:

countArray.unshift(startNum); 

return countArray; // return [3]

Now that this function is done, the engine will keep resolving functions as they were added to the pile. Something like:

[]
[3]
[2, 3]
[1, 2, 3]

Why we cannot simply “call the functions”, without one referencing each other there would be no way for the engine to know that you need that value in another “dish” in the pile, as well as… how exactly can you keep adding data if you don’t keep track of it? :slight_smile:

Hope it helps clarify thing better.

There’s also a website that lets you see function executions interactively:
http://pythontutor.com/

(don’t worry, it supports JS as well).

Happy coding :sparkles:

1 Like

@Marmiz Thanks a lot. That makes a lot more sense now.

Just to make sure I understand:

countArray.unshift(startNum);

    return countArray;

doesn’t execute until the case base is reached.

Now, when I say when can’t we just call the function without assigning it to a variable, I mean something like this:

function rangeOfNumbers(startNum, endNum) {

  if (startNum > endNum) {

    return [];

  }

  else {

    rangeOfNumbers (startNum + 1, endNum);

    

    let countArray =[];

    countArray.unshift(startNum);

    return countArray;

  }

};

console.log(rangeOfNumbers(1,3));

This function will output

[1]

And I am not sure I understand why.

Now, I know that the answer to my question is here somewhere:

But could you expand a little more on that and explain to me what’s happening in the machine with the 2nd code and why the output is [1]?

I appreciate your help.

Each function has its own lexical scope. This means that its function is aware of what its in its body as well what it surrounds it.

Each time you add a new function to your pile, each one of that will use evaluate its body.

Meaning that it doesn’t matter what you return from your recursion, every time countArray will be an empty array… because you specifically said so here:

let countArray =[];

Or in other words, you are not using what the function is returning, but arbitrarily choose that countArray should be an empty array.

1 Like

Thank you @Marmiz it makes more sense now. Just got to keep studying now :laughing:

You should try this code to create a range of numbers

function rangeOfNumbers(startNum, endNum) {
  if (endNum - startNum === 0) {
    return [startNum];
  } else {
    var numbers = rangeOfNumbers(startNum, endNum - 1);
    numbers.push(endNum);
    return numbers;
  }
}

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