Title: Functional Programming
1(No Transcript)
2Exception
- An event that causes a computation to terminate
in a non-standard way.
Abstract Machine
- A term-rewriting system for executing programs in
a particular language.
3This Talk
- We show how to calculate an abstract machine for
a small language with exceptions - The key technique is defunctionalization, first
introduced by John Reynolds in 1972 - Somewhat neglected in recent years, but now
re-popularised by Olivier Danvy et al.
4Arithmetic Expressions
Syntax
data Expr Val Int Add Expr Expr
Semantics
eval Expr ? Int eval (Val n)
n eval (Add x y) eval x eval y
5Step 1 - Add Continuations
Make the evaluation order explicit, by rewriting
the semantics in continuation-passing style.
Definition
A continuation is a function that is applied to
the result of another computation.
6Example
Basic idea
Generalise the semantics to make the use of
continuations explicit.
7Aim define a new semantics
eval Expr ? (Int ? Int) ? Int
such that
eval e c c (eval e)
and hence
eval e eval e (?n ? n)
8Case e Add x y
eval (Add x y) c
c (eval (Add x y))
c (eval x eval y)
(?n ? c (n eval y)) (eval x)
eval x (?n ? c (n eval y))
eval x (?n ? (?m ? c (nm)) (eval y))
9New semantics
eval Expr ? Cont ? Int eval (Val
n) c c n eval (Add x y) c eval x (?n ?
eval y (?m ?
c (nm)))
The evaluation order is now explicit.
10Step 2 - Defunctionalize
Make the semantics first-order again, by
rewriting eval using the defunctionalization
technique.
Basic idea
Represent the continuations we actually need
using a datatype.
11Continuations
eval Expr ? Int eval e eval e (?n ? n)
(?n ? n)
eval Expr ? Cont ? Int eval (Val
n) c c n eval (Add x y) c eval x (?n ?
eval y (?m ? c (nm)))
(?m ? c (nm))
(?n ? eval y (?m ? c (nm)))
12Combinators
c1 Cont c1 ?n ? n
c2 Expr ? Cont ? Cont c2 y c ?n ? eval y
(c3 n c)
c3 Int ? Cont ? Cont c3 n c ?m ? c (nm)
13Datatype
data CONT C1 C2 Expr CONT
C3 Int CONT
Semantics
apply CONT ? Cont apply C1
c1 apply (C2 y c) c2 y (apply c) apply (C3 n c)
c3 n (apply c)
14Aim define a function
eval Expr ? CONT ? Int
such that
eval e c eval e (apply c)
and hence
eval e eval e C1
15By calculation, we obtain
eval (Val n) c apply c n eval (Add x y) c
eval x (C2 y c)
apply C1 n n apply (C2 y c) n
eval y (C3 n c) apply (C3 n c) m apply c
(nm)
The semantics is now first-order again.
16Step 3 - Refactor
Question
- What have we actually produced?
Answer
- An abstract machine, but this only becomes clear
after we refactor the components.
17Abstract machine
data Cont STOP EVAL
Expr Cont ADD Int Cont
run e eval e
STOP eval (Val n) c exec c n eval (Add x y)
c eval x (EVAL y c) exec STOP n
n exec (EVAL y c) n eval y (ADD n c) exec (ADD
n c) m exec c (nm)
18Example
run (Add (Val 1) (Val 2))
19Adding Exceptions
Syntax
data Expr Throw Catch Expr Expr
Semantics
eval Expr ? Maybe Int eval (Val n)
Just n eval (Throw) Nothing eval (Add
x y) eval x ? eval y eval (Catch x y) eval
x ? eval y
20Step 1 - Add Continuations
Make evaluation order explicit.
Step 2 - Defunctionalize
Make first-order once again.
Step 3 - Refactor
Reveal the abstract machine.
21Control stack
data Cont STOP EVAL Expr Cont
ADD Int Cont HAND Expr Cont
Evaluating an expression
eval Expr ? Cont ? Maybe Int eval
(Val n) c exec c n eval (Throw) c
unwind c eval (Add x y) c eval x (EVAL y
c) eval (Catch x y) c eval x (HAND y c)
22Executing the control stack
exec Cont ? Int ? Maybe Int exec
STOP n Just n exec (EVAL y c) n eval y
(ADD n c) exec (ADD n c) m exec c (nm) exec
(HAND _ c) n exec c n
Unwinding the control stack
unwind Cont ? Maybe Int unwind STOP
Nothing unwind (EVAL _ c) unwind
c unwind (ADD _ c) unwind c unwind (HAND y c)
eval y c
23Summary
- Purely calculational development of an abstract
machine for a language with exceptions - Key ideas of marking/unmarking and unwinding the
stack arise directly from the calculations - Techniques have been used to systematically
design many other machines - Danvy et al.
24Further Work
- Exploiting monads and folds
- Reasoning about efficiency
- Generalising the language
- Calculating a compiler.