Introduction to the Lambda Calculus

Alonzo Church

1932, “A set of postulates for the foundation of logic”, a formal system

with the aim of providing a foundation for logic which would be more

natural than Russell’s type theory or Zermelo’s set theory, and would

not contain free variables

1936 Church isolated and published just the portion relevant to

computation, what is now called the untyped lambda calculus

1940, he also introduced a computationally weaker, but logically

consistent system, known as the simply typed lambda calculus

Re-discovered as a versatile tool in Computer Science by people like

McCarthy, et al. in the 1960s

Operational Semantics — Syntax

t ::=

x /* variable */

λx.t /* abstraction */

t t /* application */

v ::=

λx.t /* abstraction value */

Let’s start with the booleans

true = λt. λf. t

false = λt. λf. f

not = λa. a false true

Applying not

(λa. a false true) true

(λa. a false true) (λt. λf. t)

(λt. λf. t) false true

false

(λx.t) v [x ↦ v]t

(from operational semantic rules)

β-reduction

applying functions to their arguments

Normal order reduction – most well-known languages work

from the leftmost, outermost, redex and work in, halting when

the outermost argument can no longer be applied

Redex – reducible expression

Full β-reduction – reduce available redexes in any desired order

Numbers

c0 = λs. λz. z

c1 = λs. λz. s z

c2 = λs. λz. s (s z)

c3 = λs. λz. s (s (s z))

…

Just like Peano arithmetic

Operations on numbers

iszro = λm. m (λx. fls) tru

plus = λm. λn. λs. λz. m s (n s z)

mult = λm. λn. m (plus n) c0

exp = λm. λn. n (mult m) c1

scc = λn. λs. λz. s (n s z) /* number successor */

/* number predecessor */

prd = λm. fst (m (λp. pair (snd p) (plus c1 (snd p))) (pair c0 c0))

eql = λm. λn. and (iszro (m prd n)) (iszro (n prd m))

Automating assertions

/* it is true that … */

xnor tru (eql c1 (exp c1 c1))

xnor tru (eql c6 (plus c2 c4))

xnor tru (eql c1 (fst (pair c1 tru)))

Recursion

fix (a.k.a the Y-combinator)

= λf. (λx. f (λy. x x y)) (λx. f (λy. x x y))

takes recursive abstraction

λf. λx. __f__

Haskell Curry

Recursion

(λf. (λx. f (λy. x x y)) (λx. f (λy. x x y))) (λf. λx. __) (bar)

(λx. (λf. λx’. __) (λy. x x y)) (λx. (λf. λx’. __) (λy. x x y)) (bar)

(foo)

(λf. λx’. __) (λy. foo foo y) (bar)

λx’. __ (bar)

Recursion

fact = λf. λx. cond (iszro x) c1 (mult x (f (prd x)))

(λf. (λx. f (λy. x x y)) (λx. f (λy. x x y))) fact c3

/* successive interations */

(λy. (λx. f (λy’.x x y’)) (λx. f (λy’.x x y’)) y) (/* prev recurs*/)