Many ways to express ourselves
What's the minimum needed to do so?
Let's first consider: what do we need to express? Computation
Let's first consider: what do we need to express? Computation
FSM is not enough
We need a turing machine
Turing Machine: a machine that can compute a solution to any solvable problem
Our computers are universal turing machines
Turing Completeness: Something that can simulate a turing machine
Goal: find a minimal language that is turing complete
Goal: find a minimal language that is turing complete
Fun examples:
Fun, but what about a language?
\(\lambda\)-calculus: a minimal turing complete language
e -> x
|λx.e
|e e
e -> x
|λx.e
|e e
Convention:
e -> x
|λx.e
|e e
Convention:
(λx.x) y means something
e -> x
|λx.e
|e e
(fun x -> x) y
Beta Reduction
y
(λx.λy.x y) x y
Remember our scoping rules
(fun x -> fun y -> x y) x y
(fun a -> fun b -> a b) x y
Alpha Conversion
\(a,b\) are bound variables
\(x,y\) are free variables
e -> x
|λx.e
|e e
\(\frac{}{x \Rightarrow x}\) (where \(x\) is free)
\(\frac{}{\lambda x.e \Rightarrow \lambda x.e}\)
\(\frac{e1 \Rightarrow (\lambda x.e3)\qquad e2\Rightarrow e4 \qquad {x:e4};e3\Rightarrow e5}{e1\ e2 \Rightarrow e5}\)
\(\frac{e1 \Rightarrow x\qquad e2\Rightarrow e3}{e1\ e2 \Rightarrow x\ e3}\)
This actually is "big-step" semantics:
\(e\) will eventaully evaluate \(e'\)
e -> x
|λx.e
|e e
\(\frac{}{x \Downarrow x}\) (where \(x\) is free)
\(\frac{}{\lambda x.e \Downarrow \lambda x.e}\)
\(\frac{e1 \Downarrow (\lambda x.e3)\qquad e2\Downarrow e4 \qquad {x:e4};e3\Downarrow e5}{e1\ e2 \Downarrow e5}\)
\(\frac{e1 \Downarrow x\qquad e2\Downarrow e3}{e1\ e2 \Downarrow x\ e3}\)
This actually is "big-step" semantics:
\(e\) will eventaully evaluate \(e'\)
\(\frac{}{x \Downarrow x}\) (where \(x\) is free)
\(\frac{}{\lambda x.e \Downarrow \lambda x.e}\)
\(\frac{e1 \Downarrow (\lambda x.e3)\qquad e2\Downarrow e4 \qquad {x:e4};e3\Downarrow e5}{e1\ e2 \Downarrow e5}\)
\(\frac{e1 \Downarrow x\qquad e2\Downarrow e3}{e1\ e2 \Downarrow x\ e3}\)
This actually is "big-step" semantics:
\(e\) will eventaully evaluate \(e'\)
How does it eventually evaluate? Small step semantics
How does it eventually evaluate? Small step semantics
\(\frac{}{x \Rightarrow x}\) (where \(x\) is free)
\(\frac{e1 \Rightarrow e2}{\lambda x.e1 \Rightarrow \lambda x.e2}\)
\(\frac{e1 \Rightarrow e3}{e1\ e2 \Rightarrow e3\ e2}\)
\(\frac{e2 \Rightarrow e3}{e1\ e2 \Rightarrow e1\ e3}\)
\(\frac{}{(\lambda x.e1)\ e2 \Rightarrow \{x:e2\};e1}\)
Issue with order of evaluation
Issue with order of evaluation
Use one of the following to fix:
Eager (Call by value) evaluation
\(\frac{e1 \Downarrow (\lambda x.e3)\qquad e2\Downarrow e4 \qquad {x:e4};e3\Downarrow e5}{e1\ e2 \Downarrow e5}\)
\(\frac{e1 \Rightarrow e3}{e1\ e2 \Rightarrow e3\ e2}\)
\(\frac{e2 \Rightarrow e3}{e1\ e2 \Rightarrow e1\ e3}\)
\(\frac{e2 = (\lambda x.e3)}{(\lambda x.e1)\ e2 \Rightarrow \{x:(\lambda x.e3)\};e1}\)
\(\frac{e2 = y}{(\lambda x.e1)\ e2 \Rightarrow \{x:y\};e1}\)
Eager (Call by value) evaluation
\(\frac{e1 \Rightarrow e3}{e1\ e2 \Rightarrow e3\ e2}\)
\(\frac{e2 \Rightarrow e3}{e1\ e2 \Rightarrow e1\ e3}\)
\(\frac{e2 = (\lambda x.e3)}{(\lambda x.e1)\ e2 \Rightarrow \{x:(\lambda x.e3)\};e1}\)
\(\frac{e2 = y}{(\lambda x.e1)\ e2 \Rightarrow \{x:y\};e1}\)
Issue: Lambda calc is left associative
Eager (Call by value) evaluation
\(\frac{e1 \Rightarrow e3}{e1\ e2 \Rightarrow e3\ e2}\)
\(\frac{e1 = x \text{ or }e1 = (\lambda x.e3)\qquad e2 \Rightarrow e3}{e1\ e2 \Rightarrow e1\ e3}\)
\(\frac{e2 = (\lambda x.e3)}{(\lambda x.e1)\ e2 \Rightarrow \{x:(\lambda x.e3)\};e1}\)
\(\frac{e2 = y}{(\lambda x.e1)\ e2 \Rightarrow \{x:y\};e1}\)
Issue: Lambda calc is left associative
Lazy (Call by name) evaluation
\(\frac{e1 \Downarrow (\lambda x.e3)\qquad e2\Downarrow e4 \qquad {x:e4};e3\Downarrow e5}{e1\ e2 \Downarrow e5}\)
\(\frac{e1 \Downarrow (\lambda x.e3)\qquad {x:e2};e3\Downarrow e4}{e1\ e2 \Downarrow e4}\)
Lazy (Call by name) evaluation
\(\frac{e1 \Downarrow (\lambda x.e3)\qquad {x:e2};e3\Downarrow e4}{e1\ e2 \Downarrow e4}\)
\(\frac{e1 \Rightarrow e3}{e1\ e2 \Rightarrow e3\ e2}\)
\(\frac{}{(\lambda x.e1)\ e2 \Rightarrow \{x:e2\};e1}\)
Partial Evaluation
Useful when compiling
Evaluate what you can that does not change meaning before doing more
λy.(λz.z) y x
λy.y x
We said Lambda Calculus was a turing complete language
Let's encode some values to λ expressions
if true then false else true
if true then false else true
(λx.λy.x) (λx.λy.y) (λx.λy.x)
(λy.(λx.λy.y)) (λx.λy.x)
(λx.λy.y)
if true then false else true
We can also encode pairs, numbers, and more