10 september 2002 1 implementing staged computation chiyan chen and hongwei xi boston university

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

Post on 21-Dec-2015

223 views

Category:

Documents


0 download

TRANSCRIPT

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

10 September 2002 1

Implementing Staged Computation

Chiyan Chen and

Hongwei XiBoston University

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

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)

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

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))))

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

10 September 2002 4

An Example in MetaML

(* ‘run’ is a built-in function of the type <‘a> ‘a *)

fun power (n: int) (x: <int>): <int> =if n = 0 then <1>else <~x * ~(power (n-1) x)>

val square = run <fn x => ~(power 2 <x>)>val cube = run <fn x => ~(power 3 <x>)>

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

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

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

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))))

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

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.

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

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) TYTYtup: {’a,’b}. ’a TY * ’b TY (’a * ’b) TYTYfun: {’a,’b}. ’a TY * ’b TY (’a ’b) TYTYtyp: {’a}. ’a TY (’a TY) TY

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

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)

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

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

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

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 HOASHOASif: {’a}. bool HOAS * ’a HOAS * ’a HOAS ’a HOASHOAStup: {’a,’b}. ’a HOAS * ’b HOAS (’a * ’b) HOASHOASlam: {’a,’b}. (’a HOAS ’b HOAS) (’a ’b) HOASHOASapp: {‘a,’b}. (‘a ‘b) HOAS * ‘a HOAS ‘b HOASHOASfix: {’a}. (’a HOAS ’a HOAS) ’a HOAS

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

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

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

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 …

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

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

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

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)

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

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

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

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 <int int>

val square1: int int = run (power1 2)

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

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 <int> <int>

val square2: int int = run `(fn x => ^(power2 2 `(x))

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

10 September 2002 19

The Usual Ackermann Function

fun acker m n =if m =0 then n+1else acker (m-1) (if n = 0 then 1 else acker m (n-1))

withtype int int int

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

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 <int int>

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

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

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

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

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

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) FOASFOASone: {‘a,’g}. (‘a,’a*’g) FOASFOASshift: {‘a,’b’,’g}. (‘a,’g) FOAS -> (‘a,’b*’g) FOASFOASlam: {‘a,’b,’g}. (‘b,’a * ‘g) FOAS -> (‘a -> ‘b,’g) FOAS…

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

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))))

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

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

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

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 …

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

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)

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

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))

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

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

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

10 September 2002 30

Related Work

Guarded Recursive Datatype Constructors (Xi et al)

MetalML (Sheard et al) Staged Computation (Pfenning and Davis) … …

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

10 September 2002 31

End of the Talk

Thank you!Questions

?