Presentation is loading. Please wait.

Presentation is loading. Please wait.

10 September 2002 1 Implementing Staged Computation Chiyan Chen and Hongwei Xi Boston University.

Similar presentations


Presentation on theme: "10 September 2002 1 Implementing Staged Computation Chiyan Chen and Hongwei Xi Boston University."— Presentation transcript:

1 10 September 2002 1 Implementing Staged Computation Chiyan Chen and Hongwei Xi Boston University

2 10 September 2002 2 Talk Overview Staged Computation Guarded Recursive Datatype Constructors Code Representation – Higher-order Abstract Syntax – First-order Abstract Syntax (via de Bruijn indices)

3 10 September 2002 3 An Example in Scheme (define (run code) (eval code nil)) (define (power n x) (if (= n 0) 1 `(*,x,(power (- n 1) x)))) ;;; (power 2 ‘x) yields (* x (* x 1)) (define square (run `(lambda (x),(power 2 ‘x)))) ;;; (power 3 ‘y) yields (* y (* y (* y 1))) (define cube (run `(lambda (y),(power 3 ‘y))))

4 10 September 2002 4 An Example in MetaML (* ‘run’ is a built-in function of the type  ‘a *) fun power (n: int) (x: ): = if n = 0 then else val square = run ~(power 2 )> val cube = run ~(power 3 )>

5 10 September 2002 5 Scheme vs. MetaML Most significantly, there is a type system in MetaML but none in Scheme for verifying whether staging is done correctly. However, ‘code’ can be readily represented in Scheme but not in ML

6 10 September 2002 6 Scheme vs. MetaML (continued) For instance, (define (power n x) (if (= n 0) 1 `( ,x,(power (- n 1) x)))) can really be defined as follows: (define (power n x) (if (= n 0) 1 (list ‘  x (power (- n 1) x))))

7 10 September 2002 7 G.R. Datatype Constructors A simple and natural generalization of the notion of datatypes in ML – We use  for a guarded type, where  may contain some constraints on type variables in  – A g.r. datatype constructor is used to construct g.r. datatypes, that is, sums of guarded types.

8 10 September 2002 8 A Representation for Types The g.r. datatype constructor TY is for representing simple types: typecon (type) TY = (int) TYint | {’a,’b}. (’a * ’b) TYtup of ’a TY * ’b TY | {’a,’b}. (’a  ’b) TYfun of ’a TY * ’b TY | {’a}. (’a TY) TYtyp of ’a TY TYint: (int) TY TYtup: {’a,’b}. ’a TY * ’b TY  (’a * ’b) TY TYfun: {’a,’b}. ’a TY * ’b TY  (’a  ’b) TY TYtyp: {’a}. ’a TY  (’a TY) TY

9 10 September 2002 9 The Representation of Some Types The type ‘int’ is represented as TYint The type ‘int * int’ is represented as TYtup(TYint, TYint) The type ‘int  int * int’ is represented as TYfun(TYint, TYtup (TYint, TYint)) The type ‘(int) TY’ is represented as TYtyp(TYint)

10 10 September 2002 10 A Program Example: val2string fun val2string pf x = case pf of TYint => int2string x | TYtup (pf1, pf2) => “(” ^ val2string pf1 (fst x) ^ “,” ^ val2string pf2 (snd x) ^ “)” | TYfun _ => “[a function]” | TYtyp _ => “[a type]” withtype {’a}. ’a TY -> ’a -> string

11 10 September 2002 11 H.O.A.S. Trees typecon (type) HOAS = {’a}. (’a) HOASlift of ’a | {’a}. (’a) HOASif of bool HOAS * ’a HOAS * ’a HOAS | {’a,’b}. (’a * ’b) HOAStup of ’a HOAS * ’b HOAS | {’a,’b}. (’a  ’b) HOASlam of ’a HOAS  ’b HOAS | {‘a,’b}. (‘b) HOASapp of (‘a  ’b) HOAS * ‘a HOAS | {’a}. (’a) HOASfix of ’a HOAS  ’a HOAS HOASlift: {’a}. ’a  ’a HOAS HOASif: {’a}. bool HOAS * ’a HOAS * ’a HOAS  ’a HOAS HOAStup: {’a,’b}. ’a HOAS * ’b HOAS  (’a * ’b) HOAS HOASlam: {’a,’b}. (’a HOAS  ’b HOAS)  (’a  ’b) HOAS HOASapp: {‘a,’b}. (‘a  ‘b) HOAS * ‘a HOAS  ‘b HOAS HOASfix: {’a}. (’a HOAS  ’a HOAS)  ’a HOAS

12 10 September 2002 12 A Type-Preserving Evaluator fun eval (HOASlift v) = v | eval (HOASif (b, e1, e2)) = if eval (b) then eval (e1) else eval (e2) | eval (HOAStup (e1, e2)) = (eval (e1), eval (e2)) | eval (HOASlam (f)) = fn x => eval (f (HOASlift x)) | eval (HOASapp (e1,e2)) = (eval e1) (eval e2) | eval (HOASfix f) = eval (f (HOASfix f)) withtype {’a}. ’a HOAS  ’a

13 10 September 2002 13 Compiling H.O.A.S. Trees We need a compilation function that can compile h.o.a.s trees: run: {’a}. ’a HOAS  ’a (think about normalization by evaluation) For instance, this can be done in such a manner …

14 10 September 2002 14 A Staged Program fun power1 n = HOASlam ( fn x: int HOAS => if n = 0 then HOASlift 1 else HOASapp ( HOASlift op , HOAStup (x, HOASapp (power1 n-1, x)))) withtype int  (int  int) HOAS val square1 = run (power1 2) The function square1 is like being defined as: fun square1 x = x  f1 (x) and f1(x) = x  f0(x) and f0(x) = 1

15 10 September 2002 15 Another Staged Program fun power2 n x = if n = 0 then HOASlift 1 else HOASapp (HOASlift op , HOAStup (x, power2 (n-1) x) withtype int  int HOAS  int HOAS val square2 = run (HOASlam (power2 2)) The function square2 is like being defined as fun square2 x = x  (x  1)

16 10 September 2002 16 Syntactic Sugar = (  ) HOAS `(x) = HOASlift (x) `(c) = HOASlift (c) `(e1, e2) = HOAStup (`(e1), `(e2)) `(e1(e2)) = HOASapp(`(e1), `(e2)) `(fn x => e) = HOASlam (fn x => `(e[x -> ^x])) `(fix f => e) = HOASfix (fn f => `(e[f -> ^f])) `(e:  ) = (`(e): (  ) HOAS) `(^(e)) = e

17 10 September 2002 17 An Example in Sugared Syntax fun power1 n = `(fn x => ^(if n = 0 then lift (1) else `(x  ^(power1 (n-1)) x))) withtype int  val square1: int  int = run (power1 2)

18 10 September 2002 18 Another Example in Sugared Syntax fun power2 n x = if n = 0 then lift (1) else `(^x  ^(power2 (n-1) x)) withtype int   val square2: int  int = run `(fn x => ^(power2 2 `(x))

19 10 September 2002 19 The Usual Ackermann Function fun acker m n = if m =0 then n+1 else acker (m-1) (if n = 0 then 1 else acker m (n-1)) withtype int  int  int

20 10 September 2002 20 A Staged Ackermann Function The Ackermann function can be staged as follows: fun acker m = `(fix f => fn n => ^(if m = 0 then `(n+1) else `(^(acker (m-1)) (if n = 0 then 1 else f (n-1))))) withtype int 

21 10 September 2002 21 A Staged Ackermann Function (contd.) For instance, we can define a function acker2 as follows: fun acker2 = run (acker 2) This definition is similar to the following one: fun acker2 n = acker1 (if n = 0 then 1 else acker2 (n-1)) and acker1 n = acker0 (if n = 0 then 1 else acker1 (n-1)) and acker0 n = n+1

22 10 September 2002 22 A Problem with H.O.A.S. Trees The expression e = `(fn x => ^(run `(x))), whose translation is HOASlam (fn x => run x), can be assigned the type: {‘a}. (‘a HOAS  ‘a) HOAS However, ‘run e’ causes a run-time error

23 10 September 2002 23 F.O.A.S. Trees typecon (type,type) FOAS = | {’a,’g}. (’a,’g) FOASlift of ’a | {’a,’g}. (‘a,’a*’g) FOASone | {’a,’b,’g}. (‘a,’b*’g) FOASshift of (‘a,’g) FOAS | {‘a,’b,’g}. (‘a -> ‘b,’g) FOASlam of (‘b,’a*’g) FOAS | … FOASlift: {’a,’g}. ’a -> (’a,’g) FOAS FOASone: {‘a,’g}. (‘a,’a*’g) FOAS FOASshift: {‘a,’b’,’g}. (‘a,’g) FOAS -> (‘a,’b*’g) FOAS FOASlam: {‘a,’b,’g}. (‘b,’a * ‘g) FOAS -> (‘a -> ‘b,’g) FOAS …

24 10 September 2002 24 Some Examples of F.O.A.S. Trees The F.O.A.S. tree for ‘fn x => x’: FOASlam (FOASone) The F.O.A.S. tree for ‘fn x => fn y => x+y’: FOASlam(FOASlam( FOASapp (FOASlift +, FOAStup (FOASshift (FOASone), FOASone))))

25 10 September 2002 25 Some Examples of F.O.A.S. Trees FOASone can be assigned the type: (int, int * unit) FOAS FOASapp (FOASone, FOASshift(FOASone)) can be assigned the type: (int, (int  int) * (int * unit)) FOAS FOASapp (FOASshift(FOASone), FOASone) can be assigned the type: (int, int * ((int  int) * unit)) FOAS

26 10 September 2002 26 Compiling F.O.A.S trees We need a function to compile closed F.O.A.S. trees: run: {‘a}. (‘a, unit) FOAS  ‘a This can be readily implemented …

27 10 September 2002 27 A Simple Example fun power1 n = if n = 0 then FOASlam (FOASlift 1) else FOASlam ( FOASapp ( FOASlift *, FOAStup (FOASone, FOASapp (power1 (n-1), FOASone)))) withtype {‘g}. int  (int  int, ‘g) FOAS val square = run (power1 2)

28 10 September 2002 28 Another Simple Example fun power2 n x = if n = 0 then FOASlift (1) else FOASapp (FOASlift *, FOAStup (x, power2 (n-1) x)) withtype {‘g}. int  (int, ‘g) FOAS  (int, ‘g) FOAS val square = run (FOASlam (power2 2 FOASone))

29 10 September 2002 29 Conclusion We have presented two approaches (h.o.a.s. and f.o.a.s.) to representing ‘code’ through the use of g.r. datatype constructors With such concrete represention of code, we can implement staged computation by simply translating away staging notations in staged programs

30 10 September 2002 30 Related Work Guarded Recursive Datatype Constructors (Xi et al) MetalML (Sheard et al) Staged Computation (Pfenning and Davis) … …

31 10 September 2002 31 End of the Talk Thank you! Questions?


Download ppt "10 September 2002 1 Implementing Staged Computation Chiyan Chen and Hongwei Xi Boston University."

Similar presentations


Ads by Google