CUTTING OUT CONTINUATIONS Graham Hutton and Patrick Bahr
CUTTING OUT CONTINUATIONS Graham Hutton and Patrick Bahr
Background In his classic 1972 paper on definitional interpreters, John Reynolds introduced two key techniques: z Continuation-passing style - Makes control flow explicit z Defunctionalisation - Makes programs first-order 1
Background These techniques are often used together: language CPS DEFUN compiler Can the twocontinuations steps be fused together !? Introduce Remove continuations 2
This Talk z A new approach to transforming high-level semantics into low-level implementations; z Only requires simple calculation techniques, and avoids the use of continuations; z Scales to exceptions, state, variable binding, loops, non-determinism, interrupts, etc. 3
Arithmetic Expressions Syntax: data Expr = Val Int | Add Expr Semantics: eval : : Expr Int eval (Val n) = n eval (Add x y) = eval x + eval y 4
Step 1 – Add Continuations Make the flow of control explicit by transforming the semantics into continuation-passing style. Definition: A continuation is a function that is applied to the result of another computation. 5
Specification Aim: define a new semantics eval’ : : Expr Cont Int such that Cont = Int eval’ e c = c (eval e) 6
New semantics: eval’ : : Expr Cont Int eval’ (Val n) c = c n eval’ (Add x y) c = eval’ x ( n eval’ y ( m c (n + m))) Original semantics: Control flow now explicit. eval e = eval’ e ( n n) 7
Step 2 - Defunctionalise Make the semantics first-order again by applying the technique of defunctionalisation. Basic idea: Represent the continuations that we actually need using a datatype. 8
Specification Aim: define a new semantics eval’’ : : Expr CONT Int such that exec : : CONT Cont eval’’ e c = eval’ e (exec c) 9
New semantics: eval’’ : : Expr CONT Int eval’’ (Val n) c = exec c n eval’’ (Add x y) c = eval’’ x (NEXT y c) exec : : CONT Int exec (NEXT y c) n = eval’’ y (ADD n c) exec (ADD n c) m = exec c (n + m) exec HALT n=n An abstract machine for evaluating expressions. 10
Reflection We now have a two step process for calculating an abstract machine from a high-level semantics: 1 – Add a continuation 2 – Remove the continuations Can the steps be combined? 11
The Trick Start directly with the combined specification: eval’’ e c = exec c (eval e) Aim to calculate definitions for eval’’, exec and CONT that satisfy these equations. 12
In Practice z Calculating three interlinked definitions at the same time seems like an impossible task; z But. . . with experience gained from our stepwise approach, it turns out to be straightforward; z New calculation is simpler, more direct, and eliminates the use of continuations. 13
Case: e = Add x y eval’’ (Add x y) c = exec c (eval (Add x y)) = exec c (eval x + eval y) But usingto induction, Nowwe weare appear be stuck, soaswe no have definitions induction hypotheses! further can be applied. 14
To use the hypothesis for y, we need a term of form exec c’ (eval y) for some c’, i. e. we must solve: = exec c’ (eval y) exec c (eval x + eval y) We start by generalising to: exec c’ m = exec c (n + m) But we can’t simply use this as a definition for exec, because c and n are unbound. 15
Solution Package the free variables up in the argument c’ by adding a new constructor to the CONT type, ADD : : Int CONT and a new equation for the exec function: exec (ADD n c) m = exec c (n + m) 16
Now we can continue: exec c (eval x + eval y) = exec (ADD (eval x) c) (eval y) = eval’’ y (ADD (eval x) c) = . . . 17
Summary z The rest of the calculation of the abstract machine proceeds in a similar manner; z The driving force for the calculation is the desire to apply induction hypotheses; z We solve the resulting equations by adding new constructors to CONT on demand. 18
Final Result data CONT where NEXT : : Expr CONT ADD : : Int CONT HALT : : CONT eval’’ (Val n) c = exec c n eval’’ (Add x y) c = eval’’ x (NEXT y c) exec (NEXT y c) n = eval’’ y (ADD n c) exec (ADD n c) m = exec c (n + m) exec HALT n=n 19
Conclusion z Purely calculational approach to cutting out the intermediate use of continuations; z Only requires simple techniques, and scales to a wide variety of language features; z Can also be used to calculate compilers, and everything has been formalised in Coq. 20
CUTTING OUT CONTINUATIONS Graham Hutton and Patrick Bahr
- Slides: 22