Search code examples
javascriptelixiry-combinator

Y-combinator implementation in javascript and elixir


I've been studying the Y Combinator, and I get how it works on paper, but I don't know yet understand how it can be implemented in a programming language.

According to this page: http://matt.might.net/articles/implementation-of-recursive-fixed-point-y-combinator-in-javascript-for-memoization/

The derivation of Y combinator goes:

Y(F) = F(Y(F))
# Of course, if we tried to use it, it would never work because the function Y immediately calls itself, leading to infinite recursion.
# Using a little λ-calculus, however, we can wrap the call to Y in a λ-term: 
Y(F) = F(λ x.(Y(F))(x))
#  Using another construct called the U combinator, we can eliminate the recursive call inside the Y combinator, which, with a couple more transformations gets us to: 
Y = (λh.λF.F(λ x.((h(h))(F))(x))) (λh.λF.F(λ x.((h(h))(F))(x))) 

How can he expand Y(F) to be λ x.(Y(F))(x)? And how can he use the U Combinator?

Here is the implementation in Javascript and Elixir:

# javascript
var Y = function (F) {
    return (function (x) {
        return F(function (y) { return (x(x))(y);});
    })(function (x) {
        return F(function (y) { return (x(x))(y);});
    });
};

# elixir
defmodule Combinator do
    def fix(f) do
        (fn x -> 
            f.(fn y -> (x.(x)).(y) end) 
        end).(fn x -> 
            f.(fn y -> (x.(x)).(y) end) 
        end)
    end
end

If this is the formula: Y = \f.(\x.f(x x))(\x.f(x x)), what is the relationship between f, x in the lambda expression, and the f, x, y in the implementation above? The x looks like it's the same x, the f looks like the same f. Then what is y? Specifically why is the lambda equivalent of x x being wrapped in a function that uses y?

Is y kind of like the arguments to the function!?


Solution

  • Is y kind of like the arguments to the function!?

    Yes, exactly. Lambda calculus is implicitly curried. Instead of x x you might as well write \y.x x y.