Simply said, tail recursion is a recursion where the compiler could replace the recursive call with a "goto" command, so the compiled version will not have to increase the stack depth.
Sometimes designing a tail-recursive function requires you need to create a helper function with additional parameters.
For example, this is not a tail-recursive function:
int factorial(int x) {
if (x > 0) {
return x * factorial(x - 1);
}
return 1;
}
But this is a tail-recursive function:
int factorial(int x) {
return tailfactorial(x, 1);
}
int tailfactorial(int x, int multiplier) {
if (x > 0) {
return tailfactorial(x - 1, x * multiplier);
}
return multiplier;
}
because the compiler could rewrite the recursive function to a non-recursive one, using something like this (a pseudocode):
int tailfactorial(int x, int multiplier) {
start:
if (x > 0) {
multiplier = x * multiplier;
x--;
goto start;
}
return multiplier;
}
The rule for the compiler is very simple: When you find "return thisfunction(newparameters);
", replace it with "parameters = newparameters; goto start;
". But this can be done only if the value returned by the recursive call is returned directly.
If all recursive calls in a function can be replaced like this, then it is a tail-recursive function.