Polymorphic Symmetric Multiple Dispatch with VariancePolymorphic Symmetric Multiple Dispatch with...

Post on 10-Oct-2020

12 views 0 download

Transcript of Polymorphic Symmetric Multiple Dispatch with VariancePolymorphic Symmetric Multiple Dispatch with...

Polymorphic Symmetric Multiple Dispatch with Variance*¶

Gyunghee Park§‡

Jaemin Hong§

Guy L. Steele Jr.‡

Sukyoung Ryu‡

§KAIST, Republic of Korea ‡Oracle Labs, USA *Proceedings of the 46th ACM SIGPLAN Symposium on Principles of Programming Languages (POPL '19) ¶This work has received funding from National Research Foundation of Korea (NRF) (Grants NRF-2017R1A2B3012020 and 2017M3C4A7068177)

/ 91!2

class Matrix

add(m: Matrix): Matrix = ...

end

class SparseMatrix extends Matrix

end

m: Matrix = Matrix()

sm: SparseMatrix = SparseMatrix()

m.add(sm)

/ 91!3

Method overloading

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

end

m: Matrix = Matrix()

sm: SparseMatrix = SparseMatrix()

m.add(sm)

Method dispatch

/ 91!4

Method overloading

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = Matrix()

sm: SparseMatrix = SparseMatrix()

sm.add(m)

Method dispatch

/ 91!5

Method overloading

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = Matrix()

sm: Matrix = SparseMatrix()

sm.add(m)

Method dispatch

/ 91!6

Method overloading

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = Matrix()

sm: Matrix = SparseMatrix()

sm.add(m)

Dynamic

Method dispatch

/ 91!7

Method overloading

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = Matrix()

sm: Matrix = SparseMatrix()

m.add(sm)

Method dispatch

/ 91!8

Method overloading

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = Matrix()

sm: Matrix = SparseMatrix()

m.add(sm)

Single

Method dispatch

/ 91!9

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = Matrix()

sm: Matrix = SparseMatrix()

m.add(sm)

Method overloading

Method dispatch

Single

/ 91!10

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = Matrix()

sm: Matrix = SparseMatrix()

m.add(sm)

Method overloading

The binary method problem

Method dispatch

Single

/ 91!11

Odersky et al., Programming in Scala (3rd Ed.), Artima

/ 91!12

Odersky et al., Programming in Scala (3rd Ed.), Artima

class Point(val x: Int, val y: Int) { override def equals(other: Any) = other match {

}

} class ColoredPoint(x: Int, y: Int, val color: Color.Value) extends Point(x, y) { override def equals(other: Any) = other match {

}

}

/ 91!13

class Point(val x: Int, val y: Int) { override def equals(other: Any) = other match { case that: Point => (that canEqual this) && (this.x == that.x) && (this.y == that.y) case _ => false } def canEqual(other: Any) = other.isInstanceOf[Point] } class ColoredPoint(x: Int, y: Int, val color: Color.Value) extends Point(x, y) { override def equals(other: Any) = other match { case that: ColoredPoint => (that canEqual this) && super.equals(that) && this.color == that.color case _ => false } override def canEqual(other: Any) = other.isInstanceOf[ColoredPoint] }

Odersky et al., Programming in Scala (3rd Ed.), Artima

/ 91!14

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = Matrix()

sm: Matrix = SparseMatrix()

m.add(sm)

Method dispatch

/ 91!15

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = Matrix()

sm: Matrix = SparseMatrix()

m.add(sm)

Multiple

Method dispatch

/ 91!16

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = Matrix()

sm: Matrix = SparseMatrix()

m.add(sm)

Multiple

Method dispatch

Symmetric

/ 91!17

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = Matrix()

sm: Matrix = SparseMatrix()

m.add(sm)

Multiple

Method dispatch

Symmetric

/ 91!18

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = Matrix()

sm: Matrix = SparseMatrix()

m.add(sm) Dynamic languages

Multiple

Method dispatch

Symmetric

/ 91!19

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = SparseMatrix()

sm: SparseMatrix = SparseMatrix()

sm.add(m)

Compile time

/ 91!20

Run time

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = SparseMatrix()

sm: SparseMatrix = SparseMatrix()

sm.add(m)

/ 91!21

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = SparseMatrix()

sm: SparseMatrix = SparseMatrix()

sm.add(m)

(Matrix, SparseMatrix)

(SparseMatrix, Matrix)

<:

<:

sm.add(m)

Run time

/ 91!22

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

m: Matrix = SparseMatrix()

sm: SparseMatrix = SparseMatrix()

sm.add(m) Ambiguous method calls

Run time

(Matrix, SparseMatrix)

(SparseMatrix, Matrix)

<:

<:

sm.add(m)

/ 91!23

Compile time

class Matrix

add(m: Matrix): SparseMatrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

numOfNonzeroEntries(): Int = ...

end

m: Matrix = Matrix()

sm: Matrix = SparseMatrix()

m.add(sm).numOfNonzeroEntries()

/ 91!24

Run time

class Matrix

add(m: Matrix): SparseMatrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

numOfNonzeroEntries(): Int = ...

end

m: Matrix = Matrix()

sm: Matrix = SparseMatrix()

m.add(sm).numOfNonzeroEntries()

/ 91!25

class Matrix

add(m: Matrix): SparseMatrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

numOfNonzeroEntries(): Int = ...

end

m: Matrix = Matrix()

sm: Matrix = SparseMatrix()

m.add(sm).numOfNonzeroEntries().numOfNonzeroEntries()

Matrix

Run time

/ 91!26

class Matrix

add(m: Matrix): SparseMatrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

numOfNonzeroEntries(): Int = ...

end

m: Matrix = Matrix()

sm: Matrix = SparseMatrix()

m.add(sm).numOfNonzeroEntries()

Broken type preservation

Run time

.numOfNonzeroEntries()

Matrix

/ 91!27

Compile time

Overloading rules

add(m: Matrix, m: Matrix): Matrix = ...

add(m: Matrix, m: SparseMatrix): Matrix = ...

add(m: SparseMatrix, m: SparseMatrix): SparseMatrix = ...

...

/ 91!28

add1

add2

add3

add4

adds

Run timeCompile time

Overloading rules

add(m: Matrix, m: Matrix): Matrix = ...

add(m: Matrix, m: SparseMatrix): Matrix = ...

add(m: SparseMatrix, m: SparseMatrix): SparseMatrix = ...

...

/ 91!29

add1

add2

add3

add4

<:

<:<:

(parameter type)

Unambiguity

adds

Run timeCompile time

Overloading rules

add(m: Matrix, m: Matrix): Matrix = ...

add(m: Matrix, m: SparseMatrix): Matrix = ...

add(m: SparseMatrix, m: SparseMatrix): SparseMatrix = ...

...

/ 91!30

Overloading rules

add1

add2

add3

add4

<:

<:<:

(parameter type)

Unambiguity

adds

<:

(return type)

Type Preservation

Run timeCompile time

add(m: Matrix, m: Matrix): Matrix = ...

add(m: Matrix, m: SparseMatrix): Matrix = ...

add(m: SparseMatrix, m: SparseMatrix): SparseMatrix = ...

...

/ 91!31

applicableSet(d) = {T : d is applicable to T}

Types2

applicableSet(d1)

(Matrix, Matrix)

(Matrix, SparseMatrix)

...

(Object, Object) (String, Matrix)

...

Allen et al., Type Checking Modular Multiple Dispatch with Parametric Polymorphism and Multiple Inheritance, OOPSLA '11

m1 :add(m: Matrix, m: Matrix): Matrix = ...d1 :

/ 91!32

d2 ⊑ d1 iff applicableSet(d2) ⊆ applicableSet(d1)

m1 :

applicableSet(d2)

(Matrix, Matrix)

(Matrix, SparseMatrix)

...

...

add(m: Matrix, m: Matrix): Matrix = ...

add(m: Matrix, m: SparseMatrix): Matrix = ...

is more specific than

d2 :

applicableSet(d1)

d1 :

Allen et al., Type Checking Modular Multiple Dispatch with Parametric Polymorphism and Multiple Inheritance, OOPSLA '11

/ 91!33

Overloading rules 1. No duplicates rule 2. Meet rule 3. Return type rule

add1

add2

add3

add4

Unambiguity

adds(return type)

Type Preservation

Run timeCompile time

add(m: Matrix, m: Matrix): Matrix = ...

add(m: Matrix, m: SparseMatrix): Matrix = ...

add(m: SparseMatrix, m: SparseMatrix): SparseMatrix = ...

...

⊑⊑

<:

Allen et al., Type Checking Modular Multiple Dispatch with Parametric Polymorphism and Multiple Inheritance, OOPSLA '11

/ 91!34

d1 = d2 ⇒ d1 = d2

No duplicates rule

/ 91!35

class Matrix

add(m: Matrix): Matrix = ...

add(m: Matrix): Matrix = ...

end

d1 = d2 ⇒ d1 = d2

No duplicates rule

/ 91!36

class Matrix

add(m: Matrix): Matrix = ...

end

d1 = d2 ⇒ d1 = d2

No duplicates rule

/ 91!37

d1

Meet rule

d3 d2

/ 91!38

class Matrix

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

end

d1

Meet rule

d3 d2

/ 91!39

class Matrix

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

d1

Meet rule

d3 d2

/ 91!40

Return type rule

⇒T2

d1

d2

T1

<:

Return types

/ 91!41

class Matrix

add(m: Matrix): SparseMatrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

endReturn type rule

⇒T2

d1

d2

T1

<:

Return types

/ 91!42

class Matrix

add(m: Matrix): Matrix = ...

add(m: SparseMatrix): Matrix = ...

end

class SparseMatrix extends Matrix

endReturn type rule

⇒T2

d1

d2

T1

<:

Return types

/ 91!43

add1

add2

add3

add4

adds(return type)

Type Preservation

Run timeCompile time

add(m: Matrix, m: Matrix): Matrix = ...

add(m: Matrix, m: SparseMatrix): Matrix = ...

add(m: SparseMatrix, m: SparseMatrix): SparseMatrix = ...

...

Unambiguity

⊑⊑

<:

⇒T2

d1

d2

T1

<:

Ret ur n t ypes

d1 d3 d2

d1 = d2 ⇒ d1 = d2

/ 91!44

class Array[T] end

makeArray[T](t: T): Array[T] = ...

i: Int = 1

makeArray(i)

Parametric polymorphism

/ 91!45

instances(d1) : makeArray(t: Object): Array[Object] = ...

makeArray(t: String): Array[String] = ...

makeArray(t: Number): Array[Number] = ...

makeArray(t: Int): Array[Int] = ...

...

d1 : makeArray[T](t: T): Array[T] = ...

Allen et al., Type Checking Modular Multiple Dispatch with Parametric Polymorphism and Multiple Inheritance, OOPSLA '11

/ 91!46

applicableSet(d) = {T : ∃D ∈ instances(d) . D is applicable to T}

Types = applicableSet(d1)

Object String

...

Number Int

d1 : makeArray[T](t: T): Array[T] = ...

Allen et al., Type Checking Modular Multiple Dispatch with Parametric Polymorphism and Multiple Inheritance, OOPSLA '11

/ 91!47

makeArray[T](t: T): Array[T] = ...

makeArray(i: Number): Array[Number] = ...d2 :

applicableSet(d2)

applicableSet(d1)Object String

...

Number Int...

d2 ⊑ d1 iff applicableSet(d2) ⊆ applicableSet(d1)is more specific than

d1 :

Allen et al., Type Checking Modular Multiple Dispatch with Parametric Polymorphism and Multiple Inheritance, OOPSLA '11

/ 91!48

d1

Meet rule

d3 d2d1 = d2 ⇒ d1 = d2

No duplicates rule

/ 91!49

class Array[T] end

makeArray[T](t: T): Array[T] = ...

makeArray(i: Number): Array[Number] = ...

Return type rule

⇒T2

d1

d2

T1

<:

Return types

/ 91!50

Return type rule

⇒T2

d1

d2

T1

<:

Return types

class Array[T] end

makeArray[T](t: T): Array[T] = ...

makeArray(i: Number): Array[Number] = ...

i: Object = 1

a: Array[Object] = makeArray(i)

a[0] = "1"

Compile time

/ 91!51

Return type rule

⇒T2

d1

d2

T1

<:

Return types

class Array[T] end

makeArray[T](t: T): Array[T] = ...

makeArray(i: Number): Array[Number] = ...

i: Object = 1

a: Array[Object] = makeArray(i)

a[0] = "1"

Run time

/ 91!52

class Array[T] end

makeArray[T](t: T): Array[T] = ...

makeArray(i: Number): Array[Number] = ...

Return type rule

⇒T2

d1

d2

T1

<:

Ret . types

T

∈App . to T

d1

d2

/ 91!53

class Array[T] end

makeArray[T](t: T): Array[T] = ...

makeArray(i: Number): Array[Number] = ...

⇒T2

T1

<:

Ret . types

T

∈App . to T

Int

Return type rule

d1

d2

d1

d2

/ 91!54

class Array[T] end

makeArray[T](t: T): Array[T] = ...

makeArray(i: Number): Array[Number] = ...

⇒T2

T1

<:

Ret . types

T

∈App . to T

Int

makeArray(i: Object): Array[Object] = ...

Return type rule

d1

d2

d1

d2

/ 91!55

class Array[T] end

makeArray[T](t: T): Array[T] = ...

makeArray(i: Number): Array[Number] = ...

⇒T2

T1

<:

Ret . types

T

∈App . to T

Int

makeArray(i: Object): Array[Object] = ...

Array[Object]

Return type rule

d1

d2

d1

d2

/ 91!56

class Array[T] end

makeArray[T](t: T): Array[T] = ...

makeArray(i: Number): Array[Number] = ...

⇒T2

T1

<:

Ret . types

T

∈App . to T

Int

makeArray(i: Object): Array[Object] = ...

Array[Object]

Return type rule

d1

d2

d1

d2

/ 91!57

class Array[T] end

makeArray[T](t: T): Array[T] = ...

makeArray(i: Number): Array[Number] = ...

⇒T2

T1

<:

Ret . types

T

∈App . to T

Int

makeArray(i: Object): Array[Object] = ...

makeArray(i: Number): Array[Number] = ...

Array[Object]

/∃

Return type rule

d1

d2

d1

d2

/ 91!58

⇒T2

T1

<:

Ret . types

T

∈App . to T

class Array[T] end

makeArray[T](t: T): Array[T] = ...

makeArray[T](i: Number): Array[T] = ...

Return type rule

d1

d2

d1

d2

/ 91!59

class Array[T] end

makeArray[T](t: T): Array[T] = ...

makeArray[T](i: Number): Array[T] = ...

⇒T2

T1

<:

Ret . types

T

∈App . to T

Int

makeArray(i: Object): Array[Object] = ...

makeArray[T](i: Number): Array[T] = ...

Array[Object]

makeArray(i: Number): Array[Object] = ...Return type rule

d1

d2

d1

d2

/ 91!60

d1

d2

d1

d2

Return type rule

class Array[T] end

makeArray[T](t: T): Array[T] = ...

makeArray[T](i: Number): Array[T] = ...

⇒T2

T1

<:

Ret . types

T

∈App . to T

Int

makeArray(i: Object): Array[Object] = ...

makeArray[T](i: Number): Array[T] = ...

Array[Object]

makeArray(i: Number): Array[Object] = ...

T

Object

A dynamic dispatch algorithmneeds statically determined return types

/ 91!61

add1

add2

add3

add4

adds: T(return type)

Type Preservation

Run timeCompile time

makeArray[T](t: T): Array[T] = ...

makeArray(t: Number): Array[Number] = ...

makeArray[T](i: Number): Array[T] = ...

...

Unambiguity

⊑⊑

<:

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

∈App . to T

d1

d2

d1

d2

/ 91!62

FGFV Calculus

/ 91!63

FGFV CalculusMultiple inheritance

/ 91!64

FGFV CalculusMultiple inheritance

Parametric polymorphism

/ 91!65

FGFV CalculusMultiple inheritance

Parametric polymorphismVariance

/ 91!66

FGFV CalculusMultiple inheritance

Parametric polymorphismVariance

class A[+T] end

class A[=T] end

class A[-T] end

A[T] <: A[S] iff T <: S

A[T] <: A[S] iff T ≡ S

A[T] <: A[S] iff T :> S

/ 91!67

d1 : add(m: Matrix, m: Matrix): Matrix = ...

makeArray[T](t: T): Array[T] = ...d2 :

dom(d1) = ∃[](Matrix, Matrix)dom(d2) = ∃[T <: Object](T)

arrow(d1) = ∀[](Matrix, Matrix) → Matrixarrow(d2) = ∀[T <: Object](T) → Array[T]

/ 91!68

d1 = d2 ⇒ d1 = d2

No duplicates rule

/ 91!69

d1

Meet rule

d3 d2

/ 91!70

⇒T2

T1

<:

Ret . types

T

∈App . to T

Return type rule

d1

d2

d1

d2

/ 91!71

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

d2

d5

d1

d4

d6 d7

⊑ ⊑

⊑ ⊑ ⊑d3

m(e)

/ 91!72

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

d2

d5

d1

d4

d6 d7

⊑ ⊑

⊑ ⊑ ⊑d3

m(e)

/ 91!73

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

d2

d5

d1

d4

d6 d7

⊑ ⊑

⊑ ⊑ ⊑d3

m(e)

d2 d5d1 d4 d6 d7d3

/ 91!74

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

d2

d5

d1

d4

d6 d7

⊑ ⊑

⊑ ⊑ ⊑d3

m(e)

d2 d5d1 d4 d6 d7d3

m(a): Tr

/ 91!75

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

d2

d5

d1

d4

d6 d7

⊑ ⊑

⊑ ⊑ ⊑d3

m(e)

d2 d5d1 d4 d6 d7d3

m(v): Tr

Ta

Dispatch

Match

MatchSolve

:

<:

<:

/ 91!76

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

d2

d5

d1

d4

d6 d7

⊑ ⊑

⊑ ⊑ ⊑d3

m(e)

d2 d5d1 d4 d6 d7d3

m(v): Tr

Ta

Dispatch

Match

Match

m[P](Sa): Sr Solve

:

<:

<:

/ 91!77

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

d2

d5

d1

d4

d6 d7

⊑ ⊑

⊑ ⊑ ⊑d3

m(e)

d2 d5d1 d4 d6 d7d3

m(v): Tr

Ta

Dispatch

Match

Match

m[P](Sa): Sr Solve

:

<:

<:

/ 91!78

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

d2

d5

d1

d4

d6 d7

⊑ ⊑

⊑ ⊑ ⊑d3

m(e)

d2 d5d1 d4 d6 d7d3

m(v): Tr

Ta

Dispatch

Match

Match

m[P](Sa): Sr Solve

:

<:

<:

/ 91!79

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

d2

d5

d1

d4

d6 d7

⊑ ⊑

⊑ ⊑ ⊑d3

m(e)

d2 d5d1 d4 d6 d7d3

m(v): Tr

Ta

Dispatch

Match

Match

m[P](Sa): Sr Solve

:

<:

<:

/ 91!80

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

d2

d5

d1

d4

d6 d7

⊑ ⊑

⊑ ⊑ ⊑d3

m(e)

d2 d5d1 d4 d6 d7d3

m(v): Tr

Ta

Dispatch

Match

Match

m[P](Sa): Sr Solve

:

<:

<:

P=T

[T/P] d1

/ 91!81

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

d2

d5

d1

d4

d6 d7

⊑ ⊑

⊑ ⊑ ⊑d3

m(e)

d2 d5d1 d4 d6 d7d3

m(v): Tr

Ta

Dispatch

Match

Match

m[P](Sa): Sr Solve

:

<:

<:

/ 91!82

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

makeArray(i)

makeArray[T](t: T): Array[T] = ...

makeArray[T](i: Number): Array[T] = ...

makeArray[T](i: Number): Array[T] makeArray[T](t: T): Array[T]

/ 91!83

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

d2 d5d1 d4 d6 d7d3

makeArray(i): Array[Object]makeArray(i)

makeArray[T](t: T): Array[T] = ...

makeArray[T](i: Number): Array[T] = ...

makeArray[T](i: Number): Array[T] makeArray[T](t: T): Array[T]

/ 91!84

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

d2 d5d1 d4 d6 d7d3

makeArray(1): Array[Object]makeArray(i)

makeArray[T](t: T): Array[T] = ...

makeArray[T](i: Number): Array[T] = ...

makeArray[T](i: Number): Array[T] makeArray[T](t: T): Array[T]

Int

:

/ 91!85

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

Dispatch

Match

Match

[T](Number): Array[T]Solve

<:

<:

d4d3

makeArray(1): Array[Object]makeArray(i)

makeArray[T](t: T): Array[T] = ...

makeArray[T](i: Number): Array[T] = ...

makeArray[T](i: Number): Array[T] makeArray[T](t: T): Array[T]

Int

:

/ 91!86

[T](Number): Array[T]

d4d3

makeArray(1): Array[Object]makeArray(i)

makeArray[T](t: T): Array[T] = ...

makeArray[T](i: Number): Array[T] = ...

makeArray[T](i: Number): Array[T] makeArray[T](t: T): Array[T]

Int

:

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

Dispatch

Match

MatchSolve

<:

<:

{}

/ 91!87

[T](Number): Array[T]

d4d3

makeArray(1): Array[Object]makeArray(i)

makeArray[T](t: T): Array[T] = ...

makeArray[T](i: Number): Array[T] = ...

makeArray[T](i: Number): Array[T] makeArray[T](t: T): Array[T]

Int

:

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

Dispatch

Match

MatchSolve

<:

<:

{}

{T=Object}

/ 91!88

[T](Number): Array[T]

d4d3

makeArray(1): Array[Object]makeArray(i)

makeArray[T](t: T): Array[T] = ...

makeArray[T](i: Number): Array[T] = ...

makeArray[T](i: Number): Array[T] makeArray[T](t: T): Array[T]

Int

:

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

Dispatch

Match

MatchSolve

<:

<:

{}

{T=Object}

{}

/ 91!89

[T](Number): Array[T]

d4d3

makeArray(1): Array[Object]makeArray(i)

makeArray[T](t: T): Array[T] = ...

makeArray[T](i: Number): Array[T] = ...

makeArray[T](i: Number): Array[T] makeArray[T](t: T): Array[T]

Int

:

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

Dispatch

Match

MatchSolve

<:

<:

{}

{T=Object}

{}

T=Object

/ 91!90

TheoremA well-formed program never results in an ambiguous method call.

TheoremA well-formed program never results in a type error.

/ 91!91

Run timeCompile time

d1 d3 d2

d1 = d2 ⇒ d1 = d2

⇒T2

T1

<:

Ret . t ypes

T

App . to T

d1

d2

d1

d2

d2

d5

d1

d4

d6 d7

⊑ ⊑

⊑ ⊑ ⊑d3

m(e)

d2 d5d1 d4 d6 d7d3

m(v): Tr

Ta

Dispatch

Match

Match

m[P](Sa): Sr Solve

:

<:

<:

P=T

[T/P] d1