I have built a y-combinator in js like this
const y = f => { const g = self => x => f(self(self))(x); return g(g);}
and I simplified this code like this
const y = f => { const g = self => f(self(self)); return g(g);}
this get an infinite recursion. What's the difference between these two versions?
If you don't understand the difference between the two, I would be surprised that you actually built them. Nevertheless, perhaps the best way to demonstrate the difference between the two, is to follow their evaluation
Ok, so
y(z)
(wherez
is some function, it doesn't matter) returns a functionx => ...
. Until we apply that function, evaluation stops there.Now let's compare that to your second definition
So
y (z)
never terminates – at least in JavaScript which uses applicative order evaluation – where function arguments are evaluated before the called function is appliedAlternate Y-combinators
Here we can build a Y-combinator from the ground up
Let's test it out
Or my recent favourite