1 / 24

Exception

Exception. 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. This Talk. We show how to calculate an abstract machine for a small language with exceptions;

greerp
Download Presentation

Exception

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Exception • 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.

  2. This 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.

  3. 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

  4. Step 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.

  5. eval x + eval y computation continuation Example: Basic idea: Generalise the semantics to make the use of continuations explicit.

  6. Aim: 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)

  7. = 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 (n+m)) (eval y)) = eval’ x (n  eval’ y (m  c (n+m)) Case: 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 (n+m)) (eval y))

  8. 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))) The evaluation order is now explicit.

  9. Step 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.

  10. Continuations: 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 (n+m))) (n  eval’ y (m  c (n+m))) (m  c (n+m))

  11. Combinators: 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 (n+m)

  12. Datatype: 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)

  13. Aim: define a function eval’’ :: Expr  CONT  Int such that eval’’ e c = eval’ e (apply c) and hence eval e = eval’’ e C1

  14. By 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 (n+m) The semantics is now first-order again.

  15. Step 3 - Refactor Question: • What have we actually produced? Answer: • An abstract machine, but this only becomes clear after we refactor the components.

  16. Abstract 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 (n+m)

  17. = eval (Add (Val 1) (Val 2)) STOP = eval (Val 1) (EVAL (Val 2) STOP) = exec (EVAL (Val 2) STOP) 1 = eval (Val 2) (ADD 1 STOP) = exec (ADD 1 STOP) 2 = exec 3 STOP = 3 Example: run (Add (Val 1) (Val 2))

  18. 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 y) = eval x  eval y

  19. Step 1 - Add Continuations Make evaluation order explicit. Step 2 - Defunctionalize Make first-order once again. Step 3 - Refactor Reveal the abstract machine.

  20. Control 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)

  21. Executing 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 (n+m) 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

  22. Summary • 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.

  23. Further Work • Exploiting monads and folds; • Reasoning about efficiency; • Generalising the language; • Calculating a compiler.

More Related