Gradual Typing with Inference Jeremy Siek University of Colorado - - PowerPoint PPT Presentation

gradual typing with inference
SMART_READER_LITE
LIVE PREVIEW

Gradual Typing with Inference Jeremy Siek University of Colorado - - PowerPoint PPT Presentation

Gradual Typing with Inference Jeremy Siek University of Colorado at Boulder joint work with Manish Vachharajani Overview Motivation Background Gradual Typing Unification-based inference Exploring the Solution Space Type


slide-1
SLIDE 1

Gradual Typing with Inference

Jeremy Siek University of Colorado at Boulder

joint work with Manish Vachharajani

slide-2
SLIDE 2

Overview

  • Motivation
  • Background
  • Gradual Typing
  • Unification-based inference
  • Exploring the Solution Space
  • Type system (specification)
  • Inference algorithm (implementation)
slide-3
SLIDE 3

Why Gradual Typing?

  • Static and dynamic type systems have

complimentary strengths.

  • Static typing provides full-coverage error

checking, efficient execution, and machine-checked documentation.

  • Dynamic typing enables rapid

development and fast adaption to changing requirements.

  • Why not have both in the same language?

Java Python

slide-4
SLIDE 4

Goals for gradual typing

  • Treat programs without type annotations as

dynamically typed.

  • Programmers may incrementally add type

annotations to gradually increase static checking.

  • Annotate all parameters and the type system

catches all type errors.

4

slide-5
SLIDE 5

Goals for gradual typing

  • Treat programs without type annotations as

dynamically typed.

  • Programmers may incrementally add type

annotations to gradually increase static checking.

  • Annotate all parameters and the type system

catches all type errors.

4

dynamic static

slide-6
SLIDE 6

Goals for gradual typing

  • Treat programs without type annotations as

dynamically typed.

  • Programmers may incrementally add type

annotations to gradually increase static checking.

  • Annotate all parameters and the type system

catches all type errors.

4

dynamic static gradual

slide-7
SLIDE 7

The Gradual Type System

5

  • Classify dynamically typed expressions

with the type ‘?’

  • Allow implicit coercions to ? and from ?

with any other type

  • Extend coercions to compound types

using a new consistency relation

slide-8
SLIDE 8

Coercions to and from ‘?’

(λa:int. (λx. x + 1) a) 1

Parameters with no type annotation are given the dynamic type ‘?’.

6

slide-9
SLIDE 9

Coercions to and from ‘?’

(λa:int. (λx. x + 1) a) 1 ?

Parameters with no type annotation are given the dynamic type ‘?’.

6

slide-10
SLIDE 10

Coercions to and from ‘?’

(λa:int. (λx. x + 1) a) 1 int ?

Parameters with no type annotation are given the dynamic type ‘?’.

6

slide-11
SLIDE 11

Coercions to and from ‘?’

(λa:int. (λx. x + 1) a) 1 int ? int ⇒ ?

Parameters with no type annotation are given the dynamic type ‘?’.

6

slide-12
SLIDE 12

Coercions to and from ‘?’

(λa:int. (λx. x + 1) a) 1 int ⇒ ?

Parameters with no type annotation are given the dynamic type ‘?’.

6

int x int → int

slide-13
SLIDE 13

Coercions to and from ‘?’

(λa:int. (λx. x + 1) a) 1 int ⇒ ?

Parameters with no type annotation are given the dynamic type ‘?’.

6

int x int → int ?

slide-14
SLIDE 14

Coercions to and from ‘?’

(λa:int. (λx. x + 1) a) 1 ? ⇒ int int ⇒ ?

Parameters with no type annotation are given the dynamic type ‘?’.

6

int x int → int ?

slide-15
SLIDE 15

Coercions between compound types

7

(λf:int→int. f 1) (λx. 1)

slide-16
SLIDE 16

Coercions between compound types

7

(λf:int→int. f 1) (λx. 1) ? → int

slide-17
SLIDE 17

Coercions between compound types

7

(λf:int→int. f 1) (λx. 1) ? → int ? → int ⇒ int → int

slide-18
SLIDE 18

Detect static type errors

8

(λf:int→int. f 1) 1 int ⇒ int → int

slide-19
SLIDE 19

Type system: replace = with ~

Γ ⊢ e1 : σ → τ Γ ⊢ e2 : σ‘ σ‘ ~ σ Γ ⊢ e1 e2 : τ

9

slide-20
SLIDE 20

Type system: replace = with ~

Γ ⊢ e1 : σ → τ Γ ⊢ e2 : σ‘ σ‘ ~ σ Γ ⊢ e1 e2 : τ

9

slide-21
SLIDE 21
  • Definition: a type is consistent, written ~, with

another type when they are equal where they are both defined.

  • Examples:

The consistency relation

int ~ int int ~ bool

? ~ int

int ~ ?

? → bool ~ ? → int

10

int → ? ~ ? → bool

slide-22
SLIDE 22

The consistency relation

11

τ1 → τ2 ~ τ3 → τ4 τ1 ~ τ3 τ2 ~ τ4 τ ~ ?

? ~ τ

τ ~ τ τ1 ~ τ2

slide-23
SLIDE 23

Compiler inserts run-time checks

Γ ⊢ e1 ⇒ e’1 : σ → τ

Γ ⊢ e2 ⇒ e’2 : σ‘ σ‘ ~ σ

Γ ⊢ e1 e2 ⇒ e’1 〈σ⇐σ‘〉 e’2 : τ (λa:int. (λx. x + 1) a) 1 ⇒ (λa:int. (λx. 〈int⇐?〉x + 1) 〈?⇐int〉a) 1

Example:

12

slide-24
SLIDE 24

Recent Developments

  • Integration with objects (Siek & Taha, ECOOP’07)
  • Space-efficiency (Herman et al, TFP’07)
  • Blame tracking (Wadler & Findler, Scheme’07)
  • In JavaScript (Herman & Flanagan, ML’07)

13

slide-25
SLIDE 25

Why Inference?

  • Interesting research question: how does the

dynamic type interact with type variables?

  • Practical applications
  • Help programmers migrate dynamically

typed code to statically typed code

  • Explain how gradual typing can be

integrated with functional languages with inference (ML, Haskell, etc.)

14

slide-26
SLIDE 26

STLC with type vars: Specification

15

Γ ⊢ e : τ

Standard STLC judgment: An STLC term with type variables is well typed if there exists an S such that S(Γ) ⊢ S(e) : S(τ) e.g., (λx:int. (λy:α. y) x) S = {α ↦ int}

slide-27
SLIDE 27

Inference Algorithm

16

λx:int. (λy:α. y) x α → α = int → β constraint generation unification S = {α ↦ int, β ↦ int}

slide-28
SLIDE 28

Huet’s Unification

17

α → α = int → β

slide-29
SLIDE 29

Huet’s Unification

17

α → α = int → β

  • int
slide-30
SLIDE 30

Huet’s Unification

17

α → α = int → β

  • int
  • int
slide-31
SLIDE 31

Huet’s Unification

17

α → α = int → β

  • int
  • int
  • int
slide-32
SLIDE 32

Huet’s Unification

17

α → α = int → β

  • int
  • int
  • int
  • int
slide-33
SLIDE 33

Huet’s Unification

  • When merging nodes, the algorithm needs

to decide which label to keep

  • In this setting, non-type variables trump type

variables

18

  • int

int

slide-34
SLIDE 34

Gradual Typing with Inference

  • Setting: STLC with α and ?.
  • To migrate from dynamic to static,

change ? to α and the inferencer will tell you the solution for α or give an error.

19

λ f:?. λ x:?. f x x λ f:α. λ x:?. f x x

slide-35
SLIDE 35

Syntactic Sugar

20

λ f. λ x. f x x

?

slide-36
SLIDE 36

Syntactic Sugar

20

λ f. λ x. f x x λ f:?. λ x:?. f x x

?

slide-37
SLIDE 37

Syntactic Sugar

20

λ f. λ x. f x x λ f:?. λ x:?. f x x λ f:α. λ x:β. f x x

?

slide-38
SLIDE 38

Non-solution #1

21

Well typed in gradual type system after substitution S(Γ) ⊢ S(e) : S(τ) (λ f:α. f 1) 1 Problem: the following is accepted S = {α ↦ ?}

slide-39
SLIDE 39

Non-solution #2

22

Forbid ?s from appearing in a solution S Problem: sometimes this forces cast errors at runtime λx:?. (λ y:α. y) x λx:?. (λ y:int. y) x λx:?. (λ y:int. y) 〈int⇐?〉x

slide-40
SLIDE 40

Non-solution #2

22

Forbid ?s from appearing in a solution S Problem: sometimes this forces cast errors at runtime λx:?. (λ y:α. y) x λx:?. (λ y:int. y) x λx:?. (λ y:int. y) 〈int⇐?〉x

slide-41
SLIDE 41

Non-solution #3

23

Treat each ? as a different type variable then check for well typed in STLC after substitution λ f:int → bool → int. λ x:?. f x x Problem: the following is rejected λ f:int → bool → int. λ x:α. f x x

slide-42
SLIDE 42

Non-solution #4

24

Treat each occurrence of ? in a constraint as a different type variable Problem: if no type vars in the program, the resulting type should not have type vars λ f:int → ?. λ x:int. (f x) int → ? = int → β int → α = int → β

slide-43
SLIDE 43

Lessons

  • Need to restrict the occurrences of ? in

solutions

  • But can’t completely outlaw the use of ?
  • Idea: a solution for α at least as informative

as any of the types that constrain α constrain

  • i.e., the solution for α must be an upper

bound of all the types that constrain α

25

slide-44
SLIDE 44

Information Ordering

26

? int → ? int ? → ? ? → int int → int bool

τ1 ⊑ τ2

semi-lattice

slide-45
SLIDE 45

Type System

  • But what does it mean for a type to

constrain α?

27

λf:α→α. λg:(?→int)→int. g f ? → int α → α

slide-46
SLIDE 46

Type System

  • But what does it mean for a type to

constrain α?

27

λf:α→α. λg:(?→int)→int. g f ? → int α → α ? ⊑ S(α)

slide-47
SLIDE 47

Type System

  • But what does it mean for a type to

constrain α?

27

λf:α→α. λg:(?→int)→int. g f ? → int α → α ? ⊑ S(α) int ⊑ S(α)

slide-48
SLIDE 48

Type System

  • The typing judgment:
  • Consistent-equal:
  • Consistent-less:

28

S; Γ ⊢ e : τ S ⊨ τ ≃ τ S ⊨ τ ⊑ τ

slide-49
SLIDE 49

Type System

29

S; Γ ⊢ e1 : τ1 S; Γ ⊢ e2 : τ2 S ⊨ τ1 ≃ τ2 → β (β fresh) S; Γ ⊢ e1 e2 : β S; Γ ⊢ e : τ

slide-50
SLIDE 50

Type System

29

S; Γ ⊢ e1 : τ1 S; Γ ⊢ e2 : τ2 S ⊨ τ1 ≃ τ2 → β (β fresh) S; Γ ⊢ e1 e2 : β S; Γ ⊢ e : τ

slide-51
SLIDE 51

Consistent-equal

30

S ⊨ τ ≃ τ S ⊨ τ1 → τ2 ≃ τ3 → τ4 S ⊨ τ1 ≃ τ3 S ⊨ τ2 ≃ τ4 S ⊨ τ ≃ ? S ⊨ ? ≃ τ S ⊨ γ ≃ γ S ⊨ α ≃ τ S ⊨ τ ⊑ S(α) S ⊨ τ ≃ α S ⊨ τ ⊑ S(α)

slide-52
SLIDE 52

Consistent-less

31

S ⊨ τ ⊑ τ S ⊨ τ1 → τ2 ⊑ τ3 → τ4 S ⊨ τ1 ⊑ τ3 S ⊨ τ2 ⊑ τ4 S ⊨ ? ⊑ τ S ⊨ γ ⊑ γ S ⊨ α ⊑ τ S ⊨ S(α) = τ

slide-53
SLIDE 53

Properties

  • When there are no type variables in the

program, the type system acts like the

  • riginal gradual type system
  • When there are no ? in the program, the

type system acts like the STLC with variables

32

slide-54
SLIDE 54

Inference Algorithm

33

λf:α→α. λg:(?→int)→int. g f (? → int) → int ≃ (α → α) → β constraint generation unification for ≃ S = {α ↦ int, β ↦ int}

slide-55
SLIDE 55

Unification for ≃

  • Can’t use the standard substitution-based

version because we need to see all the unificands before deciding on the solution

34

(? → int) → int ≃ (α → α) → β

slide-56
SLIDE 56

Unification for ≃

  • Need to compute the least upper bound
  • Otherwise spurious casts are inserted

35

λx:?. (λ y:α. y) x λx:?. (λ y:int. y) x λx:?. (λ y:int. y) 〈int⇐?〉x

slide-57
SLIDE 57

Unification for ≃

  • Need to compute the least upper bound
  • Otherwise spurious casts are inserted

35

λx:?. (λ y:α. y) x λx:?. (λ y:int. y) x λx:?. (λ y:int. y) 〈int⇐?〉x

slide-58
SLIDE 58

Merging Labels

  • Type variables are trumped by non-type

variables (including the dynamic type)

  • The dynamic type is trumped by concrete

types (e.g., int, bool, →)

36

  • ?

? ? int int

slide-59
SLIDE 59

Unification for ≃

37

(? → int) → int ≃ (α → α) → β

slide-60
SLIDE 60

Unification for ≃

37

(? → int) → int ≃ (α → α) → β

  • int

?

  • var
  • var
slide-61
SLIDE 61

Unification for ≃

37

(? → int) → int ≃ (α → α) → β

  • int

?

  • var
  • var
slide-62
SLIDE 62

Unification for ≃

37

(? → int) → int ≃ (α → α) → β

  • int

?

  • var
  • var
slide-63
SLIDE 63

Unification for ≃

37

(? → int) → int ≃ (α → α) → β

  • int

?

  • var
slide-64
SLIDE 64

Unification for ≃

37

(? → int) → int ≃ (α → α) → β

  • int
  • var
slide-65
SLIDE 65

Unification for ≃

37

(? → int) → int ≃ (α → α) → β

  • int
slide-66
SLIDE 66

Properties

  • The time complexity of unification for ≃ is

O(m α(n)) for a graph with n nodes and m edges

  • Soundness: if (S,τ) = infer(Γ, e) then

S*; Γ ⊢ e : τ.

  • Completeness: if S; Γ ⊢ e : τ then there is

a S’, τ’, and R such that (S’, τ’) = infer(Γ, e) and R•S’ ⊑ S and R•S’*(τ’) ⊑ S(τ).

38

slide-67
SLIDE 67

Related Work

  • Java + Dynamic (Gray & Findler & Flatt)
  • Optional types (LISP, Dylan, etc.)
  • BabyJ: gradual typing in a nominal setting(Anderson

& Drossopoulou)

  • Quasi-static types (Thatte)
  • Soft typing (Cartwright & Fagan, Wright &

Cartwright, Flanagan & Felleisen, Aiken & Wimmers & Lakshman)

  • Dynamic typing (Henglein)

39

slide-68
SLIDE 68

Conclusion

  • Gradual typing provides a combination of

dynamic and static typing in the same language, under programmer control.

  • We present a type system for gradually

typed programs with type variables.

  • We present a unification-based inference

algorithm that only requires a small change to Huet’s algorithm to handle ?s.

40

slide-69
SLIDE 69

41

slide-70
SLIDE 70

Type System

42

S; Γ ⊢ e1 : τ1 S; Γ ⊢ e2 : τ2 S ⊨ τ1 ≃ τ2 → β (β fresh) S; Γ ⊢ e1 e2 : β

slide-71
SLIDE 71

Type System

42

S; Γ ⊢ e1 : τ1 S; Γ ⊢ e2 : τ2 S ⊨ τ1 ≃ τ2 → β (β fresh) S; Γ ⊢ e1 e2 : β

slide-72
SLIDE 72

Non-solution

43

S; Γ ⊢ e1 : τ1 S; Γ ⊢ e2 : τ2 S ⊨ τ1 ≃ τ2 → τ3 S; Γ ⊢ e1 e2 : τ3 λ f:int → int. λ g:int → bool. f (g 1) Problem: the following is accepted because we can choose τ3 = ?

slide-73
SLIDE 73

Solution

44

S; Γ ⊢ e1 : τ1 S; Γ ⊢ e2 : τ2 S ⊨ τ1 ≃ τ2 → β (β fresh) S; Γ ⊢ e1 e2 : β λ f:int → int. λ g:int → bool. f (g 1) S ⊨ int → bool ≃ int → β1 S ⊨ int → int ≃ β1 → β2 S ⊨ bool ⊑ β1 S ⊨ int ⊑ β1

slide-74
SLIDE 74

Inference Algorithm

45

λf:(?→int)→(int→?)→int. λy:α. f y y (?→int)→ (int→?)→int ≃ α → β1 constraint generation unification for ≃ S = {α ↦ int→int, β1 ↦ (int→int)→int, β2 ↦ int} β1 ≃ α → β2

slide-75
SLIDE 75

Unification for ≃

46

(?→int) → (int→?)→int ≃ α → β1 β1 ≃ α → β2

slide-76
SLIDE 76

Unification for ≃

46

(?→int) → (int→?)→int ≃ α → β1

  • var

2 var

  • ?

var 1

  • int

?

β1 ≃ α → β2

slide-77
SLIDE 77

Unification for ≃

46

(?→int) → (int→?)→int ≃ α → β1 β1 ≃ α → β2

  • var

2 ? var 1

  • int

? var

slide-78
SLIDE 78

Unification for ≃

46

(?→int) → (int→?)→int ≃ α → β1 β1 ≃ α → β2

  • 1
  • var

2 ?

  • int

?

slide-79
SLIDE 79

Unification for ≃

46

(?→int) → (int→?)→int ≃ α → β1 β1 ≃ α → β2

  • 1
  • var

2 ? int ?

slide-80
SLIDE 80

Unification for ≃

46

(?→int) → (int→?)→int ≃ α → β1 β1 ≃ α → β2

  • 1
  • ?

int 2 ?

slide-81
SLIDE 81

Unification for ≃

46

(?→int) → (int→?)→int ≃ α → β1 β1 ≃ α → β2

  • 1

? int 2 ?

slide-82
SLIDE 82

Unification for ≃

46

(?→int) → (int→?)→int ≃ α → β1 β1 ≃ α → β2

  • 1

int 2

slide-83
SLIDE 83

Unification for ≃

46

(?→int) → (int→?)→int ≃ α → β1 β1 ≃ α → β2