PHP and Recursion

Source: Internet
Author: User

In program design, Recursion is a common concept. Reasonable Use of Recursion can improve the readability of the code, but it may also cause some problems.

The following uses Factorial as an example to illustrate recursive usage. The implementation language is PHP:

<? Php

Function factorial ($ n ){
If ($ n = 0 ){
Return 1;
}

Return factorial ($ n-1) * $ n;
}

Var_dump (factorial (100 ));

?>
If XDebug is installed, the following error may occur:

Fatal error: Maximum function nesting level of '000000' reached, aborting!

Note: This is a protection mechanism of XDebug, which can be set through the max_nesting_level option.

Even if the code runs normally, as long as we increase the number of parameters, the program will report an error sooner or later:

Fatal error: Allowed memory size... Bytes exhausted

Why? To put it simply, recursion causes stack overflow. There are several ways to avoid this problem, such as using Tail Call to eliminate the impact of recursion on stack.

The following uses Lua as the description language to describe the meaning of the End call. The Code is as follows:

Function factorial (n)
If (n = 0) then
Return 1
End

Return factorial (n-1) * n
End

Print (factorial (100 ))
This Code also encounters stack overflow. How can we use the end call? Let's take a look at the definition of the final call: If a function does not do anything else after it executes the callback function call, it is called the final call. The image point is to directly return a function call. The End call does not return the original function, so no additional stack is required to retain the data of the called function. After the code above is changed to the end of the call, it looks like the following code:

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 more information about Lua Tail call, see Proper Tail Recursion.

We use PHP to implement a factorial of the called version at the end:

<? Php

Function factorial ($ n, $ accumulator = 1 ){
If ($ n = 0 ){
Return $ accumulator;
}

Return factorial ($ n-1, $ accumulator * $ n );
}

Var_dump (factorial (100 ));

?>
It is a pity that PHP does not support end-to-end calls only after testing! Fortunately, there is no way to survive. After carefully reading the introduction to the end call in Wikipedia, you will find that the concept of Trampoline is mentioned. To put it simply, we use higher-order functions to eliminate recursion. Based on this theory, we can rewrite the above Code called at the end to the following method:

<? Php

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 )));

?>
It looks good, but I have to apologize to everyone. This article uses Recursion TO IMPLEMENT factorial. In fact, we only need to use a loop, code Daquan specifically mentions this point:

<? Php

Function factorial ($ n ){
$ Result = 1;

For ($ I = 1; $ I <= $ n; $ I ++ ){
$ Result * = $ I;
}

Return $ result;
}

Var_dump (factorial (100 ));

?>
There are also many other methods to avoid stack overflow caused by recursion. For example, in Python, the last call can be eliminated through the decorator and exception, which makes people feel a different kind:

Tail Call Optimization Decorator (Python recipe)
In addition, the blog post by the father of Python on why Python does not support end-to-end calling is also very interesting:

Tail Recursion Elimination
Final Words on Tail CILS
Well, write it here. There is no need to use recursion unless it can improve code readability. It is best to consider using technologies such as Tail Call or Trampoline to avoid potential stack overflow.

Author: Lao Wang

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.