views:

254

answers:

3

Is it possible to have a PHP function that is both recursive and anonymous? This is my attempt to get it to work, but it doesn't pass in the function name.

$factorial = function( $n ) use ( $factorial ) {
    if( $n == 1 ) return 1;
    return $factorial( $n - 1 ) * $n;
};
print $factorial( 5 );

I'm also aware that this is a bad way to implement factorial, it's just an example.

+6  A: 

In order for it to work, you need to pass $factorial as a reference

$factorial = function( $n ) use ( &$factorial ) {
    if( $n == 1 ) return 1;
    return $factorial( $n - 1 ) * $n;
};
print $factorial( 5 );
Zurahn
+1, see also http://php100.wordpress.com/2009/04/13/php-y-combinator/
stereofrog
+1  A: 

Try this (uses global):

 $factorial = function($n) {
   global $factorial;
   if ($n == 1) return 1;
   return $factorial($n - 1) * $n;
 };

or (using create_function and nowdoc)

 $factorial = create_function('$n', <<<'EOL'
   global $factorial; 
   if( $n == 1 ) return 1;
   return $factorial($n - 1) * $n;
   EOL
 );
St. John Johnson
Thats a very long example
streetparade
What do you mean?
St. John Johnson
+1  A: 

I know this might not be a simple approach, but I learned about a technique called "fix" from functional languages. Since PHP doesn't support currying, it's a bit of a hack, but I think it's interesting.

function fix( $func )
{
    return function() use ( $func )
    {
        $args = func_get_args();
        array_unshift( $args, $func );
        return call_user_func_array( $func, $args );
    };
}

$factorial = function( $func, $n ) {
    if( $n == 1 ) return 1;
    return $func( $func, $n - 1 ) * $n;
};
$factorial = fix( $factorial );

print $factorial( 5 );
Kendall Hopkins