//first self reference
var fact = function(self){
return function(n){
if(n == 0) return 1;
else return n * self(self)(n-1);
}
}
console.log(fact(fact)(10));
var fact1 = function(self){
return function(n){
var f = function(h){
return function(x){
if(x == 0) return 1;
else return x * h(x-1);
}
}
return f(self(self))(n);
}
}
console.log(fact1(fact1)(10));
//take out f of fact1
var f = function(self){
return function(x){
if (x == 0) return 1;
else return x * self(x - 1);
}
}
var fact2 = function(self){
return function(n){
return f(self(self))(n);
}
}
console.log(fact2(fact2)(10));
// abstract Y
var Y = function(f){
var g = function(self){
return function(n){
return f(self(self))(n);
}
}
return g(g);
}
console.log(Y(f)(10));