Structural Prototypes A Sane Framework for Statically-Typed OO+FP - - PowerPoint PPT Presentation

structural prototypes
SMART_READER_LITE
LIVE PREVIEW

Structural Prototypes A Sane Framework for Statically-Typed OO+FP - - PowerPoint PPT Presentation

Structural Prototypes A Sane Framework for Statically-Typed OO+FP Avoiding Religion Were doing static typing, like it or not! Assume with me that OO is good Expressiveness is good More expressiveness is better? Class Types


slide-1
SLIDE 1

Structural Prototypes

A Sane Framework for Statically-Typed OO+FP

slide-2
SLIDE 2

Avoiding Religion

  • We’re doing static typing, like it or not!
  • Assume with me that OO is good
  • Expressiveness is good
  • More expressiveness is better?
slide-3
SLIDE 3

Class Types

slide-4
SLIDE 4

Class Types Parametric Polymorphism

slide-5
SLIDE 5

Class Types Parametric Polymorphism Declaration Site Variance

slide-6
SLIDE 6

Class Types Parametric Polymorphism Declaration Site Variance Existentials

slide-7
SLIDE 7

Class Types Parametric Polymorphism Declaration Site Variance B

  • u

n d e d Q u a n t i fi c a t i

  • n

Existentials

slide-8
SLIDE 8

Class Types Parametric Polymorphism Declaration Site Variance B

  • u

n d e d Q u a n t i fi c a t i

  • n

Existentials P a t h Dependent

slide-9
SLIDE 9

Class Types Parametric Polymorphism Declaration Site Variance B

  • u

n d e d Q u a n t i fi c a t i

  • n

Existentials P a t h Dependent Higher Kinds

slide-10
SLIDE 10

Class Types Parametric Polymorphism Declaration Site Variance B

  • u

n d e d Q u a n t i fi c a t i

  • n

Existentials P a t h Dependent Higher Kinds

slide-11
SLIDE 11

FP Makes It Worse…

  • Higher-Kinds are really necessary
slide-12
SLIDE 12

FP Makes It Worse…

  • Higher-Kinds are really necessary
  • Typeclasses
  • (and a zillion resolution strategies)
slide-13
SLIDE 13

FP Makes It Worse…

  • Higher-Kinds are really necessary
  • Typeclasses
  • (and a zillion resolution strategies)
  • Higher-Rank polymorphism
slide-14
SLIDE 14

FP Makes It Worse…

  • Higher-Kinds are really necessary
  • Typeclasses
  • (and a zillion resolution strategies)
  • Higher-Rank polymorphism
  • Functional utility methods
slide-15
SLIDE 15

Turing Completeness

  • Higher-Kinds give us simply-typed λ-calculus
slide-16
SLIDE 16

Turing Completeness

  • Higher-Kinds give us simply-typed λ-calculus
  • Object-Orientation implies open recursion
slide-17
SLIDE 17

Turing Completeness

  • Higher-Kinds give us simply-typed λ-calculus
  • Object-Orientation implies open recursion
  • Path-dependent types reify open recursion
  • Escapes object context!
slide-18
SLIDE 18

Turing Completeness

  • Higher-Kinds give us simply-typed λ-calculus
  • Object-Orientation implies open recursion
  • Path-dependent types reify open recursion
  • Escapes object context!
  • Type-Level Fixpoint
slide-19
SLIDE 19

Scala is Inevitable!

slide-20
SLIDE 20

Scala is Inevitable!

U n d e c i d a b i l i t y

slide-21
SLIDE 21

Starting over…

slide-22
SLIDE 22
slide-23
SLIDE 23

Hindley-Milner

  • Not particularly powerful (read: expressive)
slide-24
SLIDE 24

Hindley-Milner

  • Not particularly powerful (read: expressive)
  • Lots of significant limitations
  • And yet, it’s still very popular!
slide-25
SLIDE 25

Hindley-Milner

  • Not particularly powerful (read: expressive)
  • Lots of significant limitations
  • And yet, it’s still very popular!
  • Hindley-Milner is Good Enough™
slide-26
SLIDE 26

What is Object-Orientation?

slide-27
SLIDE 27

What is Object-Orientation?

  • Message Passing
  • Open Recursion
slide-28
SLIDE 28

What is Object-Orientation?

  • Message Passing
  • Open Recursion

a p p a r e n t l y C L O S > O O …

slide-29
SLIDE 29

Simplify, Simplify

  • Q: What is the simplest way to encode objects?
  • (hint: it’s not π-calculus)
slide-30
SLIDE 30

Simplify, Simplify

  • Q: What is the simplest way to encode objects?
  • (hint: it’s not π-calculus)
  • A: Records of functions
slide-31
SLIDE 31

Simplify, Simplify

  • Q: What is the simplest way to encode objects?
  • (hint: it’s not π-calculus)
  • A: Records of functions
  • Primitive self pointer
slide-32
SLIDE 32

What is Functional?

slide-33
SLIDE 33

What is Functional?

λ

slide-34
SLIDE 34

Simplify, Simplify

  • Q: What’s the simplest way to encode lambdas?
slide-35
SLIDE 35

Simplify, Simplify

  • Q: What’s the simplest way to encode lambdas?
  • A: Uh…with lambdas?
slide-36
SLIDE 36

Simplify, Simplify

  • Q: What’s the simplest way to encode lambdas?
  • A: Uh…with lambdas?
  • Let-bound polymorphism
slide-37
SLIDE 37

Putting It Together

  • Records of lambdas
slide-38
SLIDE 38

Putting It Together

  • Records of lambdas
  • Primitive self pointer
slide-39
SLIDE 39

Putting It Together

  • Records of lambdas
  • Primitive self pointer
  • Let-bound polymorphism
  • (requires extension for objects)
slide-40
SLIDE 40

Putting It Together

  • Records of lambdas
  • Primitive self pointer
  • Let-bound polymorphism
  • (requires extension for objects)
  • Principal typing
slide-41
SLIDE 41

Structural Prototypes

  • We only have records, no classes
  • Object abstraction must be prototypical
slide-42
SLIDE 42

Structural Prototypes

  • We only have records, no classes
  • Object abstraction must be prototypical
  • Record types are fully-structural
  • Not quite OCaml!
slide-43
SLIDE 43

Structural Prototypes

  • We only have records, no classes
  • Object abstraction must be prototypical
  • Record types are fully-structural
  • Not quite OCaml!
  • Full expressivity of both FP and OO
slide-44
SLIDE 44

Structural Prototypes

  • We only have records, no classes
  • Object abstraction must be prototypical
  • Record types are fully-structural
  • Not quite OCaml!
  • Full expressivity of both FP and OO
  • Very simple and orthogonal
slide-45
SLIDE 45

Apricot = Origin.with( sweetness: 7 bites: 0 takeBite: #(this.with(bites: bites + 1))) Grapefruit = Apricot.with(sweetness: 1) Apple = Apricot.with(sweetness: 5)

slide-46
SLIDE 46

Some = #(x, Origin.with( getOrElse: #(_, x) map: #(f, Some(f(x))) flatMap: #(f, f(x)))) None = Origin.with( getOrElse: #(x, x) map: #(_, this) flatMap: #(_, this))

slide-47
SLIDE 47

Seq = #(foldRight, Origin.with( builder: #(xs, Seq(xs.foldRight)) foldRight: foldRight map: #(f, res = foldRight(Vector0, #(x, acc, acc.prepend(f(x)))))))

slide-48
SLIDE 48

Seq = #(foldRight, Origin.with( builder: #(xs, Seq(xs.foldRight)) foldRight: foldRight map: #(f, res = foldRight(Vector0, #(x, acc, acc.prepend(f(x))))))) ListImpl = #(foldRight, Seq(foldRight).with( builder: #(xs, xs.foldRight(Nil, Cons)))) Cons = #(head, tail, foldRight = #(z, f, f(head, tail.foldRight(z, f))) ListImpl(foldRight)) Nil = ListImpl(#(_, z, z))

slide-49
SLIDE 49

Vector = #(xs, ds = Origin.with( /* hard core data structure */ ) Seq(ds.foldRight).with( builder: Vector prepend: #(x, …))) Vector0 = … // empty vector

slide-50
SLIDE 50

Problems

  • Structural subtyping is usually tricky
  • Error messages
  • Branded types?
slide-51
SLIDE 51

Problems

  • Structural subtyping is usually tricky
  • Error messages
  • Branded types?
  • Prototypes are not always fantastic
slide-52
SLIDE 52

Problems

  • Structural subtyping is usually tricky
  • Error messages
  • Branded types?
  • Prototypes are not always fantastic
  • Let-bound polymorphism is very restrictive
slide-53
SLIDE 53

Is this the Future?

  • I don’t know (probably not)
  • We need to keep trying!
  • Static typing is very hard
  • …complicated
  • …and divisive
slide-54
SLIDE 54

Questions?