Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Meta-Programming through Typeful Code Representation Chiyan Chen and Hongwei Xi Boston University.

Similar presentations


Presentation on theme: "1 Meta-Programming through Typeful Code Representation Chiyan Chen and Hongwei Xi Boston University."— Presentation transcript:

1 1 Meta-Programming through Typeful Code Representation Chiyan Chen and Hongwei Xi Boston University

2 2 Talk Overview Meta-Programming Examples Untyped (Scheme) Typed (MetaML) Some Issues on Typing Meta-Programs Typeful Code Representation Higher-Order Abstract Syntax First-Order Abstract Syntax (via de Bruijn indexes) A Translation to Provide Syntactic Support for Meta-Programming

3 3 A Meta-Program 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 4 A Meta-Program in MetaML (* : the type for code of type  (* run is a built-in function of type:     *) fun power (n: int) (x: ): = if n = 0 then else val square: int  int = run ~(power 2 )> val cube: int  int = run ~(power 3 )>

5 5 Scheme vs. MetaML Scheme is untyped but MetaML is typed The type system of MetaML can be of great use in ruling out ill-staged meta-programs The syntax supporting meta-programming can be “translated away” in Scheme but not in MetaML 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))))

6 6 Higher-Order Abstract Syntax In essence, it uses functions in the meta-language to represent functions in the object-language For instance, we can declare a datatype in ML as follows to represent pure untyped lambda-expressions: datatype exp = Lam of (exp  exp) | App of exp  exp As an example, the -expression x. y.y(x) is represented as follows in ML: Lam(fn x => Lam (fn y => App (y, x)))

7 7 Typeful H.O.A.S. HOAS : a unary type constructor (  ) HOAS : the type for the representation of a closed object- program of type  HOASlam :  .  . (  HOAS   HOAS )  (    ) HOAS HOASapp :  .  . (    ) HOAS  HOAS   HOAS For instance, the simply typed -expression x:int. y:int  int.y(x) is represented as follows: HOASlam(fn x: int HOAS => HOASlam (fn y: (int  int) HOAS => HOASapp (y, x))) which is given the type (int  (int  int)  int) HOAS.

8 8 Weak Head Normalization As an example, we can implement the following function whnf to compute the weak head normal form of a given -expression: fun whnf (t as HOASlam _) = t | whnf (HOASapp (t1, t2)) = (case whnf t1 of HOASlam f => whnf (f t2) | t1 as HOASapp _ => HOASapp (t1, t2)) withtype {‘a}. ‘a HOAS  ‘a HOAS The invariant that weak head normalization is type-preserving is captured here. Notice that HOASlam(whnf) does not represent any -expression (of type (‘a  ‘a) HOAS )

9 9 A Difficulty with H.O.A.S. With h.o.a.s., it often seems inherently difficult to represent object-programs containing free variables On the other hand, it also seems that there is a genuine need for dealing with open code in meta-programming For instance, in the following MetaML program: ~(power 2 )> the expression power 2 is open code.

10 10 Free Variable Evaluation With h.o.a.s., there is a difficult issue involving compiling/evaluating object- programs containing free variables. For instance, this issue occurs when we compile the following object-program, HOASlam(fn x: (int HOAS) HOAS => run x) which can also be written as follows in MetaML syntax: => ~(run )>

11 11 First-Order Abstract Syntax We can declare the following datatype in ML to represent untyped -expressions: datatype exp = One | Shi of exp | Lam of exp | App of exp  exp For instance, the -expression x. y.y(x) is now represented as follows: Lam (Lam (App(One, Shi (One))))

12 12 Typeful F.O.A.S. FOAS : A binary type constructor ( G,  ) FOAS : The type for the representation of an object-program of type  in which free program variables are assigned types by G, which is represented as a sequence of types. FOASone:  .  .   (  FOAS FOASshi:  .  .   (  FOAS   FOAS FOASlam:  .  .   (  FOAS   FOAS FOASapp:  .  .    FOAS   FOAS  FOAS For instance, the simply typed l-expression x:int. y:int  int.y(x) is represented as follows, FOASlam(FOASlam(FOASapp(FOASone, FOASshi(FOASone)))) which can be assigned the type ( ,int  (int  int)  int) FOAS

13 13 The Syntax for code kinds  ::= type | env types  ::=  |  1   2 |  G,  |  type  |  env  type env. G  |  |  G const. fun. cf ::= run const. con. cc ::= Lift | One | Shi | Lam | App | Fix expr. e ::= … values v ::= … expr. var. ctx.  ::=  |  x  type. var. ctx.  ::=  |  type |  env

14 14 Code Constructors in code We assign the following types to the code constructors in code: Lift:  .   ,  One:  .   ,  Shi:  .  .   ,   ,  Lam:  .  .   ,   ,  App:  .  .   ( , , ,  ) ,  Fix:  .   ,  , 

15 15 The function run in code We can now assign the special function run the following type: run :   ,   That is, only closed program is allowed to be run!

16 16 A Staged Program in code As an example, we can implement a staged power function as follows: fun mult (x: int) (y: int): int = x * y fun power (n: int) (x: ): = if n = 0 then Lift (1) else App (App (Lift mult, x), power (n-1) x) We can then implement the square function as follows: val square: int  int = run (Lam (power 2 One))

17 17 Meta-Programming Syntax It is at least inconvenient, if not impractical, to construct meta-programs with abstract syntax trees. This situation is further worsened when de Bruijn indexes are used to represent program variables. To address the issue, we provide meta-programming syntax to facilitate the construction of meta-programs a translation that can “translate away” meta-programming syntax

18 18 Extending code to  Some additional syntax in : expr. e ::= … | `(e) | ^(e) expr. var. ctx.  ::=  |  x @ k  A typing judgment is of the form   ;  |  k e :  where G is a finite mapping from positive integers to type environments such that the domain of G is always equal to the set {1,…,k}. code G +

19 19 Some Typing Rules in  The typing rule for encoding: The typing rule for decoding: code  |  k `(e) : G  |  k+1 e :  G + G  |  k e : G  |  k+1 ^(e) :  G + G

20 20 Translating  into code (1) Some generalized code constructors: Lift n :   1 …   n.  .  1,…,  n ;  Lam n :   1 …   n.  .  .  1,…,  ::  n ;  1,…,  n ;  App n :   1 …   n.  .  .  1,…,  n ;   1,…,  n ;  1,…,  n ;  One n :   1 …   n.  .  1,…,  ::  n ;  Shi n :   1 …   n.  .  .  1,…,  n ;  1,…,  n ;  where we use  1,…,  n ;  for  1,  …  n,  code

21 21 Translating  into code (2) trans 0 (xs; x) = x if x@0 is in xs trans 0 (xs; lam x.e) = lam x. trans 0 (xs,x@0; e) trans 0 (xs; e 1 (e 2 )) = (trans 0 (xs; e 1 ))(trans 0 (xs; e 2 )) trans 0 (xs; `(e)) = trans 1 (xs; e) … trans 1 (xs; x) = Lift (x) if x@0 is in xs trans 1 (xs; x) = var 1 (xs, x) if x@1 is in xs trans 1 (xs; lam x.e) = Lam x. trans 1 (xs,x@1; e) trans 1 (xs; e 1 (e 2 )) = App(trans 1 (xs; e 1 ),trans 1 (xs; e 2 )) trans 1 (xs; `(e)) = trans 2 (xs; e) trans 1 (xs; ^(e)) = trans 0 (xs; e) … code

22 22 Translating  into code (3) The main technical result of the paper: Theorem Assume that  ;  e :  is derivable. Then  ;  |  trans(e) :  is also derivable, where trans(e) = trans 0 (  ; e) code  |  0

23 23 Some Remarks Bound variables at stage k>0 Let e = `(lam x. ^(f `x)) for some function f. Then we have trans(e)=Lam (f One)  f is the identity function lam x. x : trans(e) reduces to Lam (One)  f is the shifting function lam x. Shi (x) : trans(e) reduces to Lam (Shi One)  f is the lifting function lam x. Lift (x) : trans(e) reduces to Lam (Lift One) Cross-Stage Persistence (CSP) operator % % can be defined as ^Lift Lift can be defined as `%

24 24 Some Closely Related Work MetalML (Sheard andTaha) Imperative MetaML (Calcagno et al ) Environment Classifier (Taha and Nielsen) Staged Computation (Davis and Pfenning) Meta-Programming with Names and Necessities (Nanevski and Pfenning) Guarded Recursive Datatypes (Xi et al )

25 25 End of the Talk Thank You! Questions?


Download ppt "1 Meta-Programming through Typeful Code Representation Chiyan Chen and Hongwei Xi Boston University."

Similar presentations


Ads by Google