I noticed the common definition of recursion that "It is a function calling itself" is wrong.
Wait! Don't react yet. Hear me out first; is the function below a loop or recursion?
Note: If you want a video version of this explanation, watch What is recursion.
function countdown(count) {
console.log(count);
if(count > 1) {
count = count - 1;
countdown(count);
} else {
return;
};
};
// access function
countdown(5);
I know you're probably going to say it is recursion because of the common definition but it is not — it is a loop.
If you check the console, nothing will be repeated but the output of recursion must be a repetition of a structure.
Is recursion really a case of a function calling itself? I don't think so.
I came to this realization when I was building koras.jsx that uses Constant Reactivity and it is implemented in a way that looks like it is recursive but it is not.
I will get back to that later but let's focus on recursion first. Then, what is recursion if it is not a function calling itself?
Before I define what recursion is, it is important I define what a loop is for clarification.
What is a loop?
A loop is an operation that applies a process to a series or sequence of elements once until the last element (if any) or continue till infinity.
That means a loop doesn't go back to reapply the same process to already processed elements.
Now, let's go back to the previous function so that you realize it is a loop:
function countdown(count) {
console.log(count);
if(count > 1) {
count = count - 1;
countdown(count);
} else {
return;
};
};
// access function
countdown(5);
You will notice that, even though the function calls itself to move to the next line of action, it doesn't reapply the same process to the same element(s).
If you log the count in the console, nothing will be recursive, that is, repeat the same index, structure or item(s).
That means, you can implement a loop with a function. So a function calling itself is not a criterion to determine a recursion.
Let's compare the function above with a while loop for clarification.
let depth = 5;
while(depth > 0){
console.log(depth)
depth--;
}
The countdown function
is very similar to the above while loop because they get similar results with similar structures. Can you see it is a loop? Okay.
Did you say "How do you define and identify a recursion?"? Keep on reading.
What is recursion?
It is a repetition of an operation on the same element(s) by always starting from the beginning to the end and then starting again, again and again until the stopping point (if any); if not, it continues till infinity.
Recursion always repeats the same process on the same elements several times until the stopping point is reached or it continues till infinity.
We have some examples of recursion in the real world. A good example are the days of the week or February 14.
A week always starts from Monday; continues to Sunday and goes backs to Monday again, again and again.
Here we are again; it is VAL🥰. Isn't VAL recursive? Yes, it is.
That is recursion.
If you write a function to achieve weeks in continuity, it will automatically be recursive because you will always reapply the same process to the same elements again and again.
And if you log it to the console, you will see that items will be repeated in a certain structure, if not, it is not recursion.
You can achieve recursion with a loop or a function. So, instead of saying a recursion is defined as a function calling itself, you had better say it is a repeated process reapplied to or within the same element(s).
Now, let's write true recursion with a loop and a function.
We're going to turn the previous countdown
function to recursion by backtracking it.
function startCountdown(n, backtrackCount = 0) {
if (backtrackCount >= 5) {
console.log("Countdown stopped after 5 backtracks.");
return;
}
console.log(n);
n--;
if (n === 0) {
console.log("Restarting countdown!");
startCountdown(5, backtrackCount + 1);
} else {
startCountdown(n, backtrackCount);
}
}
startCountdown(5);
That is true recursion. If you check the console, you will see that a structure is repeated.
We can achieve the same with a while loop as in below:
function countdown(n) {
let backtrackCount = 0;
while (backtrackCount < 5) {
console.log(n);
n--;
if (n === 0) {
console.log("Restarting countdown!");
n = 5;
backtrackCount++;
}
}
console.log("Countdown stopped after 5 backtracks.");
}
countdown(5);
We get the same results despite the second function doesn't call itself.
If it achieves recursive effects without calling itself, isn't it wrong or incomplete to say recursion is a function calling itself? Yes it is wrong!
That is an obvious explanation to claim a function calling itself is not a correct definition of recursion and so it is misrepresenting what recursion is.
You should know that the first code example you gave is in fact recursion. Your base case is present, and the function is called recursively with a consistently modified parameter until the base case is satisfied. Your
if-else
block is an example of a base statement.Why this is a recursive function:
Self-Referencing Call
if
statement:Base Case and Recursive Case
(Stops recursion when
count
reaches1
.) This prevents infinite recursion, which would otherwise lead to a stack overflow.(Keeps calling itself with a decremented value.)
Function Call Stack
Why it's NOT a loop:
for
,while
,do-while
) executes code repeatedly within the same execution context, modifying variables without calling itself.