$blog→errstr

do not commit

Z-Combinator and Factorial in Perl

| Comments

Introduction

Since I just did an implementation of the Z-combinator and Factorial in Python, I figured it would be fun to implement in Perl, too. It’s a lot uglier in Perl than Python, but Python is cheating with having a built-in lambda operator.

Implementation

Z = λf. (λx. f (λy. x x y))(λx. f (λy. x x y))
g = λfct. λn. if realeq n c0 then c1 else (times n (fct (prd n))) ;
factorial = Z g
#!/usr/bin/env perl

use warnings;
use strict;

my $Z = sub {
    my ($f) = @_;
    return (sub {
        my ($x) = @_;
        return $f->(sub {
            my ($y) = @_;
            return $x->($x)->($y);
        });
    })->(sub {
        my ($x) = @_;
        return $f->(sub {
            my ($y) = @_;
            return $x->($x)->($y);
        });
    })
};

my $g = sub {
    my ($fct) = @_;
    return sub {
        my ($n) = @_;
        return !$n ? 1 : $n * $fct->($n-1);
    };
};

my $factorial = $Z->($g);

print map { $factorial->($_)."\n" } @ARGV;

So what is the output?

./thelambda.pl 3 5 100
6
120
9.33262154439441e+157