Title: Functional Programming
1(No Transcript)
2What Is An Exception?
An event within a computation that causes
termination in a non-standard way.
Examples
- Division by zero
- Stack overflow
- Null pointer.
3This Talk
- Most modern languages support programming with
exceptions, e.g. using throw and catch - The compilation of such exception primitives is
traditionally viewed as an advanced topic - We give a simple explanation and verification,
using elementary functional techniques.
4Step 1 - Arithmetic 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
5Virtual machine
type Stack Int data Op PUSH Int
ADD type Code Op
Compiler
comp Expr ? Code comp (Val n)
PUSH n comp (Add x y) comp x comp y
ADD
6Compiler Correctness
Theorem
exec s (comp e) eval e s
7Proof by induction, using a distribution lemma
exec s (xs ys) exec (exec s xs) ys
However, we can avoid this lemma and shorten the
proof by 60 by generalising the theorem
exec s (comp e ops) exec (eval e s) ops
8Step 2 - Adding 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 h)
eval x ? eval h
9Examples
eval
Add (Val 1) (Val 2)
Just 3
eval
Add Throw (Val 2)
Nothing
eval
Catch (Val 1) (Val 2)
Just 1
eval
Catch Throw (Val 2)
Just 2
10Virtual machine
data Op THROW MARK Code UNMARK type
Stack Item data Item VAL Int HAN Code
Compiler
comp (Throw) THROW comp (Catch x h)
MARK (comp h) comp x UNMARK
11How Is THROW Executed?
Informally, we must
- Unwind the stack seeking a handler
- Execute the first handler found, if any
- Skip to the next part of the computation.
12Implementation
unwind Stack ? Code ?
Stack unwind ops unwind (VAL n
s) ops unwind s ops unwind (HAN h s) ops
exec s (h skip ops)
skip Code ? Code skip
skip (UNMARK ops) ops skip
(MARK h ops) skip (skip ops) skip (op
ops) skip ops
13Example
1 (catch (2 throw) 3)
Stack
Code
14Example
1 (catch (2 throw) 3)
Stack
Code
PUSH 1 MARK PUSH 3 PUSH 2 THROW ADD UNMARK ADD
15Example
1 (catch (2 throw) 3)
Stack
Code
MARK PUSH 3 PUSH 2 THROW ADD UNMARK ADD
VAL 1
16Example
1 (catch (2 throw) 3)
Stack
Code
PUSH 2 THROW ADD UNMARK ADD
HAN PUSH 3 VAL 1
17Example
1 (catch (2 throw) 3)
Stack
Code
THROW ADD UNMARK ADD
VAL 2 HAN PUSH 3 VAL 1
18Example
1 (catch (2 throw) 3)
Stack
Code
THROW ADD UNMARK ADD
HAN PUSH 3 VAL 1
19Example
1 (catch (2 throw) 3)
Stack
Code
PUSH 3 THROW ADD UNMARK ADD
VAL 1
20Example
1 (catch (2 throw) 3)
Stack
Code
THROW ADD UNMARK ADD
VAL 3 VAL 1
21Example
1 (catch (2 throw) 3)
Stack
Code
ADD UNMARK ADD
VAL 3 VAL 1
22Example
1 (catch (2 throw) 3)
Stack
Code
UNMARK ADD
VAL 3 VAL 1
23Example
1 (catch (2 throw) 3)
Stack
Code
ADD
VAL 3 VAL 1
24Example
1 (catch (2 throw) 3)
Stack
Code
VAL 4
25Compiler Correctness
eval
Expr
Maybe Int
comp
conv
Code
Stack
exec
where
conv Nothing conv (Just n) VAL n
26As previously, we generalise to an arbitrary
initial stack and arbitrary additional
code. Theorem
exec s (comp e ops) exec s (trans
(eval e) ops)
where
trans Maybe Int ? Op trans Nothing
THROW trans (Just n) PUSH n
27Proof by induction, using a skipping lemma
skip (comp e ops) skip ops
Notes
- The proof is 3.5 pages of simple calculation
- The quickcheck tool was very useful as an aid to
simplifying the definitions and results.
28Step 3 - Adding Jumps
Basic idea
Catch x h
See the paper for further details.
is now compiled to
MARK a code for x UNMARK JUMP b a
code for h b remaining code
29Summary
- Explanation and verification of the compilation
of exceptions using stack unwinding. - Stepwise development to aid understanding
1 - Arithmetic expressions 2 - Adding
exceptions 3 - Adding jumps.
30Further Work
- Mechanical verification
- Modular compilers
- Calculating the compiler
- Generalising the language
- Compiler optimisations.