78
Language Extensions and Abstractions OCaml

FYP Final Presentation

Embed Size (px)

Citation preview

Page 1: FYP Final Presentation

Language Extensions and Abstractions�

OCaml �

Page 2: FYP Final Presentation

PROJECT OBJECTIVES�

Page 3: FYP Final Presentation

DEBUGGING�EXTENSION�

Page 4: FYP Final Presentation

LAZY EVALUATION�EXTENSION�

Page 5: FYP Final Presentation

WHAT IS CAMLP4?�

Page 6: FYP Final Presentation

WHAT IS CAMLP4?�Caml Preprocessor and Pretty

Printer�

Page 7: FYP Final Presentation

let  rec  fib  =      |  0  -­‐>  0      |  1  -­‐>  1      |  n  when  n  >  1  -­‐>          fib  (n  -­‐  1)  +  fib  (n  -­‐  2)    

Page 8: FYP Final Presentation

let  rec  fib  =  memo      |  0  -­‐>  0      |  1  -­‐>  1      |  n  when  n  >  1  -­‐>          fib  (n  -­‐  1)  +  fib  (n  -­‐  2)    

Page 9: FYP Final Presentation

let  rec  fib  =      let  tbl  =  Hashtbl.create  100  in      fun  x  -­‐>          try  Hashtbl.find  tbl  x          with  Not_found  -­‐>              let  result  =                  match  x  with                  |  0  -­‐>  0                  |  1  -­‐>  1                  |  n  when  n  >  1  -­‐>                      fib  (n  -­‐  1)  +  fib  (n  -­‐  2)  in              do  {  Hashtbl.replace  tbl  x  result;                        ;result  }  

Page 10: FYP Final Presentation

let  rec  fib  =      let  tbl  =  Hashtbl.create  100  in      fun  x  -­‐>          try  Hashtbl.find  tbl  x          with  Not_found  -­‐>              let  result  =                  match  x  with                  |  0  -­‐>  0                  |  1  -­‐>  1                  |  n  when  n  >  1  -­‐>                      fib  (n  -­‐  1)  +  fib  (n  -­‐  2)  in              do  {  Hashtbl.replace  tbl  x  result;                        ;result  }  

Page 11: FYP Final Presentation

THINK MACROS�

Page 12: FYP Final Presentation

C MACROS?�

Page 13: FYP Final Presentation

LISP MACROS�For a statically typed language�

Page 14: FYP Final Presentation

let  simple_optimize  =      object          inherit  Ast.map  as  super          method  expr  e  =              match  super#expr  e  with              |  <:expr<  1  *  $e$  >>  -­‐>                    <:expr<  $e$  >>              |  <:expr<  0  +  $e$  >>  -­‐>                    <:expr<  $e$  >>                                                                                                                                                                                              |  e  -­‐>  e                                                                                                                                                                                                      end  

Page 15: FYP Final Presentation

let  simple_optimize  =      object          inherit  Ast.map  as  super          method  expr  e  =              match  super#expr  e  with              |  <:expr<  1  *  $e$  >>  -­‐>                    <:expr<  $e$  >>              |  <:expr<  0  +  $e$  >>  -­‐>                    <:expr<  $e$  >>                                                                                                                                                                                              |  e  -­‐>  e                                                                                                                                                                                                      end  

Page 16: FYP Final Presentation

let  simple_optimize  =      object          inherit  Ast.map  as  super          method  expr  e  =              match  super#expr  e  with              |  <:expr<  1  *  $e$  >>  -­‐>                    <:expr<  $e$  >>              |  <:expr<  0  +  $e$  >>  -­‐>                    <:expr<  $e$  >>                                                                                                                                                                                              |  e  -­‐>  e                                                                                                                                                                                                      end  

1  *  humblepi  BECOMES  humblepi  0  +  humblepi  BECOMES  humblepi  

Page 17: FYP Final Presentation

DEBUGGING EXTENSION�Easier function tracing and debugging

using annotations�

Page 18: FYP Final Presentation

PROBLEM�Functions are hard�

to debug�

Page 19: FYP Final Presentation

type  env  =  (string  *  expr)  list  and  expr  =      |  Var  of  string      |  IntConst  of  int      |  Plus  of  expr  *  expr      |  Minus  of  expr  *  expr      |  Lambda  of  string  *  expr      |  Apply  of  expr  *  expr      |  Closure  of  env  *  string  *  expr  

Page 20: FYP Final Presentation

let  rec  eval  env  e  =      let  rec  aux  env  e  =          match  e  with          |  IntConst  _  -­‐>  e          |  Plus  (e1,  e2)  -­‐>            ...  in      aux  env  e  

Page 21: FYP Final Presentation

NO GENERIC PRINTERS�

Page 22: FYP Final Presentation

let rec string_of_expr e =! match e with! ... (* for every variant *)!and string_of_env env =! (* Map string_of_expr over elements *)!

Page 23: FYP Final Presentation

let  rec  eval  env  e  =      let  rec  aux  env  e  =          match  e  with          |  IntConst  _  -­‐>  e          |  Plus  (e1,  e2)  -­‐>            …  in      let  _  =  printf  "Input:  env  =  %s,  e  =  %s"  (string_of_env  env)  (string_of_expr  e)  in      let  out  =  aux  env  e  in      let  _  =  printf  "Output:  %s"  (string_of_expr  e)  in  out      

Page 24: FYP Final Presentation

let  rec  eval  env  e  =      let  rec  aux  env  e  =          match  e  with          |  IntConst  _  -­‐>  e          |  Plus  (e1,  e2)  -­‐>            …  in      let  _  =  printf  "Input:  env  =  %s,  e  =  %s"  (string_of_env  env)  (string_of_expr  e)  in      let  out  =  aux  env  e  in      let  _  =  printf  "Output:  %s"  (string_of_expr  e)  in  out      

Page 25: FYP Final Presentation

let  rec  eval  env  e  =      let  rec  aux  env  e  =          match  e  with          |  IntConst  _  -­‐>  e          |  Plus  (e1,  e2)  -­‐>            …  in      let  _  =  printf  "Input:  env  =  %s,  e  =  %s"  (string_of_env  env)  (string_of_expr  e)  in      let  out  =  aux  env  e  in      let  _  =  printf  "Output:  %s"  (string_of_expr  e)  in  out      

Tedious and Cumbersome�

Page 26: FYP Final Presentation

SOLUTION�Generate debugging code from function�

annotated with debug keyword�

Page 27: FYP Final Presentation

let  rec  eval  env  e  =      let  rec  aux  env  e  =          match  e  with          |  IntConst  _  -­‐>  e          |  Plus  (e1,  e2)  -­‐>            ...  in      aux  env  e  

Page 28: FYP Final Presentation

let  debug  rec  eval  env  e  =      let  rec  aux  env  e  =          match  e  with          |  IntConst  _  -­‐>  e          |  Plus  (e1,  e2)  -­‐>            ...  in      aux  env  e  

Page 29: FYP Final Presentation

DEMO�

Page 30: FYP Final Presentation

HOW DOES IT WORK?�

Page 31: FYP Final Presentation

Annotated�Expression�

Page 32: FYP Final Presentation

Camlp4 Lexer & Parser �

Annotated�Expression�

Page 33: FYP Final Presentation

Camlp4 Lexer & Parser �

Type Inference �

Annotated�Expression�

Page 34: FYP Final Presentation

Camlp4 Lexer & Parser �

Type Inference �

Deriving Library�

Annotated�Expression�

Page 35: FYP Final Presentation

Camlp4 Lexer & Parser �

Type Inference �

Deriving Library�

AST Transformer �

Annotated�Expression�

Page 36: FYP Final Presentation

Camlp4 Lexer & Parser �

Type Inference �

Deriving Library�

AST Transformer �

Annotated�Expression�

Generated�OCaml Code �

Page 37: FYP Final Presentation

Camlp4 Lexer & Parser �

Type Inference �

Deriving Library�

AST Transformer �

Annotated�Expression�

Generated�OCaml Code �

Page 38: FYP Final Presentation

Camlp4 Lexer & Parser �

Type Inference �

Deriving Library�

AST Transformer �

Annotated�Expression�

Generated�OCaml Code �

Page 39: FYP Final Presentation

TYPE INFERENCE�

Page 40: FYP Final Presentation

let sqr x = x * x!

TYPE INFERENCE STEP�RETURNS�[“int”; “int”]!

Page 41: FYP Final Presentation

let fact count x = match x with | 1 -> x | n -> fact (count – 1) (n * x)!

Page 42: FYP Final Presentation

let fact count x = match x with | 1 -> x | n -> fact (count – 1) (n * x)!

TYPE INFERENCE STEP�RETURNS�[“int”; “int”; “int”]!

Page 43: FYP Final Presentation

Camlp4 Lexer & Parser �

Type Inference �

Deriving Library�

AST Transformer �

Annotated�Expression�

Generated�OCaml Code �

Page 44: FYP Final Presentation

DERIVING LIBRARY�Third party open source library that

generates printing functions from types�

Page 45: FYP Final Presentation

type  env  =  (string  *  expr)  list  and  expr  =      |  Var  of  string      |  IntConst  of  int      |  Plus  of  expr  *  expr      |  Minus  of  expr  *  expr      |  Lambda  of  string  *  expr      |  Apply  of  expr  *  expr      |  Closure  of  env  *  string  *  expr      deriving  (Show)  

Page 46: FYP Final Presentation

Show.show<expr>  (Plus  (IntConst  40)                                                      (IntConst  2))  

Page 47: FYP Final Presentation

LAZY EVALUATION EXTENSION�Automatic generation �

of lazy and force �

Page 48: FYP Final Presentation

PROBLEM�Lazy streams are�

difficult to work with�

Page 49: FYP Final Presentation

type 'a node_t = | Nil | Cons of 'a * ('a node_t)!

Page 50: FYP Final Presentation

type 'a node_t = | Nil | Cons of 'a * ('a node_t) Lazy.t!

Page 51: FYP Final Presentation

let map f l = let rec aux rest = match Lazy.force rest with | Cons (x, r) -> Cons (f x, lazy (aux r)) | Nil -> Nil in lazy (aux l)!

Page 52: FYP Final Presentation

let map f l = let rec aux rest = match Lazy.force rest with | Cons (x, r) -> Cons (f x, lazy (aux r)) | Nil -> Nil in lazy (aux l)!

Page 53: FYP Final Presentation

let zipwith f l1 l2 = let rec aux r1 r2 = match Lazy.force r1, Lazy.force r2 with | Cons (x1, r1), Cons (x2, r2) -> Cons ((f x1 x2), lazy (aux r1 r2)) | Cons (x, r), Nil -> Cons (x, lazy (aux r (lazy Nil))) | Nil, Cons (x, r) -> Cons (x, lazy (aux (lazy Nil) r)) | Nil, Nil -> Nil in lazy (aux l1 l2)!

Page 54: FYP Final Presentation

let zipwith f l1 l2 = let rec aux r1 r2 = match Lazy.force r1, Lazy.force r2 with | Cons (x1, r1), Cons (x2, r2) -> Cons ((f x1 x2), lazy (aux r1 r2)) | Cons (x, r), Nil -> Cons (x, lazy (aux r (lazy Nil))) | Nil, Cons (x, r) -> Cons (x, lazy (aux (lazy Nil) r)) | Nil, Nil -> Nil in lazy (aux l1 l2)!

Page 55: FYP Final Presentation

SOLUTION�Annotate with keyword�and insert lazy and force when type error occurs�

Page 56: FYP Final Presentation

let ilazy map f l = let rec aux rest = match rest with | Cons (x, r) -> Cons (f x, aux r) | Nil -> Nil in aux l!

Page 57: FYP Final Presentation

let ilazy zipwith f l1 l2 = let rec aux r1 r2 = match r1, r2 with | Cons (x1, r1), Cons (x2, r2) -> Cons ((f x1 x2), (aux r1 r2)) | Cons (x, r), Nil -> Cons (x, (aux r Nil)) | Nil, Cons (x, r) -> Cons (x, (aux Nil r)) | Nil, Nil -> Nil in (aux l1 l2)!

Page 58: FYP Final Presentation

HOW DOES IT WORK?�

Page 59: FYP Final Presentation

Annotated�Expression�

Page 60: FYP Final Presentation

Camlp4 Lexer & Parser �

Annotated�Expression�

Page 61: FYP Final Presentation

Camlp4 Lexer & Parser �

Type Checker�

Annotated�Expression�

Page 62: FYP Final Presentation

Camlp4 Lexer & Parser �

Type Checker�

AST Transformer �

Annotated�Expression�

Page 63: FYP Final Presentation

Camlp4 Lexer & Parser �

Type Checker�

AST Transformer �

Annotated�Expression�

Generated�OCaml Code �

Page 64: FYP Final Presentation

Camlp4 Lexer & Parser �

Type Checker�

AST Transformer �

Annotated�Expression�

Generated�OCaml Code �

Page 65: FYP Final Presentation

TYPE CHECKER�OUTPUT�

Page 66: FYP Final Presentation

Error: This expression has type 'a lazy_t! but an expression was expected of type! 'b Batteries.LazyList.node_t = 'b BatLazyList.node_t!

Page 67: FYP Final Presentation

Error: This expression has type 'a lazy_t! but an expression was expected of type! 'b node_t!

THIS SAYS INSERT Lazy.force!

Page 68: FYP Final Presentation

Error: This expression has type! 'a node_t! but an expression was expected of type!! ! !int node_t lazy_t!

Page 69: FYP Final Presentation

Error: This expression has type! 'a node_t! but an expression was expected of type!! ! !int node_t lazy_t!

THIS SAYS INSERT�lazy!

Page 70: FYP Final Presentation

TYPE CHECKER�OUTPUT�

Output is in the form of a typed tree�

Page 71: FYP Final Presentation

TECHNICAL CHALLENGES�

Page 72: FYP Final Presentation

UNFAMILIARITY�WITH LANGUAGE�

Lots of mucking around�

Page 73: FYP Final Presentation

OPEN RECURSION�A feature in most OO languages�

Page 74: FYP Final Presentation

let  insert_lazy_at  loc  =      object          inherit  Ast.map  as  super          method  expr  e  =              match  super#expr  e  with              |  <:expr@_loc<  $e1$  $e2$  >>                        when  _loc  =  loc  -­‐>                    <:expr<  lazy  ($e1$  $e2$)  >>              |  <:expr@_loc<  $id:i$  >>                        when  _loc  =  loc  -­‐>                    <:expr<  lazy  $id:i$  >>              |  e  -­‐>  e    end  

Page 75: FYP Final Presentation

LACK OF DOCUMENTATION�

Lots of code reading�

Page 76: FYP Final Presentation

ASKING QUESTIONS ON IRC�

Page 77: FYP Final Presentation

SEARCHING AND READING COMPILER SOURCE CODE�

Page 78: FYP Final Presentation

QUESTIONS?�