twice x = 3 * x -‐ (42 -‐ 41) * x let x2 = twice 5 let add x y = x + y let seven = add 4 (1 + 2) let fact n = if n < 2 then 1 else n * fact (n-‐1) Thursday, 23 May, 13
let o = Some "thing" data List a = Cons a (List a) | Nil let l = Cons 5 (Cons 6 Nil) data Tree a = Null | Leaf a | Node (Tree a) a (Tree a) let t = Node (Leaf 5) 4 (Leaf 3) Thursday, 23 May, 13
match xs [] => Nil h :: t => (f h) :: (map f t) let l = [1, 2] let double x = 2 * x -‐-‐ pass a function by name let l2 = map double l -‐-‐ or simply a lambda let l2 = map (\x => 2 * x) l let a = 4 let f = \x => a * x -‐-‐ f captures the lexical value of a, i.e. 4 let a = 5 f 5 Thursday, 23 May, 13
let NAME add NAME x NAME y SYM = SYM + NAME x NAME y Expr.EName name: y LetBinding name: add type:_ args: [x, y] instructions EAp fn arg EAp fn arg Expr.EName name: + Expr.EName name: x Thursday, 23 May, 13
p = new Program(); p.instructions.addAll(body()); return p; } private List<Instruction> body() { List<Instruction> res = new ArrayList<Instruction>(); while (found(Token.Type.NEWLINE)) { res.add(instruction()); } return res; } Thursday, 23 May, 13
Num = if x > y x else y • Vérifier que les arguments (x, y) déclarent leur type • Vérifier que le type de retour est précisé •Vérifier que le type de la condition de if est Bool • Vérifier que le type de retour du “then” est le même que celui déclaré comme retour • Idem pour le “else” Thursday, 23 May, 13
inféré à t2 ‣ Si t2 variable, unifier t2 et t1 (cas 1) ‣ Sinon, t1 et t2 sont du type Oper ‣ Si t1.name != t2.name => erreur ‣ Si t1.types.size != t2 => erreur ‣ Unifier t1.types et t2.types Thursday, 23 May, 13
• Au final, first: a -‐> b -‐> a • analyze(let f = ...) • unify(Num -‐> Bool -‐> v4, a2 -‐> b2 -‐> a2) • a2 = Num, b2 = Bool • v4 = a2 = Num • f: Num • mais first est toujours a -‐> b -‐> c let first x y = x let f = first 4 false Fresh Thursday, 23 May, 13
j’avais à faire c’était de: •Décoder les papiers de recherche •Adapter à Litil: •Pas de pattern-matching dans HM •Let différent •... Thursday, 23 May, 13
public Object eval(Object arg, ValScope scope); } ChainingFn argName nextFn eval: •Reprend les arguments précédents {name, value} •Rajoute le sien (arg) de façon anonyme •Retourne une implem de Fn (argument arg2) qui: •Reprend l’arg anonyme et l’indexe sous argName •Done la main à next ChainingLastFn argName instructions eval: •Reprend les arguments précédents {name, value} •Reprend l’arg anonyme et l’indexe sous argName •Prépare un environnement avec les args •Exécute instructions •Retourne le résultat Thursday, 23 May, 13
x + y Expr.EName name: y LetBinding name: add type:_ args: [x, y] instructions EAp fn arg EAp fn arg Expr.EName name: + Expr.EName name: x AST add 1 2 ChainingFn argName: x next ChainingLastFn argName: y instructions Trop com pliqué* * En fait j’avais plus de temps pour préparer les schémas, et puis ça fait longtemps que j’avais pas touché à ça Thursday, 23 May, 13