y-combinator

How to compute the factorial function with the Y combinator

Definitions

Let $\text{Y} = \lambda f . [\lambda x . f(xx)][\lambda x . f(xx)]$

Let $\text{F} = \lambda f . \lambda n . [\text{if } n == 0 \text{ then } 1 \text{ else } n * f (n-1)]$

🚨 Key Point 🚨

$\text{YF} = \text{F} (\text{YF})$

With this Key Point™ you don’t even need to know the definition of $\text{Y}$.

$\text{YF} \ 0$

Why does $\text{YF} \ 0$ even terminate at all? 🤔

\[\begin{align} \text{YF} \ 0 &= \text{F} (\text{YF}) \ 0 \\ &= (\lambda f. \lambda n . [\text{if } n == 0 \text{ then } 1 \text{ else } n * f (n-1)]) (\text{YF}) \ 0 \\ &= (\lambda n . [\text{if } n == 0 \text{ then } 1 \text{ else } n * \text{YF}(n-1)]) \ 0 \\ &= [\text{if } 0 == 0 \text{ then } 1 \text{ else } 0 * \text{YF}(0-1)] \\ &= 1 \end{align}\]

We need laziness! Otherwise $\text{YF} = \text{F} (\text{YF}) = \text{F} (\text{F} (\text{YF})) = \text{F} (\text{F} (\cdots (\text{F} (\text{YF})) \cdots )$ would just recurse forever 😵‍💫

That is, we just expand $\text{YF}$ once then pass $\text{YF}$ to $\text{F}$ (as a thunk) then apply that to $0$ .

$\text{YF} \ 3$ at a glance

\[\begin{align} \text{YF} \ 3 &= \text{F}(\text{YF}) \ 3 \\ &= 3 * \text{YF} \ 2 \\ &= 3 * \text{F}(\text{YF}) \ 2 \\ &= 3 * 2 * \text{YF} \ 1 \\ &= 3 * 2 * \text{F} (\text{YF}) 1 \\ &= 3 * 2 * 1 * \text{YF} \ 0 \\ &= 3 * 2 * 1 * 1 \\ &= 6. \end{align}\]

$\text{YF} \ 3$ thunkified

\[\begin{align} \text{YF} \ 3 &= \text{F}(\text{YF}) \ 3 \\ &= (\lambda n . [\text{if } n == 0 \text{ then } 1 \text{ else } n * \text{YF}(n-1)]) \ 3 \\ &= 3 * \text{YF} \ 2 \\ &= 3 * \text{F}(\text{YF}) \ 2 \\ &= 3 * (\lambda n . [\text{if } n == 0 \text{ then } 1 \text{ else } n * \text{YF}(n-1)]) \ 2 \\ &= 3 * 2 * \text{YF} \ 1 \\ &= 3 * 2 * \text{F} (\text{YF}) 1 \\ &= 3 * 2 * (\lambda n . [\text{if } n == 0 \text{ then } 1 \text{ else } n * \text{YF}(n-1)]) \ 1 \\ &= 3 * 2 * 1 * \text{YF} \ 0 \\ &= 3 * 2 * \text{F} (\text{YF}) \ 0 \\ &= 3 * 2 * 1 * (\lambda n . [\text{if } n == 0 \text{ then } 1 \text{ else } n * \text{YF}(n-1)]) \ 0 \\ &= 3 * 2 * 1 * [\text{if } 0 == 0 \text{ then } 1 \text{ else } 0 * \text{YF}(0-1)]) \\ &= 3 * 2 * 1 * 1 \\ &= 6. \end{align}\]

$\text{YF} \ 3$ full computation

\[\begin{align} \text{YF} \ 3 &= \text{F}(\text{YF}) \ 3 \\ &= (\lambda f. \lambda n . [\text{if } n == 0 \text{ then } 1 \text{ else } n * f (n-1)]) (\text{YF}) \ 3 \\ &= (\lambda n . [\text{if } n == 0 \text{ then } 1 \text{ else } n * \text{YF}(n-1)]) \ 3 \\ &= \text{if } 3 == 0 \text{ then } 1 \text{ else } 3 * \text{YF}(3-1) \\ &= 3 * \text{YF} \ 2 \\ &= 3 * \text{F}(\text{YF}) \ 2 \\ &= 3 * (\lambda f. \lambda n . [\text{if } n == 0 \text{ then } 1 \text{ else } n * f (n-1)]) (\text{YF}) \ 2 \\ &= 3 * (\lambda n . [\text{if } n == 0 \text{ then } 1 \text{ else } n * \text{YF}(n-1)]) \ 2 \\ &= 3 * (\text{if } 2 == 0 \text{ then } 1 \text{ else } 2 * \text{YF}(2-1)) \\ &= 3 * 2 * \text{YF} \ 1 \\ &= 3 * 2 * \text{F} (\text{YF}) 1 \\ &= 3 * 2 * (\lambda f. \lambda n . [\text{if } n == 0 \text{ then } 1 \text{ else } n * f (n-1)]) (\text{YF}) \ 1 \\ &= 3 * 2 * (\lambda n . [\text{if } n == 0 \text{ then } 1 \text{ else } n * \text{YF}(n-1)]) \ 1 \\ &= 3 * 2 * (\text{if } 1 == 0 \text{ then } 1 \text{ else } 1 * \text{YF}(1-1)) \\ &= 3 * 2 * 1 * \text{YF} \ 0 \\ &= 3 * 2 * 1 * (\lambda f. \lambda n . [\text{if } n == 0 \text{ then } 1 \text{ else } n * f (n-1)]) (\text{YF}) \ 0 \\ &= 3 * 2 * 1 * (\lambda n . [\text{if } n == 0 \text{ then } 1 \text{ else } n * \text{YF}(n-1)]) \ 0 \\ &= 3 * 2 * 1 * 1 \\ &= 6. \end{align}\]

Helpful resources