# Y Combinator

``````function fact(n) {
return n < 2 ? 1 : n * fact(n - 1);
}
``````

``````let fact = function(n) {
return n < 2 ? 1 : n * fact(n - 1);
};
``````

`function` 又有 `return`，寫起來或閱讀起來就是麻煩，那麼來用箭號函式：

``````let fact = n => n < 2 ? 1 : n * fact(n - 1);
``````

``````fact => n => n < 2 ? 1 : n * fact(n - 1);
``````

``````function y(f) {
// 假設存在一個 fact
return f(fact);
}
``````

``````function y(f) {
let fact = n => f(fact)(n);
return f(fact);
}
``````

``````function y(f) {
function get_fact() {
// 假設都用匿名函式實現 ...
}
return get_fact();
}
``````

``````function y(f) {
function get_fact() {
let fact = n => f(fact)(n);
return f(fact);
}
return get_fact();
}
``````

``````function y(f) {
function get_fact() {
let fact = n => get_fact()(n);
return f(fact);
}
return get_fact();
}
``````

``````function y(f) {
function get_fact() {
return f(n => get_fact()(n));
}
return get_fact();
}
``````

``````function y(f) {
function get_fact(get_fact) {
return f(n => get_fact(get_fact)(n));
}
return get_fact(get_fact);
}
``````

``````function y(f) {
let get_fact = get_fact => f(n => get_fact(get_fact)(n));
return get_fact(get_fact);
}
``````

``````function y(f) {
return (get_fact => f(n => get_fact(get_fact)(n)))(get_fact => f(n => get_fact(get_fact)(n)));
}
``````

``````function y(f) {
return (x => f(n => x(x)(n)))(x => f(n => x(x)(n)));
}
``````

``````let y = f => (x => f(n => x(x)(n)))(x => f(n => x(x)(n)));
``````

``````y(fact => n => n < 2 ? 1 : n * fact(n - 1))(5) // 120
``````

``````y(fib => n => (n ==0 || n == 1) ? n : fib(n - 1) + fib(n - 2))(10) // 55
``````

Y Combinator 看來很神奇，像是可以運行程式的程式（a program that runs programs），美國有間創投公司命名為 Y Combinator，因為他們覺得自己就類似可運行程式的程式 Y Combinator，只不過他們是間協助新創公司的公司。