Whilst starting to learn lisp, I\'ve come across the term tail-recursive. What does it mean exactly?
The recursive function is a function which calls by itself
It allows programmers to write efficient programs using a minimal amount of code.
The downside is that they can cause infinite loops and other unexpected results if not written properly.
I will explain both Simple Recursive function and Tail Recursive function
In order to write a Simple recursive function
From the given example:
public static int fact(int n){
if(n <=1)
return 1;
else
return n * fact(n-1);
}
From the above example
if(n <=1)
return 1;
Is the deciding factor when to exit the loop
else
return n * fact(n-1);
Is the actual processing to be done
Let me the break the task one by one for easy understanding.
Let us see what happens internally if I run fact(4)
public static int fact(4){
if(4 <=1)
return 1;
else
return 4 * fact(4-1);
}
If
loop fails so it goes to else
loop
so it returns 4 * fact(3)
In stack memory, we have 4 * fact(3)
Substituting n=3
public static int fact(3){
if(3 <=1)
return 1;
else
return 3 * fact(3-1);
}
If
loop fails so it goes to else
loop
so it returns 3 * fact(2)
Remember we called ```4 * fact(3)``
The output for fact(3) = 3 * fact(2)
So far the stack has 4 * fact(3) = 4 * 3 * fact(2)
In stack memory, we have 4 * 3 * fact(2)
Substituting n=2
public static int fact(2){
if(2 <=1)
return 1;
else
return 2 * fact(2-1);
}
If
loop fails so it goes to else
loop
so it returns 2 * fact(1)
Remember we called 4 * 3 * fact(2)
The output for fact(2) = 2 * fact(1)
So far the stack has 4 * 3 * fact(2) = 4 * 3 * 2 * fact(1)
In stack memory, we have 4 * 3 * 2 * fact(1)
Substituting n=1
public static int fact(1){
if(1 <=1)
return 1;
else
return 1 * fact(1-1);
}
If
loop is true
so it returns 1
Remember we called 4 * 3 * 2 * fact(1)
The output for fact(1) = 1
So far the stack has 4 * 3 * 2 * fact(1) = 4 * 3 * 2 * 1
Finally, the result of fact(4) = 4 * 3 * 2 * 1 = 24
The Tail Recursion would be
public static int fact(x, running_total=1) {
if (x==1) {
return running_total;
} else {
return fact(x-1, running_total*x);
}
}
public static int fact(4, running_total=1) {
if (x==1) {
return running_total;
} else {
return fact(4-1, running_total*4);
}
}
If
loop fails so it goes to else
loop
so it returns fact(3, 4)
In stack memory, we have fact(3, 4)
Substituting n=3
public static int fact(3, running_total=4) {
if (x==1) {
return running_total;
} else {
return fact(3-1, 4*3);
}
}
If
loop fails so it goes to else
loop
so it returns fact(2, 12)
In stack memory, we have fact(2, 12)
Substituting n=2
public static int fact(2, running_total=12) {
if (x==1) {
return running_total;
} else {
return fact(2-1, 12*2);
}
}
If
loop fails so it goes to else
loop
so it returns fact(1, 24)
In stack memory, we have fact(1, 24)
Substituting n=1
public static int fact(1, running_total=24) {
if (x==1) {
return running_total;
} else {
return fact(1-1, 24*1);
}
}
If
loop is true
so it returns running_total
The output for running_total = 24
Finally, the result of fact(4,1) = 24