Re: Closures and __FUNCTION__

From: 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) {
      if ($n == 1)
        return 1;
      else
        return $n * call_user_func(__FUNCTION__, $n - 1);                                                                                                              };
  print $factorial(3);                  // => 6                                                                                                          
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) {
	        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

« previous php.internals (#43684) next »