CS345H: Programming Languages

Lecture 13: Type Inference II

Thomas Dillig

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 1/34 I Goal: Take what we studied and apply it to a project you design yourself

I This is a team project: Teams must be between 3 and 5 students

First: Your Project

I Today is the start of your course project

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 2/34 I This is a team project: Teams must be between 3 and 5 students

First: Your Project

I Today is the start of your course project

I Goal: Take what we studied and apply it to a project you design yourself

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 2/34 First: Your Project

I Today is the start of your course project

I Goal: Take what we studied and apply it to a project you design yourself

I This is a team project: Teams must be between 3 and 5 students

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 2/34 I Adding type inference to L

I Speeding up the L interpreter

I Adding major language features to L

I Type inference with novel error reporting

I ...

I Some possible examples:

I Your creativity is the limit

Possible Topics

I Your goal is to add at least one major feature to the L language

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 3/34 I Adding type inference to L

I Speeding up the L interpreter

I Adding major language features to L

I Type inference with novel error reporting

I ...

I Your creativity is the limit

Possible Topics

I Your goal is to add at least one major feature to the L language

I Some possible examples:

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 3/34 I Speeding up the L interpreter

I Adding major language features to L

I Type inference with novel error reporting

I ...

I Your creativity is the limit

Possible Topics

I Your goal is to add at least one major feature to the L language

I Some possible examples:

I Adding type inference to L

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 3/34 I Adding major language features to L

I Type inference with novel error reporting

I ...

I Your creativity is the limit

Possible Topics

I Your goal is to add at least one major feature to the L language

I Some possible examples:

I Adding type inference to L

I Speeding up the L interpreter

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 3/34 I Type inference with novel error reporting

I ...

I Your creativity is the limit

Possible Topics

I Your goal is to add at least one major feature to the L language

I Some possible examples:

I Adding type inference to L

I Speeding up the L interpreter

I Adding major language features to L

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 3/34 I ...

I Your creativity is the limit

Possible Topics

I Your goal is to add at least one major feature to the L language

I Some possible examples:

I Adding type inference to L

I Speeding up the L interpreter

I Adding major language features to L

I Type inference with novel error reporting

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 3/34 I Your creativity is the limit

Possible Topics

I Your goal is to add at least one major feature to the L language

I Some possible examples:

I Adding type inference to L

I Speeding up the L interpreter

I Adding major language features to L

I Type inference with novel error reporting

I ...

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 3/34 Possible Topics

I Your goal is to add at least one major feature to the L language

I Some possible examples:

I Adding type inference to L

I Speeding up the L interpreter

I Adding major language features to L

I Type inference with novel error reporting

I ...

I Your creativity is the limit

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 3/34 I Nov. 13st 12:30pm: Email me a one page proposal for your project as pdf clearly describing what you want to do and list your team members

I Will receive feedback from proposal

I Dec. 11st 12:30pm : Project due. No late days.

Deliverables & Time line

I Today: Start of project, form teams

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 4/34 I Will receive feedback from proposal

I Dec. 11st 12:30pm : Project due. No late days.

Deliverables & Time line

I Today: Start of project, form teams

I Nov. 13st 12:30pm: Email me a one page proposal for your project as pdf clearly describing what you want to do and list your team members

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 4/34 I Dec. 11st 12:30pm : Project due. No late days.

Deliverables & Time line

I Today: Start of project, form teams

I Nov. 13st 12:30pm: Email me a one page proposal for your project as pdf clearly describing what you want to do and list your team members

I Will receive feedback from proposal

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 4/34 Deliverables & Time line

I Today: Start of project, form teams

I Nov. 13st 12:30pm: Email me a one page proposal for your project as pdf clearly describing what you want to do and list your team members

I Will receive feedback from proposal

I Dec. 11st 12:30pm : Project due. No late days.

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 4/34 I All your source code in a tar.gz file compiling on Ubuntu

I You will be graded on size of chosen challenge, your solution and your written report

I Since every project is unique, you will get lots of feedback throughout

I If you are passionate about a PL project not related to L, or want to tackle something especially large with more people, etc: Ask!

I Any questions?

Final Deliverables

I Report written in LateX (at least 15 pages) describing clearly what problem you are solving, what choices you made, challenges encountered and your results.

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 5/34 I You will be graded on size of chosen challenge, your solution and your written report

I Since every project is unique, you will get lots of feedback throughout

I If you are passionate about a PL project not related to L, or want to tackle something especially large with more people, etc: Ask!

I Any questions?

Final Deliverables

I Report written in LateX (at least 15 pages) describing clearly what problem you are solving, what choices you made, challenges encountered and your results.

I All your source code in a tar.gz file compiling on Ubuntu

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 5/34 I Since every project is unique, you will get lots of feedback throughout

I If you are passionate about a PL project not related to L, or want to tackle something especially large with more people, etc: Ask!

I Any questions?

Final Deliverables

I Report written in LateX (at least 15 pages) describing clearly what problem you are solving, what choices you made, challenges encountered and your results.

I All your source code in a tar.gz file compiling on Ubuntu

I You will be graded on size of chosen challenge, your solution and your written report

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 5/34 I If you are passionate about a PL project not related to L, or want to tackle something especially large with more people, etc: Ask!

I Any questions?

Final Deliverables

I Report written in LateX (at least 15 pages) describing clearly what problem you are solving, what choices you made, challenges encountered and your results.

I All your source code in a tar.gz file compiling on Ubuntu

I You will be graded on size of chosen challenge, your solution and your written report

I Since every project is unique, you will get lots of feedback throughout

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 5/34 I Any questions?

Final Deliverables

I Report written in LateX (at least 15 pages) describing clearly what problem you are solving, what choices you made, challenges encountered and your results.

I All your source code in a tar.gz file compiling on Ubuntu

I You will be graded on size of chosen challenge, your solution and your written report

I Since every project is unique, you will get lots of feedback throughout

I If you are passionate about a PL project not related to L, or want to tackle something especially large with more people, etc: Ask!

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 5/34 Final Deliverables

I Report written in LateX (at least 15 pages) describing clearly what problem you are solving, what choices you made, challenges encountered and your results.

I All your source code in a tar.gz file compiling on Ubuntu

I You will be graded on size of chosen challenge, your solution and your written report

I Since every project is unique, you will get lots of feedback throughout

I If you are passionate about a PL project not related to L, or want to tackle something especially large with more people, etc: Ask!

I Any questions?

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 5/34 I Big idea: Replace all concrete type assumptions with type variables

I Collect constraints on these type variables

I Find most general solution for these constraints to deduce types

Introduction

I Recall for last time: We are inferring types

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 6/34 I Collect constraints on these type variables

I Find most general solution for these constraints to deduce types

Introduction

I Recall for last time: We are inferring types

I Big idea: Replace all concrete type assumptions with type variables

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 6/34 I Find most general solution for these constraints to deduce types

Introduction

I Recall for last time: We are inferring types

I Big idea: Replace all concrete type assumptions with type variables

I Collect constraints on these type variables

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 6/34 Introduction

I Recall for last time: We are inferring types

I Big idea: Replace all concrete type assumptions with type variables

I Collect constraints on these type variables

I Find most general solution for these constraints to deduce types

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 6/34 I Type derivation:

Γ[f ← a1][x ← a2] ` f : a1 Γ[f ← a1][x ← a2] ` x : a2 a1 = a2 → a3 Γ[f ← a1][x ← a2] ` (f x): a3 Γ[f ← a1]f `: a1 Γ[f ← a1] ` λx.(f x): a1 Γ ` let f = λx.(f x) in f : a1

I Final Type: a1 under constraint a1 = a2 → a3

I This yielded constraint system

a1 = a2 → a3 a1

Quick Refresher

I Lets quickly look again at one example: let f = lambda x.(f x) in f

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 7/34 I Final Type: a1 under constraint a1 = a2 → a3

I This yielded constraint system

a1 = a2 → a3 a1

Quick Refresher

I Lets quickly look again at one example: let f = lambda x.(f x) in f

I Type derivation:

Γ[f ← a1][x ← a2] ` f : a1 Γ[f ← a1][x ← a2] ` x : a2 a1 = a2 → a3 Γ[f ← a1][x ← a2] ` (f x): a3 Γ[f ← a1]f `: a1 Γ[f ← a1] ` λx.(f x): a1 Γ ` let f = λx.(f x) in f : a1

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 7/34 I This yielded constraint system

a1 = a2 → a3 a1

Quick Refresher

I Lets quickly look again at one example: let f = lambda x.(f x) in f

I Type derivation:

Γ[f ← a1][x ← a2] ` f : a1 Γ[f ← a1][x ← a2] ` x : a2 a1 = a2 → a3 Γ[f ← a1][x ← a2] ` (f x): a3 Γ[f ← a1]f `: a1 Γ[f ← a1] ` λx.(f x): a1 Γ ` let f = λx.(f x) in f : a1

I Final Type: a1 under constraint a1 = a2 → a3

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 7/34 Quick Refresher

I Lets quickly look again at one example: let f = lambda x.(f x) in f

I Type derivation:

Γ[f ← a1][x ← a2] ` f : a1 Γ[f ← a1][x ← a2] ` x : a2 a1 = a2 → a3 Γ[f ← a1][x ← a2] ` (f x): a3 Γ[f ← a1]f `: a1 Γ[f ← a1] ` λx.(f x): a1 Γ ` let f = λx.(f x) in f : a1

I Final Type: a1 under constraint a1 = a2 → a3

I This yielded constraint system

a1 = a2 → a3 a1

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 7/34 I However, the cost of this is quadratic in the number of constraints

I For a large program, this is prohibitive

I Today: How to efficiently solve type constraint systems

Solving Constraints

I Last time, we discussed two substitution rules that allow us to solve such constraints and find the most general solution

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 8/34 I For a large program, this is prohibitive

I Today: How to efficiently solve type constraint systems

Solving Constraints

I Last time, we discussed two substitution rules that allow us to solve such constraints and find the most general solution

I However, the cost of this is quadratic in the number of constraints

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 8/34 I Today: How to efficiently solve type constraint systems

Solving Constraints

I Last time, we discussed two substitution rules that allow us to solve such constraints and find the most general solution

I However, the cost of this is quadratic in the number of constraints

I For a large program, this is prohibitive

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 8/34 Solving Constraints

I Last time, we discussed two substitution rules that allow us to solve such constraints and find the most general solution

I However, the cost of this is quadratic in the number of constraints

I For a large program, this is prohibitive

I Today: How to efficiently solve type constraint systems

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 8/34 Int, String

α1, α2

X → Y

1. Type constants:

2. Type variables:

3. Function Types:

I Observe that X → Y is just in-fix notation for function(X , Y )

I To solve type constraints more efficiently, we will write X → Y also as function(X , Y ), but this is just notation

Representing Types

I Our type constraint systems are made up of the following three primitives:

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 9/34 α1, α2

X → Y

Int, String

2. Type variables:

3. Function Types:

I Observe that X → Y is just in-fix notation for function(X , Y )

I To solve type constraints more efficiently, we will write X → Y also as function(X , Y ), but this is just notation

Representing Types

I Our type constraint systems are made up of the following three primitives: 1. Type constants:

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 9/34 α1, α2

X → Y

2. Type variables:

3. Function Types:

I Observe that X → Y is just in-fix notation for function(X , Y )

I To solve type constraints more efficiently, we will write X → Y also as function(X , Y ), but this is just notation

Representing Types

I Our type constraint systems are made up of the following three primitives: 1. Type constants: Int, String

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 9/34 X → Y

α1, α2

3. Function Types:

I Observe that X → Y is just in-fix notation for function(X , Y )

I To solve type constraints more efficiently, we will write X → Y also as function(X , Y ), but this is just notation

Representing Types

I Our type constraint systems are made up of the following three primitives: 1. Type constants: Int, String

2. Type variables:

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 9/34 X → Y

3. Function Types:

I Observe that X → Y is just in-fix notation for function(X , Y )

I To solve type constraints more efficiently, we will write X → Y also as function(X , Y ), but this is just notation

Representing Types

I Our type constraint systems are made up of the following three primitives: 1. Type constants: Int, String

2. Type variables: α1, α2

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 9/34 X → Y

I Observe that X → Y is just in-fix notation for function(X , Y )

I To solve type constraints more efficiently, we will write X → Y also as function(X , Y ), but this is just notation

Representing Types

I Our type constraint systems are made up of the following three primitives: 1. Type constants: Int, String

2. Type variables: α1, α2

3. Function Types:

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 9/34 I Observe that X → Y is just in-fix notation for function(X , Y )

I To solve type constraints more efficiently, we will write X → Y also as function(X , Y ), but this is just notation

Representing Types

I Our type constraint systems are made up of the following three primitives: 1. Type constants: Int, String

2. Type variables: α1, α2

3. Function Types: X → Y

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 9/34 I To solve type constraints more efficiently, we will write X → Y also as function(X , Y ), but this is just notation

Representing Types

I Our type constraint systems are made up of the following three primitives: 1. Type constants: Int, String

2. Type variables: α1, α2

3. Function Types: X → Y

I Observe that X → Y is just in-fix notation for function(X , Y )

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 9/34 Representing Types

I Our type constraint systems are made up of the following three primitives: 1. Type constants: Int, String

2. Type variables: α1, α2

3. Function Types: X → Y

I Observe that X → Y is just in-fix notation for function(X , Y )

I To solve type constraints more efficiently, we will write X → Y also as function(X , Y ), but this is just notation

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 9/34 I Equivalence Class: Set of types that must be equal

I Specifically, if we process constraint of the form X = Y , we know that X and Y are equal

I In this case, we want to union the equivalence classes of X and Y

I Also, if X and Y are function types of the form X1 → X2 and Y1 → Y2, we also want to union X1 and Y1 as well as X2 and Y2

More Efficient Type Inference

I Big Idea: Maintain equivalence classes of types directly

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 10/34 I Specifically, if we process constraint of the form X = Y , we know that X and Y are equal

I In this case, we want to union the equivalence classes of X and Y

I Also, if X and Y are function types of the form X1 → X2 and Y1 → Y2, we also want to union X1 and Y1 as well as X2 and Y2

More Efficient Type Inference

I Big Idea: Maintain equivalence classes of types directly

I Equivalence Class: Set of types that must be equal

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 10/34 I In this case, we want to union the equivalence classes of X and Y

I Also, if X and Y are function types of the form X1 → X2 and Y1 → Y2, we also want to union X1 and Y1 as well as X2 and Y2

More Efficient Type Inference

I Big Idea: Maintain equivalence classes of types directly

I Equivalence Class: Set of types that must be equal

I Specifically, if we process constraint of the form X = Y , we know that X and Y are equal

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 10/34 I Also, if X and Y are function types of the form X1 → X2 and Y1 → Y2, we also want to union X1 and Y1 as well as X2 and Y2

More Efficient Type Inference

I Big Idea: Maintain equivalence classes of types directly

I Equivalence Class: Set of types that must be equal

I Specifically, if we process constraint of the form X = Y , we know that X and Y are equal

I In this case, we want to union the equivalence classes of X and Y

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 10/34 More Efficient Type Inference

I Big Idea: Maintain equivalence classes of types directly

I Equivalence Class: Set of types that must be equal

I Specifically, if we process constraint of the form X = Y , we know that X and Y are equal

I In this case, we want to union the equivalence classes of X and Y

I Also, if X and Y are function types of the form X1 → X2 and Y1 → Y2, we also want to union X1 and Y1 as well as X2 and Y2

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 10/34 I Each set of types is called an equivalence class

I Each set has one element as its representative

I For type inference: If an equivalence contains a type constant or a , we will always use this type as the representative.

Union-Find

I To maintain equivalence classes directly, we will use the union-find algorithm

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 11/34 I Each set has one element as its representative

I For type inference: If an equivalence contains a type constant or a function type, we will always use this type as the representative.

Union-Find

I To maintain equivalence classes directly, we will use the union-find algorithm

I Each set of types is called an equivalence class

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 11/34 I For type inference: If an equivalence contains a type constant or a function type, we will always use this type as the representative.

Union-Find

I To maintain equivalence classes directly, we will use the union-find algorithm

I Each set of types is called an equivalence class

I Each set has one element as its representative

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 11/34 Union-Find

I To maintain equivalence classes directly, we will use the union-find algorithm

I Each set of types is called an equivalence class

I Each set has one element as its representative

I For type inference: If an equivalence contains a type constant or a function type, we will always use this type as the representative.

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 11/34 results in new equivalence class {int, α, β → γ}

int

1. Union(s, t): This unions the equivalence classes of s and t into one equivalence class

2. Find(s): This returns the representative of the equivalence class of which s is part of

I Example: Assume following two equivalence classes (representatives in red): {int, α}, {β → γ, int}

I Example: Union(int, β → γ)

I Example: Find(α) =

Union-Find Cont.

I In Union-Find, we have only two operations on equivalence classes:

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 12/34 results in new equivalence class {int, α, β → γ}

int

2. Find(s): This returns the representative of the equivalence class of which s is part of

I Example: Assume following two equivalence classes (representatives in red): {int, α}, {β → γ, int}

I Example: Union(int, β → γ)

I Example: Find(α) =

Union-Find Cont.

I In Union-Find, we have only two operations on equivalence classes: 1. Union(s, t): This unions the equivalence classes of s and t into one equivalence class

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 12/34 results in new equivalence class {int, α, β → γ}

int

I Example: Assume following two equivalence classes (representatives in red): {int, α}, {β → γ, int}

I Example: Union(int, β → γ)

I Example: Find(α) =

Union-Find Cont.

I In Union-Find, we have only two operations on equivalence classes: 1. Union(s, t): This unions the equivalence classes of s and t into one equivalence class

2. Find(s): This returns the representative of the equivalence class of which s is part of

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 12/34 results in new equivalence class {int, α, β → γ}

int

I Example: Union(int, β → γ)

I Example: Find(α) =

Union-Find Cont.

I In Union-Find, we have only two operations on equivalence classes: 1. Union(s, t): This unions the equivalence classes of s and t into one equivalence class

2. Find(s): This returns the representative of the equivalence class of which s is part of

I Example: Assume following two equivalence classes (representatives in red): {int, α}, {β → γ, int}

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 12/34 int

results in new equivalence class {int, α, β → γ}

I Example: Find(α) =

Union-Find Cont.

I In Union-Find, we have only two operations on equivalence classes: 1. Union(s, t): This unions the equivalence classes of s and t into one equivalence class

2. Find(s): This returns the representative of the equivalence class of which s is part of

I Example: Assume following two equivalence classes (representatives in red): {int, α}, {β → γ, int}

I Example: Union(int, β → γ)

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 12/34 int

I Example: Find(α) =

Union-Find Cont.

I In Union-Find, we have only two operations on equivalence classes: 1. Union(s, t): This unions the equivalence classes of s and t into one equivalence class

2. Find(s): This returns the representative of the equivalence class of which s is part of

I Example: Assume following two equivalence classes (representatives in red): {int, α}, {β → γ, int}

I Example: Union(int, β → γ) results in new equivalence class {int, α, β → γ}

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 12/34 int

Union-Find Cont.

I In Union-Find, we have only two operations on equivalence classes: 1. Union(s, t): This unions the equivalence classes of s and t into one equivalence class

2. Find(s): This returns the representative of the equivalence class of which s is part of

I Example: Assume following two equivalence classes (representatives in red): {int, α}, {β → γ, int}

I Example: Union(int, β → γ) results in new equivalence class {int, α, β → γ}

I Example: Find(α) =

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 12/34 Union-Find Cont.

I In Union-Find, we have only two operations on equivalence classes: 1. Union(s, t): This unions the equivalence classes of s and t into one equivalence class

2. Find(s): This returns the representative of the equivalence class of which s is part of

I Example: Assume following two equivalence classes (representatives in red): {int, α}, {β → γ, int}

I Example: Union(int, β → γ) results in new equivalence class {int, α, β → γ}

I Example: Find(α) = int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 12/34 I Example: {β → γ,α}

I Conceptually, union will join the dotted areas of two equivalence classes

I And find will return the (red) representative in this class

Union-Find Representation

I We will represent equivalence classes as DAGs.

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 13/34 I Conceptually, union will join the dotted areas of two equivalence classes

I And find will return the (red) representative in this class

Union-Find Representation

I We will represent equivalence classes as DAGs.

I Example: {β → γ,α}

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 13/34 I Conceptually, union will join the dotted areas of two equivalence classes

I And find will return the (red) representative in this class

Union-Find Representation

I We will represent equivalence classes as DAGs.

I Example: {β → γ,α}

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 13/34 I And find will return the (red) representative in this class

Union-Find Representation

I We will represent equivalence classes as DAGs.

I Example: {β → γ,α}

I Conceptually, union will join the dotted areas of two equivalence classes

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 13/34 Union-Find Representation

I We will represent equivalence classes as DAGs.

I Example: {β → γ,α}

I Conceptually, union will join the dotted areas of two equivalence classes

I And find will return the (red) representative in this class

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 13/34 int

int

I And now consider union(β → γ, int)

Union-Find Representation Cont.

I Consider the following EQs:

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 14/34 int

I And now consider union(β → γ, int)

Union-Find Representation Cont.

I Consider the following EQs:

int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 14/34 int

Union-Find Representation Cont.

I Consider the following EQs:

int

I And now consider union(β → γ, int)

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 14/34 Union-Find Representation Cont.

I Consider the following EQs:

int

I And now consider union(β → γ, int) int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 14/34 I No! If a function type and a constant type ever end up in the same equivalence class, we know that the constraint system has no solution

I We also know constraint system has no solution if Int and String end up in the same EQ

Union-Find Representation

int

I Question: Is this a possible solution for the type constraints?

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 15/34 I We also know constraint system has no solution if Int and String end up in the same EQ

Union-Find Representation

int

I Question: Is this a possible solution for the type constraints?

I No! If a function type and a constant type ever end up in the same equivalence class, we know that the constraint system has no solution

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 15/34 Union-Find Representation

int

I Question: Is this a possible solution for the type constraints?

I No! If a function type and a constant type ever end up in the same equivalence class, we know that the constraint system has no solution

I We also know constraint system has no solution if Int and String end up in the same EQ

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 15/34 I For each type variable v, simply return find(v)

I In other words, the representative of each equivalence class is the most general solution

I Question: Why do we always pick function types or type constants as representatives?

I Question: What happens if a function type and a type constant are in the same equivalence class?

Finding a Solution from the Union-Find DAG

I Assuming we end up with an consistent Union-find DAG, we can read the most general solution right of!

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 16/34 I In other words, the representative of each equivalence class is the most general solution

I Question: Why do we always pick function types or type constants as representatives?

I Question: What happens if a function type and a type constant are in the same equivalence class?

Finding a Solution from the Union-Find DAG

I Assuming we end up with an consistent Union-find DAG, we can read the most general solution right of!

I For each type variable v, simply return find(v)

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 16/34 I Question: Why do we always pick function types or type constants as representatives?

I Question: What happens if a function type and a type constant are in the same equivalence class?

Finding a Solution from the Union-Find DAG

I Assuming we end up with an consistent Union-find DAG, we can read the most general solution right of!

I For each type variable v, simply return find(v)

I In other words, the representative of each equivalence class is the most general solution

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 16/34 I Question: What happens if a function type and a type constant are in the same equivalence class?

Finding a Solution from the Union-Find DAG

I Assuming we end up with an consistent Union-find DAG, we can read the most general solution right of!

I For each type variable v, simply return find(v)

I In other words, the representative of each equivalence class is the most general solution

I Question: Why do we always pick function types or type constants as representatives?

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 16/34 Finding a Solution from the Union-Find DAG

I Assuming we end up with an consistent Union-find DAG, we can read the most general solution right of!

I For each type variable v, simply return find(v)

I In other words, the representative of each equivalence class is the most general solution

I Question: Why do we always pick function types or type constants as representatives?

I Question: What happens if a function type and a type constant are in the same equivalence class?

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 16/34 β → γ

I How do we find solution for α?

I find(α) =

I What about β?

I Every item is in its own EQ, therefore find(β) = β

Finding a Solution from the Union-Find DAG

I Example:

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 17/34 β → γ

I find(α) =

I What about β?

I Every item is in its own EQ, therefore find(β) = β

Finding a Solution from the Union-Find DAG

I Example:

I How do we find solution for α?

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 17/34 β → γ

I What about β?

I Every item is in its own EQ, therefore find(β) = β

Finding a Solution from the Union-Find DAG

I Example:

I How do we find solution for α?

I find(α) =

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 17/34 I What about β?

I Every item is in its own EQ, therefore find(β) = β

Finding a Solution from the Union-Find DAG

I Example:

I How do we find solution for α?

I find(α) = β → γ

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 17/34 I Every item is in its own EQ, therefore find(β) = β

Finding a Solution from the Union-Find DAG

I Example:

I How do we find solution for α?

I find(α) = β → γ

I What about β?

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 17/34 Finding a Solution from the Union-Find DAG

I Example:

I How do we find solution for α?

I find(α) = β → γ

I What about β?

I Every item is in its own EQ, therefore find(β) = β

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 17/34 I We then apply the following function to each equality in our type constraint: bool unify(m, n) { s = find(m); t = find(n); if(s == t) return true; if(s == s1 → s2 && t == t1 → t2) { union(s, t); return unify(s1, t1) && unify(s2, t2); } if(is_variable(s) || is_variable(t)) { union(s, t); return true; } return false; //No solution to type constraints }

Using Union-Find for solving Type Inference Constraints

I Initially, all type variables, functions and type constants are in their own equivalence class

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 18/34 Using Union-Find for solving Type Inference Constraints

I Initially, all type variables, functions and type constants are in their own equivalence class

I We then apply the following function to each equality in our type constraint: bool unify(m, n) { s = find(m); t = find(n); if(s == t) return true; if(s == s1 → s2 && t == t1 → t2) { union(s, t); return unify(s1, t1) && unify(s2, t2); } if(is_variable(s) || is_variable(t)) { union(s, t); return true; } return false; //No solution to type constraints } Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 18/34 int

Example

I Consider the following system of type constraints:

α → Int = β γ → Int = β γ = String

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 19/34 Example

I Consider the following system of type constraints:

α → Int = β γ → Int = β γ = String

int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 19/34 Example

I Consider the following system of type constraints:

α → Int = β γ → Int = β γ = String

int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 19/34 Example

I Consider the following system of type constraints:

α → Int = β γ → Int = β γ = String

int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 19/34 Example

I Consider the following system of type constraints:

α → Int = β γ → Int = β γ = String

int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 19/34 Example

I Consider the following system of type constraints:

α → Int = β γ → Int = β γ = String

int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 19/34 Example

I Consider the following system of type constraints:

α → Int = β γ → Int = β γ = String

int String

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 19/34 Example

I Consider the following system of type constraints:

α → Int = β γ → Int = β γ = String

int String

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 19/34 String → Int

String

String

find(β) =

find(γ) =

find(α) =

I Solution for β:

I Solution for γ:

Example Cont

α → Int = β γ → Int = β γ = String

int String

I Solution for α:

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 20/34 String → Int

String

find(β) =

find(γ) =

String

I Solution for β:

I Solution for γ:

Example Cont

α → Int = β γ → Int = β γ = String

int String

I Solution for α: find(α) =

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 20/34 String → Int

String

find(β) =

find(γ) =

I Solution for β:

I Solution for γ:

Example Cont

α → Int = β γ → Int = β γ = String

int String

I Solution for α: find(α) = String

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 20/34 String

String → Int

find(γ) =

find(β) =

I Solution for γ:

Example Cont

α → Int = β γ → Int = β γ = String

int String

I Solution for α: find(α) = String

I Solution for β:

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 20/34 String

find(γ) =

String → Int

I Solution for γ:

Example Cont

α → Int = β γ → Int = β γ = String

int String

I Solution for α: find(α) = String

I Solution for β: find(β) =

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 20/34 String

find(γ) =

I Solution for γ:

Example Cont

α → Int = β γ → Int = β γ = String

int String

I Solution for α: find(α) = String

I Solution for β: find(β) = String → Int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 20/34 String

find(γ) =

Example Cont

α → Int = β γ → Int = β γ = String

int String

I Solution for α: find(α) = String

I Solution for β: find(β) = String → Int

I Solution for γ:

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 20/34 String

Example Cont

α → Int = β γ → Int = β γ = String

int String

I Solution for α: find(α) = String

I Solution for β: find(β) = String → Int

I Solution for γ: find(γ) =

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 20/34 Example Cont

α → Int = β γ → Int = β γ = String

int String

I Solution for α: find(α) = String

I Solution for β: find(β) = String → Int

I Solution for γ: find(γ) = String

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 20/34 int int

I Conflict: Unify returns false when trying to unify Int → Int and String

I Conclusion: This system of type constraints is unsatisfiable

Example 2

I Consider the following system of type constraints:

α = Int → Int α = String

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 21/34 I Conflict: Unify returns false when trying to unify Int → Int and String

I Conclusion: This system of type constraints is unsatisfiable

Example 2

I Consider the following system of type constraints:

α = Int → Int α = String

int int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 21/34 I Conflict: Unify returns false when trying to unify Int → Int and String

I Conclusion: This system of type constraints is unsatisfiable

Example 2

I Consider the following system of type constraints:

α = Int → Int α = String

int int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 21/34 I Conflict: Unify returns false when trying to unify Int → Int and String

I Conclusion: This system of type constraints is unsatisfiable

Example 2

I Consider the following system of type constraints:

α = Int → Int α = String

string

int int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 21/34 I Conflict: Unify returns false when trying to unify Int → Int and String

I Conclusion: This system of type constraints is unsatisfiable

Example 2

I Consider the following system of type constraints:

α = Int → Int α = String

string

int int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 21/34 I Conflict: Unify returns false when trying to unify Int → Int and String

I Conclusion: This system of type constraints is unsatisfiable

Example 2

I Consider the following system of type constraints:

α = Int → Int α = String

string

int int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 21/34 I Conclusion: This system of type constraints is unsatisfiable

Example 2

I Consider the following system of type constraints:

α = Int → Int α = String

string

int int

I Conflict: Unify returns false when trying to unify Int → Int and String

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 21/34 Example 2

I Consider the following system of type constraints:

α = Int → Int α = String

string

int int

I Conflict: Unify returns false when trying to unify Int → Int and String

I Conclusion: This system of type constraints is unsatisfiable

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 21/34 I However, for this to be efficient, union/find must be efficient.

I Key result from algorithms: It is possible to build a data structure for union-find that can find a solution to our sets of type constraints in approximately linear time.

I You can learn about this data structure in Advance Algorithms or Isil’s class on automated logical reasoning

I But for our purposes, we will just use this data structure

Union-Find

I With this new approach, we can now only process each equality once.

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 22/34 I Key result from algorithms: It is possible to build a data structure for union-find that can find a solution to our sets of type constraints in approximately linear time.

I You can learn about this data structure in Advance Algorithms or Isil’s class on automated logical reasoning

I But for our purposes, we will just use this data structure

Union-Find

I With this new approach, we can now only process each equality once.

I However, for this to be efficient, union/find must be efficient.

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 22/34 I You can learn about this data structure in Advance Algorithms or Isil’s class on automated logical reasoning

I But for our purposes, we will just use this data structure

Union-Find

I With this new approach, we can now only process each equality once.

I However, for this to be efficient, union/find must be efficient.

I Key result from algorithms: It is possible to build a data structure for union-find that can find a solution to our sets of type constraints in approximately linear time.

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 22/34 I But for our purposes, we will just use this data structure

Union-Find

I With this new approach, we can now only process each equality once.

I However, for this to be efficient, union/find must be efficient.

I Key result from algorithms: It is possible to build a data structure for union-find that can find a solution to our sets of type constraints in approximately linear time.

I You can learn about this data structure in Advance Algorithms or Isil’s class on automated logical reasoning

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 22/34 Union-Find

I With this new approach, we can now only process each equality once.

I However, for this to be efficient, union/find must be efficient.

I Key result from algorithms: It is possible to build a data structure for union-find that can find a solution to our sets of type constraints in approximately linear time.

I You can learn about this data structure in Advance Algorithms or Isil’s class on automated logical reasoning

I But for our purposes, we will just use this data structure

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 22/34 I New ++11 standard

I 7

I This style of polymorphic type inference we studied is known as Hindley-Milner type inference

I Type inference is at the core of languages such as OCAML and Haskell

I Type inference is increasingly moving to main-stream languages

Type Inference

I If we use Union-Find, we can make type inference practical on real programs

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 23/34 I New C++11 standard

I Java 7

I Type inference is at the core of languages such as OCAML and Haskell

I Type inference is increasingly moving to main-stream languages

Type Inference

I If we use Union-Find, we can make type inference practical on real programs

I This style of polymorphic type inference we studied is known as Hindley-Milner type inference

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 23/34 I New C++11 standard

I Java 7

I Type inference is increasingly moving to main-stream languages

Type Inference

I If we use Union-Find, we can make type inference practical on real programs

I This style of polymorphic type inference we studied is known as Hindley-Milner type inference

I Type inference is at the core of languages such as OCAML and Haskell

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 23/34 I New C++11 standard

I Java 7

Type Inference

I If we use Union-Find, we can make type inference practical on real programs

I This style of polymorphic type inference we studied is known as Hindley-Milner type inference

I Type inference is at the core of languages such as OCAML and Haskell

I Type inference is increasingly moving to main-stream languages

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 23/34 I Java 7

Type Inference

I If we use Union-Find, we can make type inference practical on real programs

I This style of polymorphic type inference we studied is known as Hindley-Milner type inference

I Type inference is at the core of languages such as OCAML and Haskell

I Type inference is increasingly moving to main-stream languages

I New C++11 standard

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 23/34 Type Inference

I If we use Union-Find, we can make type inference practical on real programs

I This style of polymorphic type inference we studied is known as Hindley-Milner type inference

I Type inference is at the core of languages such as OCAML and Haskell

I Type inference is increasingly moving to main-stream languages

I New C++11 standard

I Java 7

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 23/34 I Specifically, every error resulted from unifying two equivalence classes that could not be unified.

I Example: Trying to unify String and α → Int

I But how do we report this error to programmers?

Type Inference and Errors

I We saw that we can detect all errors easily when doing type inference

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 24/34 I Example: Trying to unify String and α → Int

I But how do we report this error to programmers?

Type Inference and Errors

I We saw that we can detect all errors easily when doing type inference

I Specifically, every error resulted from unifying two equivalence classes that could not be unified.

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 24/34 I But how do we report this error to programmers?

Type Inference and Errors

I We saw that we can detect all errors easily when doing type inference

I Specifically, every error resulted from unifying two equivalence classes that could not be unified.

I Example: Trying to unify String and α → Int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 24/34 Type Inference and Errors

I We saw that we can detect all errors easily when doing type inference

I Specifically, every error resulted from unifying two equivalence classes that could not be unified.

I Example: Trying to unify String and α → Int

I But how do we report this error to programmers?

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 24/34 I Not associated with any source location

I Understanding typing errors requires understanding type inference

I Option 1: Output message: String and α → Int cannot be unified.

I Is this helpful?

I Obvious problems:

Error Reporting

I Consider again the example: String and α → Int.

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 25/34 I Not associated with any source location

I Understanding typing errors requires understanding type inference

I Is this helpful?

I Obvious problems:

Error Reporting

I Consider again the example: String and α → Int.

I Option 1: Output message: String and α → Int cannot be unified.

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 25/34 I Not associated with any source location

I Understanding typing errors requires understanding type inference

I Obvious problems:

Error Reporting

I Consider again the example: String and α → Int.

I Option 1: Output message: String and α → Int cannot be unified.

I Is this helpful?

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 25/34 I Not associated with any source location

I Understanding typing errors requires understanding type inference

Error Reporting

I Consider again the example: String and α → Int.

I Option 1: Output message: String and α → Int cannot be unified.

I Is this helpful?

I Obvious problems:

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 25/34 I Understanding typing errors requires understanding type inference

Error Reporting

I Consider again the example: String and α → Int.

I Option 1: Output message: String and α → Int cannot be unified.

I Is this helpful?

I Obvious problems:

I Not associated with any source location

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 25/34 Error Reporting

I Consider again the example: String and α → Int.

I Option 1: Output message: String and α → Int cannot be unified.

I Is this helpful?

I Obvious problems:

I Not associated with any source location

I Understanding typing errors requires understanding type inference

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 25/34 I Message can now at least contain the program expressions that evaluate to String and α → Int

I But the actual error in your program may be arbitrarily far from these locations!

I Typical OCaml error: “At line 37: Expected expression of type ‘a -> ‘a but found expression of type ‘a -> ‘b”

I To fix this, you need to understand all the reasoning steps that happened during type inference

I Most likely, the problem did not originate at line 37!

Error Reporting Cont.

I Improvement used in practice: Associate expression/source location with type constraint.

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 26/34 I But the actual error in your program may be arbitrarily far from these locations!

I Typical OCaml error: “At line 37: Expected expression of type ‘a -> ‘a but found expression of type ‘a -> ‘b”

I To fix this, you need to understand all the reasoning steps that happened during type inference

I Most likely, the problem did not originate at line 37!

Error Reporting Cont.

I Improvement used in practice: Associate expression/source location with type constraint.

I Message can now at least contain the program expressions that evaluate to String and α → Int

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 26/34 I Typical OCaml error: “At line 37: Expected expression of type ‘a -> ‘a but found expression of type ‘a -> ‘b”

I To fix this, you need to understand all the reasoning steps that happened during type inference

I Most likely, the problem did not originate at line 37!

Error Reporting Cont.

I Improvement used in practice: Associate expression/source location with type constraint.

I Message can now at least contain the program expressions that evaluate to String and α → Int

I But the actual error in your program may be arbitrarily far from these locations!

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 26/34 I To fix this, you need to understand all the reasoning steps that happened during type inference

I Most likely, the problem did not originate at line 37!

Error Reporting Cont.

I Improvement used in practice: Associate expression/source location with type constraint.

I Message can now at least contain the program expressions that evaluate to String and α → Int

I But the actual error in your program may be arbitrarily far from these locations!

I Typical OCaml error: “At line 37: Expected expression of type ‘a -> ‘a but found expression of type ‘a -> ‘b”

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 26/34 I Most likely, the problem did not originate at line 37!

Error Reporting Cont.

I Improvement used in practice: Associate expression/source location with type constraint.

I Message can now at least contain the program expressions that evaluate to String and α → Int

I But the actual error in your program may be arbitrarily far from these locations!

I Typical OCaml error: “At line 37: Expected expression of type ‘a -> ‘a but found expression of type ‘a -> ‘b”

I To fix this, you need to understand all the reasoning steps that happened during type inference

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 26/34 Error Reporting Cont.

I Improvement used in practice: Associate expression/source location with type constraint.

I Message can now at least contain the program expressions that evaluate to String and α → Int

I But the actual error in your program may be arbitrarily far from these locations!

I Typical OCaml error: “At line 37: Expected expression of type ‘a -> ‘a but found expression of type ‘a -> ‘b”

I To fix this, you need to understand all the reasoning steps that happened during type inference

I Most likely, the problem did not originate at line 37!

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 26/34 I Type annotations allow you explicitly declare types even though the compiler can infer them automatically

I Idea: If you encounter a type error you do not understand, you give the type you expect to the expressions involved in this error and re-run the type checker

I You will now get a new type error in a different location

I You repeat this process until you fixed your type error

Type Annotations

I Most common technique for mitigating these difficulties: Allow type annotations

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 27/34 I Idea: If you encounter a type error you do not understand, you give the type you expect to the expressions involved in this error and re-run the type checker

I You will now get a new type error in a different location

I You repeat this process until you fixed your type error

Type Annotations

I Most common technique for mitigating these difficulties: Allow type annotations

I Type annotations allow you explicitly declare types even though the compiler can infer them automatically

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 27/34 I You will now get a new type error in a different location

I You repeat this process until you fixed your type error

Type Annotations

I Most common technique for mitigating these difficulties: Allow type annotations

I Type annotations allow you explicitly declare types even though the compiler can infer them automatically

I Idea: If you encounter a type error you do not understand, you give the type you expect to the expressions involved in this error and re-run the type checker

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 27/34 I You repeat this process until you fixed your type error

Type Annotations

I Most common technique for mitigating these difficulties: Allow type annotations

I Type annotations allow you explicitly declare types even though the compiler can infer them automatically

I Idea: If you encounter a type error you do not understand, you give the type you expect to the expressions involved in this error and re-run the type checker

I You will now get a new type error in a different location

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 27/34 Type Annotations

I Most common technique for mitigating these difficulties: Allow type annotations

I Type annotations allow you explicitly declare types even though the compiler can infer them automatically

I Idea: If you encounter a type error you do not understand, you give the type you expect to the expressions involved in this error and re-run the type checker

I You will now get a new type error in a different location

I You repeat this process until you fixed your type error

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 27/34 I You often need many annotations to find the source of type errors

I You can only annotate successfully if you understand polymorphic type inference

I You often end up with a program that is almost completely type annotated!

Type Annotations Drawbacks

I However, this approach still has substantial drawbacks:

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 28/34 I You can only annotate successfully if you understand polymorphic type inference

I You often end up with a program that is almost completely type annotated!

Type Annotations Drawbacks

I However, this approach still has substantial drawbacks:

I You often need many annotations to find the source of type errors

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 28/34 I You often end up with a program that is almost completely type annotated!

Type Annotations Drawbacks

I However, this approach still has substantial drawbacks:

I You often need many annotations to find the source of type errors

I You can only annotate successfully if you understand polymorphic type inference

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 28/34 Type Annotations Drawbacks

I However, this approach still has substantial drawbacks:

I You often need many annotations to find the source of type errors

I You can only annotate successfully if you understand polymorphic type inference

I You often end up with a program that is almost completely type annotated!

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 28/34 I Examples: OCaml, Haskell, F#

I Slogan on Type Inference: The ease of dynamic typing with the speed an guarantees of a static

I This claim is true, but real problems with explaining typing errors to programmers

I Explaining typing errors better is also an active research area!

Type Inference in the Real World

I Despite these difficulties, there are many real languages that support full type inference.

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 29/34 I Slogan on Type Inference: The ease of dynamic typing with the speed an guarantees of a static type system

I This claim is true, but real problems with explaining typing errors to programmers

I Explaining typing errors better is also an active research area!

Type Inference in the Real World

I Despite these difficulties, there are many real languages that support full type inference.

I Examples: OCaml, Haskell, F#

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 29/34 I This claim is true, but real problems with explaining typing errors to programmers

I Explaining typing errors better is also an active research area!

Type Inference in the Real World

I Despite these difficulties, there are many real languages that support full type inference.

I Examples: OCaml, Haskell, F#

I Slogan on Type Inference: The ease of dynamic typing with the speed an guarantees of a static type system

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 29/34 I Explaining typing errors better is also an active research area!

Type Inference in the Real World

I Despite these difficulties, there are many real languages that support full type inference.

I Examples: OCaml, Haskell, F#

I Slogan on Type Inference: The ease of dynamic typing with the speed an guarantees of a static type system

I This claim is true, but real problems with explaining typing errors to programmers

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 29/34 Type Inference in the Real World

I Despite these difficulties, there are many real languages that support full type inference.

I Examples: OCaml, Haskell, F#

I Slogan on Type Inference: The ease of dynamic typing with the speed an guarantees of a static type system

I This claim is true, but real problems with explaining typing errors to programmers

I Explaining typing errors better is also an active research area!

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 29/34 I In local type inference, types are only inferred within one function, but must be fully annotated at function boundaries.

I Goal: Make it easier for programmers to diagnose type errors (and make type inference tractable in the imperative setting)

Type Inference in the Real World Cont.

I Alternative approach taken by more main-stream languages recently: local type inference

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 30/34 I Goal: Make it easier for programmers to diagnose type errors (and make type inference tractable in the imperative setting)

Type Inference in the Real World Cont.

I Alternative approach taken by more main-stream languages recently: local type inference

I In local type inference, types are only inferred within one function, but must be fully annotated at function boundaries.

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 30/34 Type Inference in the Real World Cont.

I Alternative approach taken by more main-stream languages recently: local type inference

I In local type inference, types are only inferred within one function, but must be fully annotated at function boundaries.

I Goal: Make it easier for programmers to diagnose type errors (and make type inference tractable in the imperative setting)

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 30/34 I First Example: templates

I A STL pair is templatized over the type of the first and second element

I You declare a pair as: pair p(3, "duck");

I However, if you call a function that takes a pair, the compiler will infer the template type for you in some cases:

I Example: edit_pair(p) instead of edit_pair >(p)

Example of local type inference

I C++ supports some forms of local type inference.

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 31/34 I A STL pair is templatized over the type of the first and second element

I You declare a pair as: pair p(3, "duck");

I However, if you call a function that takes a pair, the compiler will infer the template type for you in some cases:

I Example: edit_pair(p) instead of edit_pair >(p)

Example of local type inference

I C++ supports some forms of local type inference.

I First Example: templates

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 31/34 I You declare a pair as: pair p(3, "duck");

I However, if you call a function that takes a pair, the compiler will infer the template type for you in some cases:

I Example: edit_pair(p) instead of edit_pair >(p)

Example of local type inference

I C++ supports some forms of local type inference.

I First Example: templates

I A STL pair is templatized over the type of the first and second element

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 31/34 I However, if you call a function that takes a pair, the compiler will infer the template type for you in some cases:

I Example: edit_pair(p) instead of edit_pair >(p)

Example of local type inference

I C++ supports some forms of local type inference.

I First Example: templates

I A STL pair is templatized over the type of the first and second element

I You declare a pair as: pair p(3, "duck");

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 31/34 I Example: edit_pair(p) instead of edit_pair >(p)

Example of local type inference

I C++ supports some forms of local type inference.

I First Example: templates

I A STL pair is templatized over the type of the first and second element

I You declare a pair as: pair p(3, "duck");

I However, if you call a function that takes a pair, the compiler will infer the template type for you in some cases:

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 31/34 Example of local type inference

I C++ supports some forms of local type inference.

I First Example: templates

I A STL pair is templatized over the type of the first and second element

I You declare a pair as: pair p(3, "duck");

I However, if you call a function that takes a pair, the compiler will infer the template type for you in some cases:

I Example: edit_pair(p) instead of edit_pair >(p)

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 31/34 I This is done using the auto keyword

I Example using iterator: vector v; ... for(vector::iterator it = v.begin(); it != v.end(); it++) ...

I Example using iterator with new auto keyword: vector v; ... for(auto it = v.begin(); it != v.end(); it++) ...

Example of local type inference

I The new C++11 standard supports much more expressive local type inference

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 32/34 I Example using iterator: vector v; ... for(vector::iterator it = v.begin(); it != v.end(); it++) ...

I Example using iterator with new auto keyword: vector v; ... for(auto it = v.begin(); it != v.end(); it++) ...

Example of local type inference

I The new C++11 standard supports much more expressive local type inference

I This is done using the auto keyword

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 32/34 I Example using iterator with new auto keyword: vector v; ... for(auto it = v.begin(); it != v.end(); it++) ...

Example of local type inference

I The new C++11 standard supports much more expressive local type inference

I This is done using the auto keyword

I Example using iterator: vector v; ... for(vector::iterator it = v.begin(); it != v.end(); it++) ...

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 32/34 Example of local type inference

I The new C++11 standard supports much more expressive local type inference

I This is done using the auto keyword

I Example using iterator: vector v; ... for(vector::iterator it = v.begin(); it != v.end(); it++) ...

I Example using iterator with new auto keyword: vector v; ... for(auto it = v.begin(); it != v.end(); it++) ...

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 32/34 I Very convenient, local feature that is also creeping into languages such as C# and Java

I You will see more of this in the future

Type Inference in C++

I The auto keyword really just says “do type inference on this expression and figure the type out”

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 33/34 I You will see more of this in the future

Type Inference in C++

I The auto keyword really just says “do type inference on this expression and figure the type out”

I Very convenient, local feature that is also creeping into languages such as C# and Java

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 33/34 Type Inference in C++

I The auto keyword really just says “do type inference on this expression and figure the type out”

I Very convenient, local feature that is also creeping into languages such as C# and Java

I You will see more of this in the future

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 33/34 I This formulation is one of the classic and elegant results in programming languages, known as Hindley-Milner type inference

I Type inference is most likely coming to your favorite language in the near future, if it is not already there!

Conclusion

I We saw how to use Union-Find to make type inference scalable

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 34/34 I Type inference is most likely coming to your favorite language in the near future, if it is not already there!

Conclusion

I We saw how to use Union-Find to make type inference scalable

I This formulation is one of the classic and elegant results in programming languages, known as Hindley-Milner type inference

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 34/34 Conclusion

I We saw how to use Union-Find to make type inference scalable

I This formulation is one of the classic and elegant results in programming languages, known as Hindley-Milner type inference

I Type inference is most likely coming to your favorite language in the near future, if it is not already there!

Thomas Dillig, CS345H: Programming Languages Lecture 13: Type Inference II 34/34