# Expressiveness of the Lambda Calculus

We will show now that the lambda calculus is expressive enough to encode all Recursive functions, whose definition we have seen in previous lecture. This result is due to Kleene.

## The Theorem of Kleene (1936)

All Recursive functions can be defined in the lambda calculus.

### Church's numerals

In order to show the above result, we first need to encode the natutal numbers as lambda terms. The following is a possible representation:
[n] = \x y. xny
where, for generic lambda terms M and N, MnN represents the term M(...(M(M N))...), i.e. the application of M to N repeated n times. These terms [n] are called Church's numerals.

### Lambda-definability

We now make precise the concept of defining a function in the lambda calculus.

A partial function f : Nk -> N is lambda-definable if there exists a lambda term [f] such that, whenever f(n1,...,nk) is defined, we have

[f][n1]...[nk] = [f(n1,...,nk)]
The equality here is the "lambda-convertibility" (see previous lecture), i.e. the equality in the theory of Lambda Calculus. Note that [f] is curried, i.e. it takes its arguments one by one.

## Lambda-definability of the recursive functions

We give here a simpler proof than the original proof by Kleene.

### Encoding of the initial functions

• Zero: [Z] = \x. [0]
• Successor: [S] = \z x y. x(z x y)
• Projection: [Upi] = \x1...xp.xi
It is easy to see that these encodings satisfy the definition of lambda-definability. For instance:
[S][n] = (\z.\x y. x(z x y))[n] = \x y. x([n] x y) = \x y. x(xn y) = [n+1]

### Encoding of composition

[f o (g1,...,gk)] = \x1...xh. [f]([g1]x1...xh) ... ([gk]x1...xh)

### Encoding of primitive recursion

Assume, for the sake of simplicity, that k = 0 (the general case is left for exercise). The equations defining f in this case are:
f(0) = g    (constant)
f(n+1) = h(n,f(n))
In ML we could define this function as:
fun f(n) = if n = 0 then g else h(n-1,f(n-1))
or equivalently (remember that the syntax for \n. M[n] in ML is fn n => M[n]) :
val rec f = fn n => if n = 0 then g else h(n-1,f(n-1))
The meaning of this declaration is that f is a fixpoint of the following functional F:
F = fn f' => fn n => if n = 0 then g else h(n-1,f'(n-1))
Namely, f satisfies the equation
f = F(f)
We will see that in the lambda calculus it is always possible to define such f (for a given F), namely it is always possible to define the fixpoint of a given function F.