The (untyped) lambda calculus

The lambda calculus was invented by Alonzo Church around 1930 as an attempt to formalize a notation for computable functions. It is important to have some basic familiarity with the lambda calculus because it forms the foundation for the definition of functional programming languages such as Haskell.

In the conventional set theoretic formulation of mathematics, a
function can be represented by its graph--that is, a binary
relation between the sets
and
consisting of all pairs . Not all
binary relations represent functions--functions are single-valued, so
if and
then we must have .
In mathematics, functions are almost always total, so we also have an
additional requirement that for each in
,
there exists a pair . Representing a function in terms
of its graph is called an *extensional* definition--two
functions are equal if and only if their graphs are equal. This is
analogous to the definition of equality in set theory--two sets are
equal if and only if they have the same elements.

From a computational viewpoint, it is not sensible to represent functions merely in terms of graphs. Clearly, all sorting algorithms define functions that have the same graph. However, from a computational viewpoint, we would like to distinguish efficient sorting algorithms from inefficient ones.

What we need is an *intensional* representation of functions--a
representation that captures not just the output value for each input,
but also how this value is arrived at.

With this background, we plunge into the (pure untyped) lambda calculus.

- Syntax
- Life without types
- The rule
- Variable capture
- Encoding arithmetic
- One step reduction
- Normal forms
- -equivalence
- Church-Rosser property

- Computability

- Encoding recursive functions in lambda calculus
- Fixed points

- A fixed point combinator
- Making sense of terms without normal forms