import std.stdio;

void main() {    
    auto Y = new class {
        auto opCall(_)(_ f) {
            return (new class {
                auto opCall(_)(_ g) {
                    return new class {
                        auto opCall(_)(_ x) {
                            return f(g(g))(x);
                        }
                    };
                }
            })(new class {
                auto opCall(_)(_ g) {
                    return new class {
                        auto opCall(_)(_ x) {
                            return f(g(g))(x);
                        }
                    };
                }
            });
        };
    };
    
    auto F = new class {
        auto opCall(_)(_ f) {
            return new class {
                auto opCall(_)(_ x) {
                    if (x == 0) {
                        return cast(_)1;
                    } else {
                        return x * f(x - 1);
                    }
                }
            };
        }
    };

    auto factorial = Y(F);
    writeln("fact(5) = ", factorial(10));
    writeln("fact(5) = ", factorial(20L));
}