Programming Language Concepts: Lecture 19 Madhavan Mukund Chennai - - PowerPoint PPT Presentation

programming language concepts lecture 19
SMART_READER_LITE
LIVE PREVIEW

Programming Language Concepts: Lecture 19 Madhavan Mukund Chennai - - PowerPoint PPT Presentation

Programming Language Concepts: Lecture 19 Madhavan Mukund Chennai Mathematical Institute madhavan@cmi.ac.in http://www.cmi.ac.in/~madhavan/courses/pl2009 PLC 2009, Lecture 19, 01 April 2009 Adding types to -calculus The basic


slide-1
SLIDE 1

Programming Language Concepts: Lecture 19

Madhavan Mukund

Chennai Mathematical Institute madhavan@cmi.ac.in http://www.cmi.ac.in/~madhavan/courses/pl2009

PLC 2009, Lecture 19, 01 April 2009

slide-2
SLIDE 2

Adding types to λ-calculus

◮ The basic λ-calculus is untyped ◮ The first functional programming language, LISP, was also

untyped

◮ Modern languages such as Haskell, ML, . . . are strongly typed ◮ What is the theoretical foundation for such languages?

slide-3
SLIDE 3

Types in functional programming

The structure of types in Haskell

◮ Basic types—Int, Bool, Float, Char

slide-4
SLIDE 4

Types in functional programming

The structure of types in Haskell

◮ Basic types—Int, Bool, Float, Char ◮ Structured types

[Lists] If a is a type, so is [a] [Tuples] If a1, a2, . . . , ak are types, so is (a1,a2,...,ak)

slide-5
SLIDE 5

Types in functional programming

The structure of types in Haskell

◮ Basic types—Int, Bool, Float, Char ◮ Structured types

[Lists] If a is a type, so is [a] [Tuples] If a1, a2, . . . , ak are types, so is (a1,a2,...,ak)

◮ Function types

◮ If a, b are types, so is a -> b ◮ Function with input a, output b

slide-6
SLIDE 6

Types in functional programming

The structure of types in Haskell

◮ Basic types—Int, Bool, Float, Char ◮ Structured types

[Lists] If a is a type, so is [a] [Tuples] If a1, a2, . . . , ak are types, so is (a1,a2,...,ak)

◮ Function types

◮ If a, b are types, so is a -> b ◮ Function with input a, output b

◮ User defined types

◮ Data day = Sun | Mon | Tue | Wed | Thu | Fri | Sat ◮ Data BTree a = Nil | Node (BTree a) a (Btree a)

slide-7
SLIDE 7

Adding types to λ-calculus . . .

◮ Set Λ of untyped lambda expressions is given by

Λ = x | λx.M | MM′ where x ∈ Var, M, M′ ∈ Λ.

slide-8
SLIDE 8

Adding types to λ-calculus . . .

◮ Set Λ of untyped lambda expressions is given by

Λ = x | λx.M | MM′ where x ∈ Var, M, M′ ∈ Λ.

◮ Add a syntax for basic types ◮ When constructing expressions, build up the type from the

types of the parts

slide-9
SLIDE 9

Adding types to λ-calculus . . .

◮ Restrict our language to have just one basic type, written as τ

slide-10
SLIDE 10

Adding types to λ-calculus . . .

◮ Restrict our language to have just one basic type, written as τ ◮ No structured types (lists, tuples, . . . )

slide-11
SLIDE 11

Adding types to λ-calculus . . .

◮ Restrict our language to have just one basic type, written as τ ◮ No structured types (lists, tuples, . . . ) ◮ Function types arise naturally (τ → τ, (τ → τ) → τ → τ, . . .

slide-12
SLIDE 12

“Simply typed” λ-calculus

A separate set of variables Vars for each type s

slide-13
SLIDE 13

“Simply typed” λ-calculus

A separate set of variables Vars for each type s Define Λs, expressions of type s, by mutual recursion

slide-14
SLIDE 14

“Simply typed” λ-calculus

A separate set of variables Vars for each type s Define Λs, expressions of type s, by mutual recursion

◮ For each type s, every variable x ∈ Vars is in Λs

slide-15
SLIDE 15

“Simply typed” λ-calculus

A separate set of variables Vars for each type s Define Λs, expressions of type s, by mutual recursion

◮ For each type s, every variable x ∈ Vars is in Λs ◮ If M ∈ Λt and x ∈ Vars then (λx.M) ∈ Λs→t.

slide-16
SLIDE 16

“Simply typed” λ-calculus

A separate set of variables Vars for each type s Define Λs, expressions of type s, by mutual recursion

◮ For each type s, every variable x ∈ Vars is in Λs ◮ If M ∈ Λt and x ∈ Vars then (λx.M) ∈ Λs→t. ◮ If M ∈ Λs→t and N ∈ Λs then (MN) ∈ Λt.

◮ Note that application must be well typed

slide-17
SLIDE 17

“Simply typed” λ-calculus

A separate set of variables Vars for each type s Define Λs, expressions of type s, by mutual recursion

◮ For each type s, every variable x ∈ Vars is in Λs ◮ If M ∈ Λt and x ∈ Vars then (λx.M) ∈ Λs→t. ◮ If M ∈ Λs→t and N ∈ Λs then (MN) ∈ Λt.

◮ Note that application must be well typed

β rule as usual

◮ (λx.M)N →β M{x ← N}

slide-18
SLIDE 18

“Simply typed” λ-calculus

A separate set of variables Vars for each type s Define Λs, expressions of type s, by mutual recursion

◮ For each type s, every variable x ∈ Vars is in Λs ◮ If M ∈ Λt and x ∈ Vars then (λx.M) ∈ Λs→t. ◮ If M ∈ Λs→t and N ∈ Λs then (MN) ∈ Λt.

◮ Note that application must be well typed

β rule as usual

◮ (λx.M)N →β M{x ← N} ◮ We must have λx.M ∈ Λs→t and N ∈ Λs for some types s, t

slide-19
SLIDE 19

“Simply typed” λ-calculus

A separate set of variables Vars for each type s Define Λs, expressions of type s, by mutual recursion

◮ For each type s, every variable x ∈ Vars is in Λs ◮ If M ∈ Λt and x ∈ Vars then (λx.M) ∈ Λs→t. ◮ If M ∈ Λs→t and N ∈ Λs then (MN) ∈ Λt.

◮ Note that application must be well typed

β rule as usual

◮ (λx.M)N →β M{x ← N} ◮ We must have λx.M ∈ Λs→t and N ∈ Λs for some types s, t ◮ Moreover, if λx.M ∈ Λs→t, then x ∈ Vars, so x and N are

compatible

slide-20
SLIDE 20

“Simply typed” λ-calculus . . .

◮ Extend →β to one-step reduction →, as usual

slide-21
SLIDE 21

“Simply typed” λ-calculus . . .

◮ Extend →β to one-step reduction →, as usual ◮ The reduction relation →∗ is Church-Rosser

slide-22
SLIDE 22

“Simply typed” λ-calculus . . .

◮ Extend →β to one-step reduction →, as usual ◮ The reduction relation →∗ is Church-Rosser ◮ In fact, →∗ satisifies a much strong property

slide-23
SLIDE 23

Strong normalization

A λ-expression is

◮ normalizing if it has a normal form.

slide-24
SLIDE 24

Strong normalization

A λ-expression is

◮ normalizing if it has a normal form. ◮ strongly normalizing if every reduction sequence leads to a

normal form

slide-25
SLIDE 25

Strong normalization

A λ-expression is

◮ normalizing if it has a normal form. ◮ strongly normalizing if every reduction sequence leads to a

normal form Examples

◮ (λx.xx)(λx.xx) is not normalizing

slide-26
SLIDE 26

Strong normalization

A λ-expression is

◮ normalizing if it has a normal form. ◮ strongly normalizing if every reduction sequence leads to a

normal form Examples

◮ (λx.xx)(λx.xx) is not normalizing ◮ (λyz.z)((λx.xx)(λx.xx)) is not strongly normalizing.

slide-27
SLIDE 27

Strong normalization . . .

A λ-calculus is strongly normalizing if every term in the calculus is strongly normalizing

slide-28
SLIDE 28

Strong normalization . . .

A λ-calculus is strongly normalizing if every term in the calculus is strongly normalizing Theorem The simply typed λ-calculus is strongly normalizing

slide-29
SLIDE 29

Strong normalization . . .

A λ-calculus is strongly normalizing if every term in the calculus is strongly normalizing Theorem The simply typed λ-calculus is strongly normalizing Proof intuition

◮ Each β-reduction reduces the type complexity of the term ◮ Cannot have an infinite sequence of reductions

slide-30
SLIDE 30

Type checking

◮ Syntax of simply typed λ-calculus permits only well-typed

terms

slide-31
SLIDE 31

Type checking

◮ Syntax of simply typed λ-calculus permits only well-typed

terms

◮ Converse question; Given an arbitrary term, is it well-typed?

slide-32
SLIDE 32

Type checking

◮ Syntax of simply typed λ-calculus permits only well-typed

terms

◮ Converse question; Given an arbitrary term, is it well-typed?

◮ For instance, we cannot assign a valid type to f f . . . ◮ . . . so f f is not a valid expression in this calculus

slide-33
SLIDE 33

Type checking

◮ Syntax of simply typed λ-calculus permits only well-typed

terms

◮ Converse question; Given an arbitrary term, is it well-typed?

◮ For instance, we cannot assign a valid type to f f . . . ◮ . . . so f f is not a valid expression in this calculus

Theorem The type-checking problem for the simply typed λ-calculus is decidable

slide-34
SLIDE 34

Type checking . . .

◮ A term may admit multiple types

◮ λx.x can be of type τ → τ, (τ → τ) → (τ → τ), . . .

slide-35
SLIDE 35

Type checking . . .

◮ A term may admit multiple types

◮ λx.x can be of type τ → τ, (τ → τ) → (τ → τ), . . .

◮ Principal type scheme of a term M — unique type s such that

every other valid type is an “instance” of s

◮ Uniformly replace τ ∈ s by another type

slide-36
SLIDE 36

Type checking . . .

◮ A term may admit multiple types

◮ λx.x can be of type τ → τ, (τ → τ) → (τ → τ), . . .

◮ Principal type scheme of a term M — unique type s such that

every other valid type is an “instance” of s

◮ Uniformly replace τ ∈ s by another type ◮ τ → τ is principal type scheme of λx.x

slide-37
SLIDE 37

Type checking . . .

◮ A term may admit multiple types

◮ λx.x can be of type τ → τ, (τ → τ) → (τ → τ), . . .

◮ Principal type scheme of a term M — unique type s such that

every other valid type is an “instance” of s

◮ Uniformly replace τ ∈ s by another type ◮ τ → τ is principal type scheme of λx.x

Theorem We can always compute the principal type scheme for any well-typed term in the simply typed λ-calculus.

slide-38
SLIDE 38

Computability with simple types

◮ Church numerals are well typed

slide-39
SLIDE 39

Computability with simple types

◮ Church numerals are well typed ◮ Translations of basic recursive functions (zero, successor,

projection) are well-typed

slide-40
SLIDE 40

Computability with simple types

◮ Church numerals are well typed ◮ Translations of basic recursive functions (zero, successor,

projection) are well-typed

◮ Translation of function composition is well typed

slide-41
SLIDE 41

Computability with simple types

◮ Church numerals are well typed ◮ Translations of basic recursive functions (zero, successor,

projection) are well-typed

◮ Translation of function composition is well typed ◮ Translation of primitive recursion is well typed

slide-42
SLIDE 42

Computability with simple types

◮ Church numerals are well typed ◮ Translations of basic recursive functions (zero, successor,

projection) are well-typed

◮ Translation of function composition is well typed ◮ Translation of primitive recursion is well typed ◮ Translation of minimalization requires elimination of recursive

definitions

◮ Uses untypable expressions of the form f f

slide-43
SLIDE 43

Computability with simple types

◮ Church numerals are well typed ◮ Translations of basic recursive functions (zero, successor,

projection) are well-typed

◮ Translation of function composition is well typed ◮ Translation of primitive recursion is well typed ◮ Translation of minimalization requires elimination of recursive

definitions

◮ Uses untypable expressions of the form f f

◮ Minimalization introduces non terminating computations, but

we have strong normalization!

slide-44
SLIDE 44

Computability with simple types

◮ Church numerals are well typed ◮ Translations of basic recursive functions (zero, successor,

projection) are well-typed

◮ Translation of function composition is well typed ◮ Translation of primitive recursion is well typed ◮ Translation of minimalization requires elimination of recursive

definitions

◮ Uses untypable expressions of the form f f

◮ Minimalization introduces non terminating computations, but

we have strong normalization!

◮ However, there do exist total recursive functions that are not

primitive recursive — e.g. Ackermann’s function

slide-45
SLIDE 45

Polymorphism

◮ Simply typed λ-calculus has explicit types

slide-46
SLIDE 46

Polymorphism

◮ Simply typed λ-calculus has explicit types ◮ Languages like Haskell have polymorphic types

◮ Compare id ::

a -> a with λx.x : τ → τ

slide-47
SLIDE 47

Polymorphism

◮ Simply typed λ-calculus has explicit types ◮ Languages like Haskell have polymorphic types

◮ Compare id ::

a -> a with λx.x : τ → τ

◮ Second-order polymorhpic typed lambda calculus (System F)

◮ Jean-Yves Girard ◮ John Reynolds

slide-48
SLIDE 48

System F

◮ Add type variables, a, b, . . .

slide-49
SLIDE 49

System F

◮ Add type variables, a, b, . . . ◮ Use i, j, . . . to denote concrete types

slide-50
SLIDE 50

System F

◮ Add type variables, a, b, . . . ◮ Use i, j, . . . to denote concrete types ◮ Type schemes

s ::= a | i | s → s | ∀a.s

slide-51
SLIDE 51

System F

Syntax of second order polymorphic lambda calculus

◮ Every variable and (type) constant is a term.

slide-52
SLIDE 52

System F

Syntax of second order polymorphic lambda calculus

◮ Every variable and (type) constant is a term. ◮ If M is a term, x is a variable and s is a type scheme, then

(λx ∈ s.M) is a term.

slide-53
SLIDE 53

System F

Syntax of second order polymorphic lambda calculus

◮ Every variable and (type) constant is a term. ◮ If M is a term, x is a variable and s is a type scheme, then

(λx ∈ s.M) is a term.

◮ If M and N are terms, so is (MN).

◮ Function application does not enforce type check

slide-54
SLIDE 54

System F

Syntax of second order polymorphic lambda calculus

◮ Every variable and (type) constant is a term. ◮ If M is a term, x is a variable and s is a type scheme, then

(λx ∈ s.M) is a term.

◮ If M and N are terms, so is (MN).

◮ Function application does not enforce type check

◮ If M is a term and a is a type variable, then (Λa.M) is a term.

◮ Type abstraction

slide-55
SLIDE 55

System F

Syntax of second order polymorphic lambda calculus

◮ Every variable and (type) constant is a term. ◮ If M is a term, x is a variable and s is a type scheme, then

(λx ∈ s.M) is a term.

◮ If M and N are terms, so is (MN).

◮ Function application does not enforce type check

◮ If M is a term and a is a type variable, then (Λa.M) is a term.

◮ Type abstraction

◮ If M is a term and s is a type scheme, (Ms) is a term.

◮ Type application

slide-56
SLIDE 56

System F

Example A polymorphic identity function Λa.λx ∈ a.x

slide-57
SLIDE 57

System F

Example A polymorphic identity function Λa.λx ∈ a.x Two β rules, for two types of abstraction

slide-58
SLIDE 58

System F

Example A polymorphic identity function Λa.λx ∈ a.x Two β rules, for two types of abstraction

◮ (λx ∈ s.M)N →β M{x ← N}

slide-59
SLIDE 59

System F

Example A polymorphic identity function Λa.λx ∈ a.x Two β rules, for two types of abstraction

◮ (λx ∈ s.M)N →β M{x ← N} ◮ (Λa.M)s →β M{a ← s}

slide-60
SLIDE 60

System F

◮ System F is also strongly normalizing

slide-61
SLIDE 61

System F

◮ System F is also strongly normalizing ◮ . . . but type inference is undecidable!

◮ Given an arbitrary term, can it be assigned a sensible type?

slide-62
SLIDE 62

Type inference in System F

◮ Type of a complex expression can be deduced from types

assigned to its parts

slide-63
SLIDE 63

Type inference in System F

◮ Type of a complex expression can be deduced from types

assigned to its parts

◮ To formalize this, define a relation A ⊢ M : s

◮ A is list {xi : ti} of type “assumptions” for variables ◮ Under the assumptions in A, the expression M has type s.

slide-64
SLIDE 64

Type inference in System F

◮ Type of a complex expression can be deduced from types

assigned to its parts

◮ To formalize this, define a relation A ⊢ M : s

◮ A is list {xi : ti} of type “assumptions” for variables ◮ Under the assumptions in A, the expression M has type s.

◮ Inference rules to derive type judgments of the form A ⊢ M : s

slide-65
SLIDE 65

Type inference in System F

Notation If A is a list of assumptions, A + {x : s} is the list where

◮ Assumption for x in A (if any) is overridden by the new

assumption x : s.

◮ For any variable y = x, assumption does not change

slide-66
SLIDE 66

Type inference in System F

Notation If A is a list of assumptions, A + {x : s} is the list where

◮ Assumption for x in A (if any) is overridden by the new

assumption x : s.

◮ For any variable y = x, assumption does not change

A + {x : s} ⊢ M : t A ⊢ (λx ∈ s.M) : s → t

slide-67
SLIDE 67

Type inference in System F

Notation If A is a list of assumptions, A + {x : s} is the list where

◮ Assumption for x in A (if any) is overridden by the new

assumption x : s.

◮ For any variable y = x, assumption does not change

A + {x : s} ⊢ M : t A ⊢ (λx ∈ s.M) : s → t A ⊢ M : s → t, A ⊢ N : s A ⊢ (MN) : t

slide-68
SLIDE 68

Type inference in System F

Notation If A is a list of assumptions, A + {x : s} is the list where

◮ Assumption for x in A (if any) is overridden by the new

assumption x : s.

◮ For any variable y = x, assumption does not change

A + {x : s} ⊢ M : t A ⊢ (λx ∈ s.M) : s → t A ⊢ M : s → t, A ⊢ N : s A ⊢ (MN) : t A ⊢ M : s A ⊢ (Λa.M) : ∀a.s

slide-69
SLIDE 69

Type inference in System F

Notation If A is a list of assumptions, A + {x : s} is the list where

◮ Assumption for x in A (if any) is overridden by the new

assumption x : s.

◮ For any variable y = x, assumption does not change

A + {x : s} ⊢ M : t A ⊢ (λx ∈ s.M) : s → t A ⊢ M : s → t, A ⊢ N : s A ⊢ (MN) : t A ⊢ M : s A ⊢ (Λa.M) : ∀a.s A ⊢ M : ∀a.s A ⊢ Mt : s{a ← t}

slide-70
SLIDE 70

Type inference in System F

Example Deriving the type of polymorphic identity function Λa.λx ∈ a.x

slide-71
SLIDE 71

Type inference in System F

Example Deriving the type of polymorphic identity function Λa.λx ∈ a.x x : a ⊢ x : a

slide-72
SLIDE 72

Type inference in System F

Example Deriving the type of polymorphic identity function Λa.λx ∈ a.x x : a ⊢ x : a ⊢ (λx ∈ a.x) : a → a

slide-73
SLIDE 73

Type inference in System F

Example Deriving the type of polymorphic identity function Λa.λx ∈ a.x x : a ⊢ x : a ⊢ (λx ∈ a.x) : a → a ⊢ (Λa.λx ∈ a.x) : ∀a.a → a

slide-74
SLIDE 74

Type inference in System F

◮ Type inference is undecidable for System F

slide-75
SLIDE 75

Type inference in System F

◮ Type inference is undecidable for System F ◮ . . . but we have type-checking algorithms for Haskell, ML, . . . !

slide-76
SLIDE 76

Type inference in System F

◮ Type inference is undecidable for System F ◮ . . . but we have type-checking algorithms for Haskell, ML, . . . ! ◮ Haskell etc use a restricted version of polymorphic types

◮ All types are universally quantified at the top level

slide-77
SLIDE 77

Type inference in System F

◮ Type inference is undecidable for System F ◮ . . . but we have type-checking algorithms for Haskell, ML, . . . ! ◮ Haskell etc use a restricted version of polymorphic types

◮ All types are universally quantified at the top level

◮ When we write map ::

(a -> b) -> [a] -> [b], we mean that the type is map :: ∀a, b. (a → b) → [a] → [b]

slide-78
SLIDE 78

Type inference in System F

◮ Type inference is undecidable for System F ◮ . . . but we have type-checking algorithms for Haskell, ML, . . . ! ◮ Haskell etc use a restricted version of polymorphic types

◮ All types are universally quantified at the top level

◮ When we write map ::

(a -> b) -> [a] -> [b], we mean that the type is map :: ∀a, b. (a → b) → [a] → [b]

◮ Also called shallow typing

slide-79
SLIDE 79

Type inference in System F

◮ Type inference is undecidable for System F ◮ . . . but we have type-checking algorithms for Haskell, ML, . . . ! ◮ Haskell etc use a restricted version of polymorphic types

◮ All types are universally quantified at the top level

◮ When we write map ::

(a -> b) -> [a] -> [b], we mean that the type is map :: ∀a, b. (a → b) → [a] → [b]

◮ Also called shallow typing ◮ System F permits deep typing

∀a. [(∀b. a → b) → a → a]