Golfed fixed point combinator
Haskell: 10 characters
y f=f$y f
Example of use to create recursive definitions of factorial or nth-Fibonacci:
> map ( y(\f n->if n <= 1 then 1 else n*f(n-1)) ) [1..10]
[1,2,6,24,120,720,5040,40320,362880,3628800]
> map ( y(\f n->if n <= 1 then 1 else f(n-1)+f(n-2)) ) [0..10]
[1,1,2,3,5,8,13,21,34,55,89]
Though, a more common way to use y
would be to generate these sequences directly, rather than as functions:
> take 10 $ y(\p->1:zipWith (*) [2..] p)
[1,2,6,24,120,720,5040,40320,362880,3628800]
> take 11 $ y(\f->1:1:zipWith (+) f (tail f))
[1,1,2,3,5,8,13,21,34,55,89]
Of course, with Haskell, this is a bit like shooting fish in a barrel! The Data.Function
library has this function, called fix
, though implemented somewhat more verbosely.
Perl, 37
sub f{my$s=$_[0];sub{$s->(f($s),@_)}}
Factorial demonstration:
sub fact {
my ($r, $n) = @_;
return 1 if $n < 2;
return $n * $r->($n-1);
}
print "Factorial $_ is ", f(\&fact)->($_), "\n" for 0..10;
Fibonacci demonstration:
sub fib {
my ($r, $n) = @_;
return 1 if $n < 2;
return $r->($n-1) + $r->($n-2);
}
print "Fibonacci number $_ is ", f(\&fib)->($_), "\n" for 0..10;
GNU C - 89 chars
#define fix(f,z)({typeof(f)__f=(f);typeof(__f(0,z))x(typeof(z)n){return __f(x,n);}x(z);})
Example:
#define lambda2(arg1, arg2, expr) ({arg1;arg2;typeof(expr)__f(arg1,arg2){return(expr);};__f;})
int main(void)
{
/* 3628800 */
printf("%ld\n", fix(lambda2(
long factorial(int n), int n,
n < 2 ? 1 : n * factorial(n-1)
), 10));
/* 89 */
printf("%ld\n", fix(lambda2(
long fibonacci(int n), int n,
n < 2 ? 1 : fibonacci(n-1) + fibonacci(n-2)
), 10));
return 0;
}