Successfully reported this slideshow.
Your SlideShare is downloading. ×

ecoop-slides.pdf

Advertisement

More Related Content

Advertisement

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

ecoop-slides.pdf

  1. 1. Virtual ECOOP 2022 Direct Foundations for Compositional Programming Andong Fan*, Xuejing Huang*, Han Xu, Yaozhu Sun, and Bruno C. d. S. Oliveira *equal contributions
  2. 2. Expression Problem Background 2 Describes the dilemma of modular extension of datatypes and their operations e.g. extending simple arithmetic expressions and their operations…
  3. 3. Expression Problem Background 2 Describes the dilemma of modular extension of datatypes and their operations e.g. extending simple arithmetic expressions and their operations… OOP FP
  4. 4. Expression Problem Background 2 Describes the dilemma of modular extension of datatypes and their operations // class hierarchy trait Exp { def eval: Int } class Lit(n: Int) extends Exp { def eval: Int = n } class Sub(l: Exp, r: Exp) extends Exp { def eval: Int = l.eval - r.eval } new Sub(new Lit(1), new Lit(2)).eval e.g. extending simple arithmetic expressions and their operations… OOP FP
  5. 5. Expression Problem Background 2 Describes the dilemma of modular extension of datatypes and their operations // class hierarchy trait Exp { def eval: Int } class Lit(n: Int) extends Exp { def eval: Int = n } class Sub(l: Exp, r: Exp) extends Exp { def eval: Int = l.eval - r.eval } new Sub(new Lit(1), new Lit(2)).eval // algebraic datatype sealed trait Exp case class Lit(n: Int) extends Exp case class Sub(l: Exp, r: Exp) extends Exp // pattern matching function def eval(exp: Exp): Int = exp match { case Lit(n) => n case Sub(l, r) => eval(l) - eval(r) } eval(Sub(Lit(1), Lit(2))) e.g. extending simple arithmetic expressions and their operations… OOP FP
  6. 6. Expression Problem 3 of datatypes and their operations // class hierarchy trait Exp { def eval: Int } class Lit(n: Int) extends Exp { def eval: Int = n } class Sub(l: Exp, r: Exp) extends Exp { def eval: Int = l.eval - r.eval } class Add(l: Exp, r: Exp) extends Exp { def eval: Int = l.eval + r.eval } new Sub(new Lit(1), new Lit(2)).eval Modular! OOP FP Describes the dilemma of modular extension e.g. extending simple arithmetic expressions and their operations… // algebraic datatype sealed trait Exp case class Lit(n: Int) extends Exp case class Sub(l: Exp, r: Exp) extends Exp // pattern matching function def eval(exp: Exp): Int = exp match { case Lit(n) => n case Sub(l, r) => eval(l) - eval(r) } eval(Sub(Lit(1), Lit(2))) Background
  7. 7. Expression Problem 4 of datatypes and their operations trait Exp { def eval: Int def print: String } class Lit(n: Int) extends Exp { def eval: Int = n def print: String = .. } class Sub(l: Exp, r: Exp) extends Exp { def eval: Int = l.eval - r.eval def print: String = .. } class Add(l: Exp, r: Exp) extends Exp { def eval: Int = l.eval + r.eval def print: String = .. } new Sub(new Lit(1), new Lit(2)).eval OOP FP Non-Modular! Non-Modular! Non-Modular! Non-Modular! Describes the dilemma of modular extension e.g. extending simple arithmetic expressions and their operations… // algebraic datatype sealed trait Exp case class Lit(n: Int) extends Exp case class Sub(l: Exp, r: Exp) extends Exp // pattern matching function def eval(exp: Exp): Int = exp match { case Lit(n) => n case Sub(l, r) => eval(l) - eval(r) } eval(Sub(Lit(1), Lit(2))) Background
  8. 8. Expression Problem 4 of datatypes and their operations trait Exp { def eval: Int def print: String } class Lit(n: Int) extends Exp { def eval: Int = n def print: String = .. } class Sub(l: Exp, r: Exp) extends Exp { def eval: Int = l.eval - r.eval def print: String = .. } class Add(l: Exp, r: Exp) extends Exp { def eval: Int = l.eval + r.eval def print: String = .. } new Sub(new Lit(1), new Lit(2)).eval OOP FP Non-Modular! Non-Modular! Non-Modular! Non-Modular! Modular extension of Datatypes ✅ Operations ❌ Describes the dilemma of modular extension e.g. extending simple arithmetic expressions and their operations… // algebraic datatype sealed trait Exp case class Lit(n: Int) extends Exp case class Sub(l: Exp, r: Exp) extends Exp // pattern matching function def eval(exp: Exp): Int = exp match { case Lit(n) => n case Sub(l, r) => eval(l) - eval(r) } eval(Sub(Lit(1), Lit(2))) Background
  9. 9. Expression Problem 5 of datatypes and their operations trait Exp { def eval: Int def print: String } class Lit(n: Int) extends Exp { def eval: Int = n def print: String = .. } class Sub(l: Exp, r: Exp) extends Exp { def eval: Int = l.eval - r.eval def print: String = .. } class Add(l: Exp, r: Exp) extends Exp { def eval: Int = l.eval + r.eval def print: String = .. } new Sub(new Lit(1), new Lit(2)).eval // algebraic datatype sealed trait Exp case class Lit(n: Int) extends Exp case class Sub(l: Exp, r: Exp) extends Exp // pattern matching function def eval(exp: Exp): Int = exp match { case Lit(n) => n case Sub(l, r) => eval(l) - eval(r) } def print(exp: Exp): String = exp match { case Lit(n) => .. case Sub(l, r) => .. } eval(Sub(Lit(1), Lit(2))) OOP FP Non-Modular! Non-Modular! Non-Modular! Non-Modular! Modular extension of Datatypes ✅ Operations ❌ Describes the dilemma of modular extension Modular! e.g. extending simple arithmetic expressions and their operations… Background
  10. 10. Expression Problem 6 of datatypes and their operations trait Exp { def eval: Int def print: String } class Lit(n: Int) extends Exp { def eval: Int = n def print: String = .. } class Sub(l: Exp, r: Exp) extends Exp { def eval: Int = l.eval - r.eval def print: String = .. } class Add(l: Exp, r: Exp) extends Exp { def eval: Int = l.eval + r.eval def print: String = .. } new Sub(new Lit(1), new Lit(2)).eval sealed trait Exp case class Lit(n: Int) extends Exp case class Sub(l: Exp, r: Exp) extends Exp case class Add(l: Exp, r: Exp) extends Exp // pattern matching function def eval(exp: Exp): Int = exp match { case Lit(n) => n case Sub(l, r) => eval(l) - eval(r) case Add(l, r) => .. } def print(exp: Exp): String = exp match { case Lit(n) => .. case Sub(l, r) => .. case Add(l, r) => .. } eval(Sub(Lit(1), Lit(2))) OOP FP Non-Modular! Non-Modular! Non-Modular! Non-Modular! Modular extension of Datatypes ✅ Operations ❌ Describes the dilemma of modular extension Non-Modular! Non-Modular! Non-Modular! e.g. extending simple arithmetic expressions and their operations… Background
  11. 11. Expression Problem 6 of datatypes and their operations trait Exp { def eval: Int def print: String } class Lit(n: Int) extends Exp { def eval: Int = n def print: String = .. } class Sub(l: Exp, r: Exp) extends Exp { def eval: Int = l.eval - r.eval def print: String = .. } class Add(l: Exp, r: Exp) extends Exp { def eval: Int = l.eval + r.eval def print: String = .. } new Sub(new Lit(1), new Lit(2)).eval sealed trait Exp case class Lit(n: Int) extends Exp case class Sub(l: Exp, r: Exp) extends Exp case class Add(l: Exp, r: Exp) extends Exp // pattern matching function def eval(exp: Exp): Int = exp match { case Lit(n) => n case Sub(l, r) => eval(l) - eval(r) case Add(l, r) => .. } def print(exp: Exp): String = exp match { case Lit(n) => .. case Sub(l, r) => .. case Add(l, r) => .. } eval(Sub(Lit(1), Lit(2))) OOP FP Non-Modular! Non-Modular! Non-Modular! Non-Modular! Modular extension of Datatypes ✅ Operations ❌ Describes the dilemma of modular extension Non-Modular! Non-Modular! Non-Modular! Modular extension of Datatypes ❌ Operations ✅ e.g. extending simple arithmetic expressions and their operations… Background
  12. 12. Compositional Programming* 7 Background Provides natural solutions to the Expression Problem Employs intersection types, a merge operator, and fi rst-class traits Novel programming paradigm featuring modularity *Weixin Zhang, Yaozhu Sun, and Bruno C. d. S. Oliveira. Compositional programming. ACM Transactions on Programming Languages and Systems (TOPLAS), 43(3):1–61, 2021.
  13. 13. Compositional Programming 8 • Intersection types • Merge operator • First-class traits Background Novel programming paradigm featuring modularity
  14. 14. Compositional Programming 8 • Intersection types • Merge operator • First-class traits Compose types with & Background Novel programming paradigm featuring modularity
  15. 15. Compositional Programming 8 • Intersection types • Merge operator • First-class traits Compose types with & e.g. {a : A} & {b : B} == {a : A ; b : B} Background Novel programming paradigm featuring modularity
  16. 16. Compositional Programming 8 • Intersection types • Merge operator • First-class traits Compose types with & e.g. {a : A} & {b : B} == {a : A ; b : B} Compose terms with ,, Introductory structure of intersection types Background Novel programming paradigm featuring modularity
  17. 17. Compositional Programming 8 • Intersection types • Merge operator • First-class traits Compose types with & e.g. {a : A} & {b : B} == {a : A ; b : B} Compose terms with ,, Introductory structure of intersection types e.g. 1 ,, true has type Int & Bool Background Novel programming paradigm featuring modularity
  18. 18. Compositional Programming 8 • Intersection types • Merge operator • First-class traits Compose types with & e.g. {a : A} & {b : B} == {a : A ; b : B} Compose terms with ,, Introductory structure of intersection types e.g. 1 ,, true has type Int & Bool Basic structures of Composition Programming Background Novel programming paradigm featuring modularity
  19. 19. The CP Language 9 type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; Background Note: In CP the merge operator is `,` while it’s originally `,,`
  20. 20. The CP Language 9 evalNum = trait implements NumSig<Eval> => { (Lit n).eval = n; (Add e1 e2).eval = e1.eval + e2.eval; }; type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; type Eval = { eval: Int }; Background Note: In CP the merge operator is `,` while it’s originally `,,`
  21. 21. The CP Language 9 evalNum = trait implements NumSig<Eval> => { (Lit n).eval = n; (Add e1 e2).eval = e1.eval + e2.eval; }; type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; type Print = { print: String }; type Eval = { eval: Int }; Background printNum = trait implements NumSig<Print> => { (Lit n).print = toString n; (Add e1 e2).print = e1.print ++ "+" ++ e2.print; }; Note: In CP the merge operator is `,` while it’s originally `,,`
  22. 22. The CP Language 9 evalNum = trait implements NumSig<Eval> => { (Lit n).eval = n; (Add e1 e2).eval = e1.eval + e2.eval; }; exp = new (repoNum @(Eval & Print) , evalNum , printNum); repoNum Exp = trait [self: NumSig<Exp>] => { num = Add (Lit 2) (Lit 3); }; type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; type Print = { print: String }; type Eval = { eval: Int }; Background printNum = trait implements NumSig<Print> => { (Lit n).print = toString n; (Add e1 e2).print = e1.print ++ "+" ++ e2.print; }; Note: In CP the merge operator is `,` while it’s originally `,,`
  23. 23. The CP Language 9 evalNum = trait implements NumSig<Eval> => { (Lit n).eval = n; (Add e1 e2).eval = e1.eval + e2.eval; }; exp = new (repoNum @(Eval & Print) , evalNum , printNum); repoNum Exp = trait [self: NumSig<Exp>] => { num = Add (Lit 2) (Lit 3); }; Merge operator type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; type Print = { print: String }; type Eval = { eval: Int }; Background printNum = trait implements NumSig<Print> => { (Lit n).print = toString n; (Add e1 e2).print = e1.print ++ "+" ++ e2.print; }; Note: In CP the merge operator is `,` while it’s originally `,,`
  24. 24. The CP Language 9 evalNum = trait implements NumSig<Eval> => { (Lit n).eval = n; (Add e1 e2).eval = e1.eval + e2.eval; }; exp = new (repoNum @(Eval & Print) , evalNum , printNum); repoNum Exp = trait [self: NumSig<Exp>] => { num = Add (Lit 2) (Lit 3); }; Intersection type argument Merge operator type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; type Print = { print: String }; type Eval = { eval: Int }; Background printNum = trait implements NumSig<Print> => { (Lit n).print = toString n; (Add e1 e2).print = e1.print ++ "+" ++ e2.print; }; Note: In CP the merge operator is `,` while it’s originally `,,`
  25. 25. The CP Language 9 evalNum = trait implements NumSig<Eval> => { (Lit n).eval = n; (Add e1 e2).eval = e1.eval + e2.eval; }; exp = new (repoNum @(Eval & Print) , evalNum , printNum); repoNum Exp = trait [self: NumSig<Exp>] => { num = Add (Lit 2) (Lit 3); }; Intersection type argument Merge operator type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; type Print = { print: String }; type Eval = { eval: Int }; exp.num.eval —> 5 exp.num.print —> “2+3” Background printNum = trait implements NumSig<Print> => { (Lit n).print = toString n; (Add e1 e2).print = e1.print ++ "+" ++ e2.print; }; Note: In CP the merge operator is `,` while it’s originally `,,`
  26. 26. evalNum = trait implements NumSig<Eval> => { (Lit n).eval = n; (Add e1 e2).eval = e1.eval + e2.eval; }; printNum = trait implements NumSig<Print> => { (Lit n).print = toString n; (Add e1 e2).print = e1.print ++ "+" ++ e2.print; }; type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; type Print = { print: String }; type Eval = { eval: Int }; type MulSig<Exp> = { Mul: Exp -> Exp -> Exp; }; Background The CP Language 10 Note: In CP the merge operator is `,` while it’s originally `,,`
  27. 27. evalNum = trait implements NumSig<Eval> => { (Lit n).eval = n; (Add e1 e2).eval = e1.eval + e2.eval; }; printNum = trait implements NumSig<Print> => { (Lit n).print = toString n; (Add e1 e2).print = e1.print ++ "+" ++ e2.print; }; type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; type Print = { print: String }; type Eval = { eval: Int }; type MulSig<Exp> = { Mul: Exp -> Exp -> Exp; }; type ExpSig<Exp> = NumSig<Exp> & MulSig<Exp>; Background Intersection type The CP Language 10 Note: In CP the merge operator is `,` while it’s originally `,,`
  28. 28. evalNum = trait implements NumSig<Eval> => { (Lit n).eval = n; (Add e1 e2).eval = e1.eval + e2.eval; }; printNum = trait implements NumSig<Print> => { (Lit n).print = toString n; (Add e1 e2).print = e1.print ++ "+" ++ e2.print; }; type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; type Print = { print: String }; type Eval = { eval: Int }; type MulSig<Exp> = { Mul: Exp -> Exp -> Exp; }; evalMul = trait implements MulSig<Eval> => { (Mul e1 e2).eval = e1.eval * e2.eval; }; type ExpSig<Exp> = NumSig<Exp> & MulSig<Exp>; Background Intersection type The CP Language 10 Note: In CP the merge operator is `,` while it’s originally `,,`
  29. 29. evalNum = trait implements NumSig<Eval> => { (Lit n).eval = n; (Add e1 e2).eval = e1.eval + e2.eval; }; printNum = trait implements NumSig<Print> => { (Lit n).print = toString n; (Add e1 e2).print = e1.print ++ "+" ++ e2.print; }; type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; type Print = { print: String }; type Eval = { eval: Int }; type MulSig<Exp> = { Mul: Exp -> Exp -> Exp; }; evalMul = trait implements MulSig<Eval> => { (Mul e1 e2).eval = e1.eval * e2.eval; }; printMul = trait implements MulSig<Print> => { (Mul e1 e2).print = e1.print ++ "*" ++ e2.print; }; type ExpSig<Exp> = NumSig<Exp> & MulSig<Exp>; Background Intersection type The CP Language 10 Note: In CP the merge operator is `,` while it’s originally `,,`
  30. 30. evalNum = trait implements NumSig<Eval> => { (Lit n).eval = n; (Add e1 e2).eval = e1.eval + e2.eval; }; printNum = trait implements NumSig<Print> => { (Lit n).print = toString n; (Add e1 e2).print = e1.print ++ "+" ++ e2.print; }; type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; type Print = { print: String }; type Eval = { eval: Int }; type MulSig<Exp> = { Mul: Exp -> Exp -> Exp; }; evalMul = trait implements MulSig<Eval> => { (Mul e1 e2).eval = e1.eval * e2.eval; }; printMul = trait implements MulSig<Print> => { (Mul e1 e2).print = e1.print ++ "*" ++ e2.print; }; type ExpSig<Exp> = NumSig<Exp> & MulSig<Exp>; repoExp Exp = trait [self: ExpSig<Exp>] => { mul = Mul (Lit 2) (Lit 3) }; Background Intersection type The CP Language 10 Note: In CP the merge operator is `,` while it’s originally `,,`
  31. 31. evalNum = trait implements NumSig<Eval> => { (Lit n).eval = n; (Add e1 e2).eval = e1.eval + e2.eval; }; printNum = trait implements NumSig<Print> => { (Lit n).print = toString n; (Add e1 e2).print = e1.print ++ "+" ++ e2.print; }; type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; type Print = { print: String }; type Eval = { eval: Int }; type MulSig<Exp> = { Mul: Exp -> Exp -> Exp; }; evalMul = trait implements MulSig<Eval> => { (Mul e1 e2).eval = e1.eval * e2.eval; }; printMul = trait implements MulSig<Print> => { (Mul e1 e2).print = e1.print ++ "*" ++ e2.print; }; type ExpSig<Exp> = NumSig<Exp> & MulSig<Exp>; repoExp Exp = trait [self: ExpSig<Exp>] => { mul = Mul (Lit 2) (Lit 3) }; exp' = new (repoExp @(Eval & Print) , evalNum , evalMul , printNum , printMul); Background Intersection type Merge operator The CP Language 10 Note: In CP the merge operator is `,` while it’s originally `,,`
  32. 32. evalNum = trait implements NumSig<Eval> => { (Lit n).eval = n; (Add e1 e2).eval = e1.eval + e2.eval; }; printNum = trait implements NumSig<Print> => { (Lit n).print = toString n; (Add e1 e2).print = e1.print ++ "+" ++ e2.print; }; type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; type Print = { print: String }; type Eval = { eval: Int }; type MulSig<Exp> = { Mul: Exp -> Exp -> Exp; }; evalMul = trait implements MulSig<Eval> => { (Mul e1 e2).eval = e1.eval * e2.eval; }; printMul = trait implements MulSig<Print> => { (Mul e1 e2).print = e1.print ++ "*" ++ e2.print; }; type ExpSig<Exp> = NumSig<Exp> & MulSig<Exp>; repoExp Exp = trait [self: ExpSig<Exp>] => { mul = Mul (Lit 2) (Lit 3) }; exp' = new (repoExp @(Eval & Print) , evalNum , evalMul , printNum , printMul); exp'.num.eval —> 6 exp'.num.print —> “2*3” Background Intersection type Merge operator The CP Language 10 Note: In CP the merge operator is `,` while it’s originally `,,`
  33. 33. evalNum = trait implements NumSig<Eval> => { (Lit n).eval = n; (Add e1 e2).eval = e1.eval + e2.eval; }; printNum = trait implements NumSig<Print> => { (Lit n).print = toString n; (Add e1 e2).print = e1.print ++ "+" ++ e2.print; }; type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; type Print = { print: String }; type Eval = { eval: Int }; type MulSig<Exp> = { Mul: Exp -> Exp -> Exp; }; evalMul = trait implements MulSig<Eval> => { (Mul e1 e2).eval = e1.eval * e2.eval; }; printMul = trait implements MulSig<Print> => { (Mul e1 e2).print = e1.print ++ "*" ++ e2.print; }; type ExpSig<Exp> = NumSig<Exp> & MulSig<Exp>; repoExp Exp = trait [self: ExpSig<Exp>] => { mul = Mul (Lit 2) (Lit 3) }; exp' = new (repoExp @(Eval & Print) , evalNum , evalMul , printNum , printMul); exp'.num.eval —> 6 exp'.num.print —> “2*3” Background Intersection type Merge operator The CP Language 10 Note: In CP the merge operator is `,` while it’s originally `,,` repoExp + mul Lit + eval evalNum Add + eval printNum Lit + print Add + print evalMul Mul + eval printMul Mul + print , , , , = Lit + eval + print exp Mul + eval + print Add + eval + print + mul
  34. 34. evalNum = trait implements NumSig<Eval> => { (Lit n).eval = n; (Add e1 e2).eval = e1.eval + e2.eval; }; printNum = trait implements NumSig<Print> => { (Lit n).print = toString n; (Add e1 e2).print = e1.print ++ "+" ++ e2.print; }; type NumSig<Exp> = { Lit: Int -> Exp; Add: Exp -> Exp -> Exp; }; type Print = { print: String }; type Eval = { eval: Int }; type MulSig<Exp> = { Mul: Exp -> Exp -> Exp; }; evalMul = trait implements MulSig<Eval> => { (Mul e1 e2).eval = e1.eval * e2.eval; }; printMul = trait implements MulSig<Print> => { (Mul e1 e2).print = e1.print ++ "*" ++ e2.print; }; type ExpSig<Exp> = NumSig<Exp> & MulSig<Exp>; repoExp Exp = trait [self: ExpSig<Exp>] => { mul = Mul (Lit 2) (Lit 3) }; exp' = new (repoExp @(Eval & Print) , evalNum , evalMul , printNum , printMul); exp'.num.eval —> 6 exp'.num.print —> “2*3” Background Intersection type Merge operator The CP Language 10 Note: In CP the merge operator is `,` while it’s originally `,,` Solves the EP Modular Dependency Injection Modular Context Evolution
  35. 35. Disjoint Intersection Types* Background 11 Languages with the merge operator may be ambiguous *Bruno C. d. S. Oliveira, Zhiyuan Shi, and João Alpuim. Disjoint intersection types. In International Conference on Functional Programming (ICFP), 2016.
  36. 36. Disjoint Intersection Types* Background 11 Languages with the merge operator may be ambiguous 1 ,, 2 has type Int & Int (1 , , 2) + 3 ⟶ ??? *Bruno C. d. S. Oliveira, Zhiyuan Shi, and João Alpuim. Disjoint intersection types. In International Conference on Functional Programming (ICFP), 2016.
  37. 37. Disjoint Intersection Types* Background 11 Languages with the merge operator may be ambiguous 1 ,, 2 has type Int & Int (1 , , 2) + 3 ⟶ ??? Oliveira et al. proposed disjoint intersection types Reject ambiguous merges with overlapping types *Bruno C. d. S. Oliveira, Zhiyuan Shi, and João Alpuim. Disjoint intersection types. In International Conference on Functional Programming (ICFP), 2016.
  38. 38. Disjoint Intersection Types* Background 11 Languages with the merge operator may be ambiguous 1 ,, 2 has type Int & Int (1 , , 2) + 3 ⟶ ??? Oliveira et al. proposed disjoint intersection types Reject ambiguous merges with overlapping types Type is disjoint to type (i.e. ) A B A * B ≐ For all type if and then C A <: C B <: C C ∼ 𝖳 𝗈 𝗉 *Bruno C. d. S. Oliveira, Zhiyuan Shi, and João Alpuim. Disjoint intersection types. In International Conference on Functional Programming (ICFP), 2016.
  39. 39. Disjoint Intersection Types* Background 11 Languages with the merge operator may be ambiguous 1 ,, 2 has type Int & Int (1 , , 2) + 3 ⟶ ??? Oliveira et al. proposed disjoint intersection types Reject ambiguous merges with overlapping types Type is disjoint to type (i.e. ) A B A * B ≐ For all type if and then C A <: C B <: C C ∼ 𝖳 𝗈 𝗉 Type equivalence *Bruno C. d. S. Oliveira, Zhiyuan Shi, and João Alpuim. Disjoint intersection types. In International Conference on Functional Programming (ICFP), 2016.
  40. 40. Disjoint Intersection Types* Background 11 Languages with the merge operator may be ambiguous 1 ,, 2 has type Int & Int (1 , , 2) + 3 ⟶ ??? Oliveira et al. proposed disjoint intersection types Reject ambiguous merges with overlapping types Type is disjoint to type (i.e. ) A B A * B ≐ For all type if and then C A <: C B <: C C ∼ 𝖳 𝗈 𝗉 Type equivalence Int is the common supertype of Int itself *Bruno C. d. S. Oliveira, Zhiyuan Shi, and João Alpuim. Disjoint intersection types. In International Conference on Functional Programming (ICFP), 2016.
  41. 41. Disjoint Intersection Types* Background 11 Languages with the merge operator may be ambiguous 1 ,, 2 has type Int & Int (1 , , 2) + 3 ⟶ ??? Oliveira et al. proposed disjoint intersection types Reject ambiguous merges with overlapping types Type is disjoint to type (i.e. ) A B A * B ≐ For all type if and then C A <: C B <: C C ∼ 𝖳 𝗈 𝗉 Type equivalence Int is the common supertype of Int itself Int * Int, therefore 1 ,, 2 is rejected *Bruno C. d. S. Oliveira, Zhiyuan Shi, and João Alpuim. Disjoint intersection types. In International Conference on Functional Programming (ICFP), 2016.
  42. 42. 12 Motivation The Calculus - CP’s Foundation 𝖥 + i A polymorphic calculus with disjoint intersection types and a merge operator
  43. 43. 13 Motivation The Calculus - CP’s Foundation 𝖥 + i A polymorphic calculus with disjoint intersection types and a merge operator
  44. 44. 13 Motivation The Calculus - CP’s Foundation 𝖥 + i A polymorphic calculus with disjoint intersection types and a merge operator The current formulation of 𝖥 + i based on an elaboration semantics
  45. 45. 13 Motivation The Calculus - CP’s Foundation 𝖥 + i A polymorphic calculus with disjoint intersection types and a merge operator The current formulation of 𝖥 + i • Lack of impredicative polymorphism • Lack of recursion its coherence proof causes… based on an elaboration semantics
  46. 46. 13 Motivation The Calculus - CP’s Foundation 𝖥 + i A polymorphic calculus with disjoint intersection types and a merge operator The current formulation of 𝖥 + i • Lack of impredicative polymorphism • Lack of recursion While CP allows the creation of objects with polymorphic methods its coherence proof causes… based on an elaboration semantics
  47. 47. 14 Motivation The Calculus - CP’s Foundation 𝖥 + i The current formulation of 𝖥 + i • Lack of impredicative polymorphism • Lack of recursion its coherence proof causes… based on an elaboration semantics While CP’s elaboration of traits… ↝ A polymorphic calculus with disjoint intersection types and a merge operator
  48. 48. 15 Motivation The Calculus - CP’s Foundation 𝖥 + i The current formulation of 𝖥 + i its coherence proof causes… based on an elaboration semantics While CP’s elaboration of traits… ↝ A polymorphic calculus with disjoint intersection types and a merge operator • Lack of impredicative polymorphism • Lack of recursion
  49. 49. 16 Motivation The Calculus - CP’s Foundation 𝖥 + i The current formulation of 𝖥 + i • Di ff erence in evaluation strategies its coherence proof causes… based on an elaboration semantics While call-by-value will diverge in… • CP assumed call-by-name • is call-by-value 𝖥 + i A polymorphic calculus with disjoint intersection types and a merge operator Note: CP is implemented as call-by-need • Lack of impredicative polymorphism • Lack of recursion
  50. 50. 17 Motivation The Calculus - CP’s Foundation 𝖥 + i The current formulation of 𝖥 + i • Di ff erence in evaluation strategies its coherence proof causes… based on an elaboration semantics • CP assumed call-by-name • is call-by-value 𝖥 + i }The gap between theory & practice A polymorphic calculus with disjoint intersection types and a merge operator Note: CP is implemented as call-by-need • Lack of impredicative polymorphism • Lack of recursion
  51. 51. 18 Our Contribution The Calculus - CP’s Foundation 𝖥 + i The new formulation of 𝖥 + i its determinism proof is simple based on a direct Type-Directed Operational Semantics* • CP assumed call-by-name • is call-by-name 𝖥 + i }The gap between theory & practice • Lack of impredicative polymorphism • Lack of recursion • Di ff erence in evaluation strategies A polymorphic calculus with disjoint intersection types and a merge operator Note: CP is implemented as call-by-need *Xuejing Huang and Bruno C. d. S. Oliveira. A type-directed operational semantics for a calculus with a merge operator. In 34th European Conference on Object-Oriented Programming (ECOOP 2020), volume 166 of Leibniz International Proceedings in Informatics (LIPIcs), pages 26:1–26:32.
  52. 52. 18 Our Contribution The Calculus - CP’s Foundation 𝖥 + i The new formulation of 𝖥 + i its determinism proof is simple based on a direct Type-Directed Operational Semantics* • CP assumed call-by-name • is call-by-name 𝖥 + i }The gap between theory & practice • Lack of impredicative polymorphism • Lack of recursion • Di ff erence in evaluation strategies A polymorphic calculus with disjoint intersection types and a merge operator Note: CP is implemented as call-by-need *Xuejing Huang and Bruno C. d. S. Oliveira. A type-directed operational semantics for a calculus with a merge operator. In 34th European Conference on Object-Oriented Programming (ECOOP 2020), volume 166 of Leibniz International Proceedings in Informatics (LIPIcs), pages 26:1–26:32.
  53. 53. 18 Our Contribution The Calculus - CP’s Foundation 𝖥 + i The new formulation of 𝖥 + i its determinism proof is simple based on a direct Type-Directed Operational Semantics* • CP assumed call-by-name • is call-by-name 𝖥 + i }The gap between theory & practice • Lack of impredicative polymorphism • Lack of recursion • Di ff erence in evaluation strategies A polymorphic calculus with disjoint intersection types and a merge operator Note: CP is implemented as call-by-need *Xuejing Huang and Bruno C. d. S. Oliveira. A type-directed operational semantics for a calculus with a merge operator. In 34th European Conference on Object-Oriented Programming (ECOOP 2020), volume 166 of Leibniz International Proceedings in Informatics (LIPIcs), pages 26:1–26:32.
  54. 54. 18 Our Contribution The Calculus - CP’s Foundation 𝖥 + i The new formulation of 𝖥 + i its determinism proof is simple based on a direct Type-Directed Operational Semantics* • CP assumed call-by-name • is call-by-name 𝖥 + i }The gap between theory & practice • Lack of impredicative polymorphism • Lack of recursion • Di ff erence in evaluation strategies A polymorphic calculus with disjoint intersection types and a merge operator Note: CP is implemented as call-by-need *Xuejing Huang and Bruno C. d. S. Oliveira. A type-directed operational semantics for a calculus with a merge operator. In 34th European Conference on Object-Oriented Programming (ECOOP 2020), volume 166 of Leibniz International Proceedings in Informatics (LIPIcs), pages 26:1–26:32.
  55. 55. 18 Our Contribution The Calculus - CP’s Foundation 𝖥 + i The new formulation of 𝖥 + i its determinism proof is simple based on a direct Type-Directed Operational Semantics* • CP assumed call-by-name • is call-by-name 𝖥 + i }The gap between theory & practice • Lack of impredicative polymorphism • Lack of recursion • Di ff erence in evaluation strategies A polymorphic calculus with disjoint intersection types and a merge operator Note: CP is implemented as call-by-need *Xuejing Huang and Bruno C. d. S. Oliveira. A type-directed operational semantics for a calculus with a merge operator. In 34th European Conference on Object-Oriented Programming (ECOOP 2020), volume 166 of Leibniz International Proceedings in Informatics (LIPIcs), pages 26:1–26:32.
  56. 56. The Calculus 𝖥 + i Example 19 type LitSig<Exp> = { Lit: Int -> Exp }; type Eval = { eval: Int }; type Print = { print: String }; evalLit = trait implements LigSig<Eval> => { (Lit n).eval = n; } printLit = trait implements LigSig<Print> => { (Lit n).print = toString n; } repoLit Exp = trait [self: LitSig<Exp>] => { num = Lit ((1+1) , true); }; (new repoLit @(Eval & Print) , evalLit , printLit).num
  57. 57. The Calculus 𝖥 + i Example 19 type LitSig<Exp> = { Lit: Int -> Exp }; type Eval = { eval: Int }; type Print = { print: String }; evalLit = trait implements LigSig<Eval> => { (Lit n).eval = n; } printLit = trait implements LigSig<Print> => { (Lit n).print = toString n; } repoLit Exp = trait [self: LitSig<Exp>] => { num = Lit ((1+1) , true); }; (new repoLit @(Eval & Print) , evalLit , printLit).num
  58. 58. The Calculus 𝖥 + i Example 19 type LitSig<Exp> = { Lit: Int -> Exp }; type Eval = { eval: Int }; type Print = { print: String }; evalLit = trait implements LigSig<Eval> => { (Lit n).eval = n; } printLit = trait implements LigSig<Print> => { (Lit n).print = toString n; } repoLit Exp = trait [self: LitSig<Exp>] => { num = Lit ((1+1) , true); }; (new repoLit @(Eval & Print) , evalLit , printLit).num ({ 𝖫 𝗂 𝗍 = f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }} , , { 𝖫 𝗂 𝗍 = g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }}) . 𝖫 𝗂 𝗍 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ↝ after simpli fi cation
  59. 59. The Calculus 𝖥 + i Example 19 type LitSig<Exp> = { Lit: Int -> Exp }; type Eval = { eval: Int }; type Print = { print: String }; evalLit = trait implements LigSig<Eval> => { (Lit n).eval = n; } printLit = trait implements LigSig<Print> => { (Lit n).print = toString n; } repoLit Exp = trait [self: LitSig<Exp>] => { num = Lit ((1+1) , true); }; (new repoLit @(Eval & Print) , evalLit , printLit).num ({ 𝖫 𝗂 𝗍 = f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }} , , { 𝖫 𝗂 𝗍 = g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }}) . 𝖫 𝗂 𝗍 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ↝ after simpli fi cation g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x})
  60. 60. The Calculus 𝖥 + i Example 19 type LitSig<Exp> = { Lit: Int -> Exp }; type Eval = { eval: Int }; type Print = { print: String }; evalLit = trait implements LigSig<Eval> => { (Lit n).eval = n; } printLit = trait implements LigSig<Print> => { (Lit n).print = toString n; } repoLit Exp = trait [self: LitSig<Exp>] => { num = Lit ((1+1) , true); }; (new repoLit @(Eval & Print) , evalLit , printLit).num ({ 𝖫 𝗂 𝗍 = f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }} , , { 𝖫 𝗂 𝗍 = g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }}) . 𝖫 𝗂 𝗍 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ↝ after simpli fi cation g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x})
  61. 61. The Calculus 𝖥 + i Example 19 type LitSig<Exp> = { Lit: Int -> Exp }; type Eval = { eval: Int }; type Print = { print: String }; evalLit = trait implements LigSig<Eval> => { (Lit n).eval = n; } printLit = trait implements LigSig<Print> => { (Lit n).print = toString n; } repoLit Exp = trait [self: LitSig<Exp>] => { num = Lit ((1+1) , true); }; (new repoLit @(Eval & Print) , evalLit , printLit).num ({ 𝖫 𝗂 𝗍 = f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }} , , { 𝖫 𝗂 𝗍 = g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }}) . 𝖫 𝗂 𝗍 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ↝ after simpli fi cation ↪ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x})
  62. 62. The Calculus 𝖥 + i 20 Example Dynamic ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x})
  63. 63. The Calculus 𝖥 + i 20 Example Dynamic ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ↪ Parallel application (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x})
  64. 64. The Calculus 𝖥 + i 20 Example Dynamic ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ↪ Parallel application (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x})
  65. 65. The Calculus 𝖥 + i 20 Example Dynamic ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 : 𝖨 𝗇 𝗍 ↪ Parallel application (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x})
  66. 66. The Calculus 𝖥 + i 20 Example Dynamic ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 : 𝖨 𝗇 𝗍 Call-by-name ↪ Parallel application (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) { 𝖾 𝗏 𝖺 𝗅 = ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 } , , { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 } Value!
  67. 67. The Calculus 𝖥 + i 20 Example Dynamic ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 : 𝖨 𝗇 𝗍 Call-by-name ↪ Parallel application (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) { 𝖾 𝗏 𝖺 𝗅 = ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 } , , { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 } Consider projecting out… 𝖾 𝗏 𝖺 𝗅 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 Value!
  68. 68. The Calculus 𝖥 + i 20 Example Dynamic ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 : 𝖨 𝗇 𝗍 Call-by-name ↪ Parallel application ↪ Evaluate the merge Evaluate the merge (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) { 𝖾 𝗏 𝖺 𝗅 = ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 } , , { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 } Consider projecting out… 𝖾 𝗏 𝖺 𝗅 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 Value!
  69. 69. The Calculus 𝖥 + i 20 Example Dynamic (2 , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 : 𝖨 𝗇 𝗍 Call-by-name ↪ Parallel application ↪ Evaluate the merge Evaluate the merge Lazy evaluation (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) { 𝖾 𝗏 𝖺 𝗅 = ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 } , , { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 } Consider projecting out… 𝖾 𝗏 𝖺 𝗅 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 Value!
  70. 70. The Calculus 𝖥 + i 20 Example Dynamic (2 , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 : 𝖨 𝗇 𝗍 Call-by-name ↪ Parallel application ↪ Evaluate the merge Evaluate the merge Lazy evaluation ↪ Casting (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) { 𝖾 𝗏 𝖺 𝗅 = ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 } , , { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 } Consider projecting out… 𝖾 𝗏 𝖺 𝗅 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 Value!
  71. 71. The Calculus 𝖥 + i 20 Example Dynamic (2 , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 2 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 : 𝖨 𝗇 𝗍 Call-by-name ↪ Parallel application ↪ Evaluate the merge Evaluate the merge Lazy evaluation ↪ Casting Select the desired value with type annotations (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) { 𝖾 𝗏 𝖺 𝗅 = ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 } , , { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 } Consider projecting out… 𝖾 𝗏 𝖺 𝗅 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) : 𝖨 𝗇 𝗍 Value!
  72. 72. The Calculus 𝖥 + i Example 21 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static
  73. 73. The Calculus 𝖥 + i Example 21 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ Type synthesis (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static
  74. 74. The Calculus 𝖥 + i Example 21 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒ Type synthesis (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static
  75. 75. The Calculus 𝖥 + i Example 21 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒ Type synthesis (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐
  76. 76. The Calculus 𝖥 + i Example 21 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒ Type synthesis (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static Type checking ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐
  77. 77. The Calculus 𝖥 + i Example 21 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐
  78. 78. The Calculus 𝖥 + i Example 21 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒ f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } ⇒ g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐
  79. 79. The Calculus 𝖥 + i Example 21 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒ f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } ⇒ g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }⇒ 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐
  80. 80. The Calculus 𝖥 + i Example 21 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒ f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } ⇒ g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }⇒ 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 } (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐
  81. 81. The Calculus 𝖥 + i Example 21 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒ f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } ⇒ g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }⇒ 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 } 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 } * (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐
  82. 82. The Calculus 𝖥 + i Example 21 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒ f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } ⇒ g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }⇒ 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 } 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 } * ( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐
  83. 83. The Calculus 𝖥 + i Example 22 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ⊳ 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } & { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 } ( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐
  84. 84. The Calculus 𝖥 + i Example 22 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ⊳ Applicative distribution 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } & { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 } ( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐
  85. 85. The Calculus 𝖥 + i Example 22 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ⊳ Applicative distribution 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } & { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 } ( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (A → B1) & (A → B2) <: A → B1 & B2 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐
  86. 86. The Calculus 𝖥 + i Example 23 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐ ⊳ Applicative distribution 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } & { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 } ( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (A → B1) & (A → B2) <: A → B1 & B2 𝖨 𝗇 𝗍
  87. 87. The Calculus 𝖥 + i Example 23 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐ ⊳ Applicative distribution 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } & { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 } ( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (A → B1) & (A → B2) <: A → B1 & B2 𝖨 𝗇 𝗍 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒
  88. 88. The Calculus 𝖥 + i Example 23 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐ ⊳ Applicative distribution 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } & { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 } ( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (A → B1) & (A → B2) <: A → B1 & B2 𝖨 𝗇 𝗍 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ 𝖨 𝗇 𝗍 & 𝖡 𝗈 𝗈 𝗅
  89. 89. The Calculus 𝖥 + i Example 23 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐ ⊳ Applicative distribution 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } & { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 } ( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (A → B1) & (A → B2) <: A → B1 & B2 𝖨 𝗇 𝗍 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ 𝖨 𝗇 𝗍 & 𝖡 𝗈 𝗈 𝗅 𝖨 𝗇 𝗍 & 𝖡 𝗈 𝗈 𝗅 <: 𝖨 𝗇 𝗍
  90. 90. The Calculus 𝖥 + i Example 23 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐ ⊳ Applicative distribution 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } & { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 } ( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (A → B1) & (A → B2) <: A → B1 & B2 𝖨 𝗇 𝗍 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ 𝖨 𝗇 𝗍 & 𝖡 𝗈 𝗈 𝗅 𝖨 𝗇 𝗍 & 𝖡 𝗈 𝗈 𝗅 <: 𝖨 𝗇 𝗍
  91. 91. The Calculus 𝖥 + i Example 23 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) ⇒( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (f : 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } , , g : 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) g := (λx : 𝖨 𝗇 𝗍 . { 𝗉 𝗋 𝗂 𝗇 𝗍 = 𝗍 𝗈 𝖲 𝗍 𝗋 𝗂 𝗇 𝗀 x}) f := (λx : 𝖨 𝗇 𝗍 . { 𝖾 𝗏 𝖺 𝗅 = x}) Static ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇐ ⊳ Applicative distribution 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } & { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 } ( 𝖨 𝗇 𝗍 → { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 }) ( 𝖨 𝗇 𝗍 → { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }) & (A → B1) & (A → B2) <: A → B1 & B2 𝖨 𝗇 𝗍 ((1 + 1) , , 𝗍 𝗋 𝗎 𝖾 ) ⇒ 𝖨 𝗇 𝗍 & 𝖡 𝗈 𝗈 𝗅 𝖨 𝗇 𝗍 & 𝖡 𝗈 𝗈 𝗅 <: 𝖨 𝗇 𝗍 { 𝖾 𝗏 𝖺 𝗅 : 𝖨 𝗇 𝗍 } & { 𝗉 𝗋 𝗂 𝗇 𝗍 : 𝖲 𝗍 𝗋 }
  92. 92. Thanks! More in the paper… 24 • Artifact • Algorithmic subtyping with polymorphic types • Enhanced subtyping and disjointness • More CP examples • Self-contained presentation of 𝖥 + i
  93. 93. Thanks! More in the paper… 25 • Artifact • Algorithmic subtyping with polymorphic types • Enhanced subtyping and disjointness • More CP examples • Self-contained presentation of 𝖥 + i *Xuejing Huang, Jinxu Zhao, and Bruno C. d. S. Oliveira. Taming the merge operator. Journal of Functional Programming, 31:e28, 2021.
  94. 94. Thanks! More in the paper… 25 • Artifact • Algorithmic subtyping with polymorphic types Based on splittable types* • Enhanced subtyping and disjointness • More CP examples • Self-contained presentation of 𝖥 + i *Xuejing Huang, Jinxu Zhao, and Bruno C. d. S. Oliveira. Taming the merge operator. Journal of Functional Programming, 31:e28, 2021.
  95. 95. Thanks! More in the paper… 25 • Artifact • Algorithmic subtyping with polymorphic types Based on splittable types* • Enhanced subtyping and disjointness More types equivalent to Top • More CP examples • Self-contained presentation of 𝖥 + i *Xuejing Huang, Jinxu Zhao, and Bruno C. d. S. Oliveira. Taming the merge operator. Journal of Functional Programming, 31:e28, 2021.
  96. 96. Thanks! More in the paper… 25 • Artifact is type sound, formalized in the Coq theorem prover 𝖥 + i • Algorithmic subtyping with polymorphic types Based on splittable types* • Enhanced subtyping and disjointness More types equivalent to Top • More CP examples • Self-contained presentation of 𝖥 + i A PureScript implementation of CP on top of 𝖥 + i *Xuejing Huang, Jinxu Zhao, and Bruno C. d. S. Oliveira. Taming the merge operator. Journal of Functional Programming, 31:e28, 2021.

×