- Syntax
- Variables
- Substitution
- α-conversion
- β-reduction
- Fixpoint combinators
The untyped λ-Calculus is the smallest universal programming language first developed by Alonzo Church in 1932.
It has the same expressive power as Turing machines. It lends itself more the the study of properties of computation than Turing machines do.
The λ-Calculus contains terms (syntax) and rules to compute terms
The λ-Calculus has only 3 constructs:
- Variables
- Functions
- (Function) Applications
let V be a set of variables
let x,y,z,… range over V
The following Backus-Naur form inductively defines the syntax:
M::=x∣λx.M∣MM
**terms can be surrounded with parenthesis in ambiguous cases
A λ-term λx.M is an anonymous function, also known as a λ abstraction. It has 1 parameter x with a body M
Applications of the form MN are used to pass arguments to functions
we sometimes write λx1,…,xn.M instead of λx1…λxn.M
Officially a function with 1 parameter would take the form λx.M and a function with 2 parameters would take the form λx.λy.M
We use brackets to remove ambiguity but in general, our precedence rule is that application has higher precedence over λ
We also use an associativity rule, application is left associative, i.e: xyz stands for (xy)z
Exercise:
Write parentheses appropriately around all lambda as applications:
- λx.λy.xy
(λx.(λy.(xy)))
- λx.xλx.xx
(λx.(x(λx.(xx))))
- λx.xxλx.x
(λx.((xx)(λx.x)))
T = λx.λy.x
F = λx.λy.y
and=λa.λb.abF
or=λa.λb.aTB
notλx.aFT
0=λf.λx.x
1=λf.λx.fx
2=λf.λx.f(fx)
⋯
succ=λa.λf.λx.f(afx)
add=λa.λbλf.λx.afx(bfx)
essentially with x being a base case (0) each application of f represents another successor
We can use these rules to derive trees where:
- leaves are variables
- nodes are either
- application nodes (labelled with @)
- lambda nodes (labelled λ)
We refer to these trees as abstract syntax trees
λx.x
graph TD;
\ --> x.
\ --> x
λx.λy.xy
graph TD;
\ --> x
\ --> \,
\, --> y
\, --> *
* --> x,
* --> y,
x(λy.z)
graph TD;
* --> x
* --> \
\ --> y
\ --> z
Exercise
What are the abstract syntax trees corresponding to:
λf.λx.x
graph TD;
\ --> f
\ --> \.
\. --> x
\. --> x.
λf.λx.λx
graph TD;
\ --> f
\ --> \.
\. --> x
\. --> *
* --> f.
* --> x.
λf.λx.f(fx)
graph TD
\ --> f
\ --> \.
\. --> x
\. --> *
* --> f.
*--> *.
*. --> f,
*. --> x.
Free and Bound Variables
Given a λ- term, λx.M
- x is the parameter of the function
- the scope of x is the body M
- the λ-abstraction binds the "free" occurrences of x in M
A variable x is either
- bound if it is i the scope of a λ abstraction with a parameter x e.g λx.x
- free, otherwise e.g. λy.yx
x can occur both free and bound in some cases: x(λx.x)
We say that the occurrence of a bound variable x is bound to a λ in a term M, fi the corresponding λ-abstraction is the smallest λ-abstraction in M with parameter x containing that bound occurrence
For example:
(λx.x)(λx.x)
- x's 2nd occurrence is bound to the 1st λ
- x's 4th occurrence is bound to the 2nd λ
The set of free variables occurring in a term is recursively computed as:
FV(x)={x}FV(λx.M)=FV(M) {x}FV(MN)=FV(M)∪FV(N)
We can then say a variable x occurs free in M iff x∈FV(M)
A term M is closed if FV(M)=∅
Bound variable names are not important and can be renamed without changing the meaning of a term
Two terms M and N are α-equivalent - denoted M≡αN if they only differ by their bound variables, i.e
- M and N have the same tree structure up to the leaves
- M and N have the same occurrences of free variables
- one superscript assignment can be used to label both M and N
TODO Finish