The SKI basis

The λ-calculus itself can be built on just three of them — S, K and I. In combinatory logic they are taken as primitives:

S\displaystyle \mathrm{S} =λx y z. x z (y z),\displaystyle {} = \lambda x\,y\,z.\,x\,z\,(y\,z),​K\displaystyle \mathrm{K}​=λx y. x,\displaystyle {} = \lambda x\,y.\,x,​I\displaystyle \mathrm{I}​=λx. x\displaystyle {} = \lambda x.\,x
(1.28)

And I is not even needed as a primitive — it is expressible through S and K:

S K K\displaystyle \mathrm{S}\,\mathrm{K}\,\mathrm{K} =I\displaystyle {} = \mathrm{I}
(1.29)

Let us substitute and prove the formula — expand S K K\mathrm{S}\,\mathrm{K}\,\mathrm{K} on an arbitrary argument zz using the definitions (1.28):

S K K z  \displaystyle \mathrm{S}\,\mathrm{K}\,\mathrm{K}\,z \; →β  K z (K z)  \displaystyle {} \to_\beta\; \mathrm{K}\,z\,(\mathrm{K}\,z) \;​→β  z  \displaystyle {} \to_\beta\; z \;​=  I z.\displaystyle {} =\; \mathrm{I}\,z.

For any zz we get zz — exactly what I\mathrm{I} does, so S K K\mathrm{S}\,\mathrm{K}\,\mathrm{K}​=I{} = \mathrm{I}.

Any λ-term is translated into combinators mechanically. A term is built in three ways — a variable, an application and an abstraction; variables and applications already exist in combinatory logic, but abstraction has to be eliminated. This is done by bracket abstraction — the operation [x] M[x]\,M, “pull the variable xx out of the term MM”. Its result is a combinator term in which xx no longer occurs but which, if given xx back, reduces to MM again. It is defined by the shape of the body MM:

[x] x\displaystyle [x]\,x =I,\displaystyle {} = \mathrm{I},​[x] M\displaystyle [x]\,M​=K M    (x∉FV(M)),\displaystyle {} = \mathrm{K}\,M \;\;(x \notin \mathrm{FV}(M)),​[x] (M N)\displaystyle [x]\,(M\,N)​=S ([x] M) ([x] N)\displaystyle {} = \mathrm{S}\,([x]\,M)\,([x]\,N)
(1.30)
  • [x] x[x]\,x​=I{} = \mathrm{I}: the body is xx itself; returning the argument unchanged is exactly what I\mathrm{I} does.
  • [x] M[x]\,M​=K M{} = \mathrm{K}\,M when xx​∉FV(M){} \notin \mathrm{FV}(M): the body does not depend on xx, so the given argument is simply discarded.
  • [x] (M N)[x]\,(M\,N)​=S ([x] M) ([x] N){} = \mathrm{S}\,([x]\,M)\,([x]\,N): in an application xx may hide in both MM and NN, so the argument must be handed to both — which is exactly what S\mathrm{S} does.

If the body is itself an abstraction λy. M\lambda y.\,M, the inner variable is removed first and the outer one after: [x] (λy. M)[x]\,(\lambda y.\,M)​=[x] ([y] M){} = [x]\,([y]\,M); thus nested λ\lambda are stripped from the inside out until only variables and applications remain.

Take λx. f x x\lambda x.\,f\,x\,x. The body f x xf\,x\,x is an application (f x) x(f\,x)\,x, so we unwind it with the application rule, reducing everything to S\mathrm{S}, K\mathrm{K}, I\mathrm{I}:

[x] (f x x)\displaystyle [x]\,(f\,x\,x) =S ([x] (f x)) ([x] x)\displaystyle {} = \mathrm{S}\,([x]\,(f\,x))\,([x]\,x)​=S (S ([x] f) ([x] x)) I\displaystyle {} = \mathrm{S}\,\bigl(\mathrm{S}\,([x]\,f)\,([x]\,x)\bigr)\,\mathrm{I}​=S (S (K f) I) I\displaystyle {} = \mathrm{S}\,(\mathrm{S}\,(\mathrm{K}\,f)\,\mathrm{I})\,\mathrm{I}

There are no variables in the result — only S\mathrm{S}, K\mathrm{K}, I\mathrm{I} and the free ff: λx. f x x  \lambda x.\,f\,x\,x \;​⇝  S (S (K f) I) I{} \rightsquigarrow\; \mathrm{S}\,(\mathrm{S}\,(\mathrm{K}\,f)\,\mathrm{I})\,\mathrm{I}.