The Y combinator is an interesting construct, allowing recursion
without referring the function being recursed. In other words, call a
function recursively, without naming it. We will go through one
approach of deriving it.

This approach mostly follows WhyOfY by
Richard P Gabriel 1. We will derive it in
JavaScript, in steps. Each step is complete. Click on the ‘Edit in
JSFiddle’ to explore the steps.

Premise & setup

Lets pick a simple example, so we can concentrate on exploring
recursion. Given a number, n, return the sum of numbers from 1 to
n. To start with, below is a recursive solution for the
problem. Individual steps are hosted in JSFiddle, for you to play
around.

The process

We have to remove the reference to sum, inside the function, which
fortunately leads to the Y combinator. One approach to calling a
function, without using its name, is to pass the function as
parameter.

We have just moved the function name (reference) from inside the
function, to the function call. As a next step, we could pass the
function as a curried
param.

This helps later, in abstracting the passing of function as
parameter, out of the logic for the problem.

The double call inside the inner function, is quite irrelevant to the
problem of calculating sum. The logic of sum shouldn’t know that
h(h) gives the next function call. The recursive function should
just receive a function, to continue the recursion with. We could
abstract that in another function. Ex:

Why not pass h(h) as parameter? Why do we have to wrap it in a
function?

Here is the complete version.

In the current version, the function dealing with the sum logic,
doesn’t have any dependency on context, or specific knowledge about
how to get the next function. Lets name it as sum (for the time
being). Ex.

varsum=function(f){returnfunction(n){returnn===1?1:n+f(n-1);};};

This is just so we can see the real changes in code. Here is the
recursion with sum.

To evaluate the recursion, we had to call s4 with itself, ex
s4(s4). To not use a name, we would have to abstract it in a
function. We can define a function which s4 as parameter, and call
it with itself as parameter.

vars5=(function(f){returnf(f);})(s4);console.assert(s5(5)===15);

Expanding the definition of s4 gives.

We are almost done. Now, we just need to pass the actual function (ex
sum in our case) as a parameter. Here is the Y combinator.

Or in its inlined form:

Explorations

If you would like to think more about this, here are a few thoughts to
explore.

We have only explored function with single argument. How could we
make this work with multiple arguments.

Could we come up with a combinator, which doesn’t take curried
version of sum. Ex a combinator which takes sum defined as function
sum(f, n) { return n + f(n-1); } as argument.