In programming, recursion (recursion) is a very common concept, the rational use of recursion, can improve the readability of the code, but also may bring some problems.
The following is an example of factorial (factorial) to illustrate the use of recursion, the implementation language is PHP:
function factorial ($n) {
if ($n = = 0) {
return 1;
}
return factorial ($n-1) * $n;
}
Var_dump (factorial (100));
?>
If Xdebug is installed, you may encounter the following error:
Fatal error:maximum function nesting level of ' 100′reached, aborting!
Note: This is a protection mechanism for xdebug, which can be set by the Max_nesting_level option.
Even if the code works, as long as we constantly increase the parameters, the program will error sooner or later:
Fatal error:allowed memory size of ... bytes exhausted
Why is it? The simple point is that recursion causes the stack overflow. There are several ways to circumvent this problem, such as using tail calls (Tail call) to eliminate the effect of recursion on the stack.
The following describes the meaning of the tail call with Lua as the description language, with the following code:
function factorial (n)
if (n = = 0) Then
Return 1
End
return factorial (n-1) * n
End
Print (factorial (100))
This code also encounters a stack overflow problem. How do I use the tail tone to fix it? Let's take a look at the definition of the tail call: If a function has performed a function call, it will not do anything else called a tail call. The image point is that it returns a function call directly. The tail call does not return the original function, so no additional stack is required to retain the data of the calling function. The above code looks like the following code after the tail call:
function factorial (n, accumulator)
ACCUMULATOR = ACCUMULATOR or 1
if (n = = 0) Then
return accumulator
End
return factorial (n-1, accumulator * N)
End
Print (factorial (100))
Note: For a description of the end call in Lua, refer to: Proper Tail recursion.
Tiger, we use PHP to implement the factorial of a tail-call version:
function factorial ($n, $accumulator = 1) {
if ($n = = 0) {
return $accumulator;
}
return factorial ($n-1, $accumulator * $n);
}
Var_dump (factorial (100));
?>
Unfortunately after the test only found that PHP does not support tail calls at all! Fortunately despair, read the introduction of the end call in Wikipedia, and you will find that the concept of trampoline is mentioned. The simple point is that the use of higher-order functions to eliminate recursion, according to the theoretical basis, we can put the above tail call code to rewrite the following way:
function factorial ($n, $accumulator = 1) {
if ($n = = 0) {
return $accumulator;
}
return function () use ($n, $accumulator) {
return factorial ($n-1, $accumulator * $n);
};
}
function trampoline ($callback, $params) {
$result = Call_user_func_array ($callback, $params);
while (Is_callable ($result)) {
$result = $result ();
}
return $result;
}
Var_dump (Trampoline (' factorial ', Array (100)));
?>
Looks good, but I have to apologize to everyone, this article with recursive implementation of factorial is actually a joke, in fact, as long as a loop on the line, "Code encyclopedia" specifically mentions this:
function factorial ($n) {
$result = 1;
for ($i = 1; $i <= $n; $i + +) {
$result *= $i;
}
return $result;
}
Var_dump (factorial (100));
?>
There are many other ways to avoid recursive stack overflow problems, such as python can be used to eliminate the tail call through decorators and exceptions, so that people have a sense of Shia:
Tail Call Optimization Decorator (Python recipe)
In addition, the father of Python's blog about why it doesn't support tail calls in Python is also interesting:
Tail recursion Elimination
Final Words on Tail Calls
All right, let's just write about it. It is not necessary to use recursion unless you can improve the readability of the code, and it is best to consider techniques such as tail call or trampoline to circumvent potential stack overflow problems.
Author:: Lao Wang
http://www.bkjia.com/PHPjc/478119.html www.bkjia.com true http://www.bkjia.com/PHPjc/478119.html techarticle in programming, recursion (recursion) is a very common concept, the rational use of recursion, can improve the readability of the code, but also may bring some problems. The following factorial ...