Re: Closures and __FUNCTION__
| From: | Stanislav Malyshev | Date: | Mon, 13 Apr 2009 21:03:12 +0000 |
| Subject: | Re: Closures and __FUNCTION__ | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-43684@lists.php.net to get a copy of this message | ||
Hi!
The original anonymous functions patch[1] contained support for __FUNCTION__ as a recursion mechanism in closures, such that I should be able to do something like this: $factorial = function($n) {You can also do it the hard way (that's how some languages not having luxury of being PHP do it ;), using something called Y-Combinator (http://en.wikipedia.org/wiki/Y_combinator), which allows you to unroll recursive function into non-recursive one. This looks like this: function Y($F) { $func = function ($f) { return $f($f); }; return $func(function ($f) use($F) {if ($n == 1) return 1; else return $n * call_user_func(__FUNCTION__, $n - 1); };print $factorial(3); // => 6
return $F(function ($x) use($f) {
$ff = $f($f);
return $ff($x);
});
});
}
This is the generic combinator function. Now your factorial function would look like:
$factorial = Y(function($fact) {
return function($n) use($fact) {
return ($n == 0)?1:$n*$fact($n-1);
};
});
And then you can do just this:
var_dump($factorial(3));
Look, ma, no recursion! :)
If it looks confusing, then you're right - it is :) It may be not what you would want to do in your code (or maybe you do), but this is yet another thing now possible with PHP.
On the other hand, we may want to add some way to refer to the closure currently being run. We should have this information, so it should not be too hard to do.
--
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com