# The Lambda Calculus¶

## A Quote to Start the Day¶

You realize that

everythingcan be done with function composition?… It’s calledlambda calculus.—Joseph McKinsey

## The Lambda Calculus¶

The \(λ\)-calculus is a mathematical language of **lambda terms** bound by a set of
transformation rules. The \(λ\)-calculus notation was introduced in the 1930s by Alonzo
Church.

Just like programming languages, the \(λ\)-calculus has rules for what is a valid syntax:

Variables: | A variable (such as \(x\)) is valid term in the \(λ\)-calculus. |
---|---|

Abstractions: | If \(t\) is a term and \(x\) is a variable, then the term \(λx.t\) is a lambda abstraction. |

Applications: | If \(t\) and \(s\) are terms, then \(ts\) is the application term of \(t\) onto \(s\). |

## Anonymous Functions¶

**Lambda abstractions** can be thought of as anonymous functions in the \(λ\)-calculus.

A lambda abstraction which takes an \(x\) and returns a \(t\) is written as so:

Example

Suppose in mathematics we define a function \(f(x) = x + 2\). This could be written as \((λ x.x + 2)\) in the \(λ\)-calculus [1]. Of course, this function is anonymous and not bound to the name \(f\).

[1] | Of course, we haven’t said that either \(+\) nor \(2\) is valid in lambda calculus yet. We will get to that… |

## Functions are First Class¶

In the \(λ\)-calculus, abstractions are not only first class functions, they are our only way of to encode data.

Abstractions are used to encode everything:

- Numbers
- Booleans (true/false)
- Conses
- …

## Currying¶

Since abstractions in the \(λ\)-calculus may only take one argument, currying is typically used to denote functions of multiple arguments. For example, the function \(f(x, y) = x\) might be written as:

Further, function application is left-associative, so \(fxy\) means \((fx)y\).

## Free and Bound Variables¶

The \(λ\) operator (which creates lambda abstractions) binds a variable to wherever it occurs in the expression.

- Variables which are bound in an expression are called
**bound variables** - Variables which are not bound in an expression are called
**free variables**

Example

With your learning group, identify the free and bound variables in this expression:

## Transformations¶

\(\alpha\)-conversion: | |
---|---|

Allows variables to be renamed to non-colliding names. For example, \(λx.x\) is \(\alpha\)-equivalent to \(λy.y\). | |

\(\beta\)-reduction: | |

Allows functions to be applied. For example, \((λx.λy.x)(λx.x)\) is \(\beta\)-equivalent to \(λy.(λx.x)\). | |

\(\eta\)-conversion: | |

Allows functions with the same external properties to be substituted. For example, \((λx.(fx))\) is \(\eta\)-equivalent to \(f\) if \(x\) is not a free variable in \(f\). |

## Examples: Alpha Equivalence¶

With your learning group, identify if each of the following are a valid \(\alpha\)-conversion. Turn in your answers on a sheet of paper with all of your names at the end of class for learning group participation credit for today.

- \(λx.λx.x \to λy.λy.y\)
- \(λx.λx.x \to λy.λx.x\)
- \(λx.λx.x \to λy.λx.y\)
- \(λx.λy.x \to λy.λy.y\)

## Examples: Beta Reductions¶

Fully \(\beta\)-reduce each of the following expressions:

- \((λx.λy.λf.fxy)(λx.λy.y)(λx.λy.x)(λx.λy.y)\)
- \((λa.λb.a(λb.λf.λx.f(bfx))b)(λf.λx.fx)(λf.λx.f(fx))\)

## Church Numerals¶

Since all data in the \(λ\)-calculus must be a function, we use a clever convention of
functions (called **Church numerals**) to define numbers:

0: | \(λf.λx.x\) |
---|---|

1: | \(λf.λx.fx\) |

2: | \(λf.λx.f(fx)\) |

3: | \(λf.λx.f(f(fx))\) |

… and so on. In fact, the successor to any number \(n\) can be written as:

Notice this

Defining numbers as functions in this way allows us to apply a Chuch numeral \(n\) to a function to get a new function that applies the original function \(n\) times.

## Shorthand Notations¶

While it’s not a defined part of the \(λ\)-calculus, we define common shorthands for some features:

- \(0, 1, 2, \ldots\) are shorthand for their corresponding Church numerals
- \(\{\text{SUCC}\} = λn.λf.λx.f(nfx)\)

Note

The notation “\(=\)” above is not a part of the \(λ\)-calculus. I’m using it for saying “is shorthand for”.

## Addition and Multiplication¶

Adding \(m\) to \(n\) can be thought of as taking the successor to \(n\), \(m\) times. Using our shorthand \(\text{SUCC}\), this can be written as:

Similarly, multiplying \(m\) by \(n\) can be thought of as repeating \(\text{ADD}\, n\), \(m\) times and then applying it to \(0\), this can be written as:

## Boolean Logic¶

We use the following convention for true and false:

From here, we can define some common boolean operators:

## Cons Cells¶

By convention, we will represent a cons cell as a function that applies its argument to the CAR and CDR of the cons cell. This leads to the shorthand:

Using this, we can define lists:

## What else is there in Lambda Calculus?¶

- Getting the predecessor (
`{PRD}`

) for a Church Numeral is hard, but doable (extra credit). To subtract \(m\) from \(n\), apply the`{PRD}`

function \(m\) times to \(n\). - For recursion, we need to reference ourselves in a lambda abstraction. This is done using a Y-combinator.
- The graduate level Theory of Computation (CSCI 561) class talks much more extensively about the \(λ\)-calculus.
- There are many extensions to the \(λ\)-calculus such as those encoded by the \(λ\)-cube.

## Why is any of this Useful?¶

- \(λ\)-calculus can emulate a Turing machine. That means that anything you can
do with a classical computer, you can do with the \(λ\)-calculus.
**This fact underpins all of functional programming.** - Many functional programming languages (e.g., Haskell, Scheme, SlytherLisp) are just practical implementations of the \(λ\)-calculus.
- The \(λ\)-calculus gives us another perspective on
*type theory*(using the generalization of the \(λ\)-calculus called typed \(λ\)-calculus). - It is another way for us to quantify what is computable.