Re: Re: PATCH: anonymous functions in PHP
| From: | Jeff Moore | Date: | Tue, 18 Dec 2007 04:44:37 +0000 |
| Subject: | Re: Re: PATCH: anonymous functions in PHP | ||
| References: | 1 2 3 4 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-34075@lists.php.net to get a copy of this message | ||
On Dec 17, 2007, at 10:30 PM, Larry Garfield wrote:
I'm assuming that making the function above GC-able would be a herculean task at this point, based on previous comments, but I do not actually know myself.Hi Larry, Let me use a different example than yours. function getAdder($x) { return function ($y) {
lexical $x;
return $x + $y;
}
}
$plusFive = getAdder(5);
$plusTen = getAdder(10);
echo $plusFive(4); // 9
echo $plusTen(7); // 17
If the closure definition (and thus getAddr) returns a string representing an anonymous function name, then there is no where to hold the enclosing variable $x and no way to know when to free it. Notice that in this example, we have two different enclosing contexts, one where $x is 5 and one where $x is 10.
If we introduce a new variable type, a new kind of zval, then internally, that variable can hold:
1) A reference to the local variables of getAddr. (here $x)
2) A reference to $this if the closure is declared in a method
3) A reference to the opcodes of the compiled anonymous function.
The opcodes for the closure would be compiled and squirreled away when the script is compiled.
When getAddr is executed, a zval would be created that holds the reference to the enclosing locals and a reference to the proper opcodes. Note that $plusFive and $plusTen would hold two different zvals, one for each invocation of getAddr, but that both would refer to the same opcodes structure.
When a codeblock zval is executed, such as at $plusFive(4), the enclosing context can be passed to the anonymous function function to make the lexical $x statement bind to the proper variable.
When the zval in $plusFive reaches zero references, it can subsequently free its references to the local variables of getAddr.
As far as I can see, no herculean garbage collection or reference counting is required.
Adding a new kind of zval? Perhaps that's Herculean. I don't know.
I hope I've gotten my zval terminology right.
Best Regards,
Jeff