Top Banner
cs7120 (Prasad) L2-TypeInference 1 Type Checking and Type Inference
31

Type Checking and Type Inference

Jan 22, 2016

Download

Documents

shyla

Type Checking and Type Inference. Motivation. Application Programmers Reliability Logical and typographical errors manifest themselves as type errors that can be caught mechanically, thereby increasing our confidence in the code execution. Language Implementers - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 1

Type Checking and Type Inference

Page 2: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 2

Motivation• Application Programmers

– Reliability• Logical and typographical errors manifest themselves as

type errors that can be caught mechanically, thereby increasing our confidence in the code execution.

• Language Implementers– Storage Allocation (temporaries)

– Generating coercion code

– Optimizations

Page 3: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 3

Evolution of Type System• Typeless

– Assembly language• Any instruction can be

run on any data “bit pattern”

• Implicit typing and coercion

– FORTRAN

• Explicit type declarations

– Pascal• Type equivalence

• Weak typing– C

• Arrays (bounds not checked), Union type

• Actuals not checked against formals.

• Data Abstraction– Ada, CLU

• Type is independent of representation details.

• Generic Types– Ada, Java/C++/C#

• Compile-time facility for “container” classes.

• Reduces source code duplication.

Page 4: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 4

• Languages– Strongly typed (“Type errors always caught.”)

• Statically typed (e.g., Ada, COOL and Eiffel)– Compile-time type checking : Efficient.

• Dynamically typed (e.g., Scheme and Smalltalk)– Run-time type checking : Flexible.

– Weakly typed (e.g., C)– Unreliable Casts (int to/from pointer).

– Object-Oriented Languages such as C# and Java impose restrictions that guarantee type safety and efficiency, but bind the code to function names at run-time.

Page 5: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 5

Type inference is abstract interpretation.

( 1 + 4 ) / 2.5 int * int int 5 / 2.5 (ML-

error) (coercion) real * real real 2.0

( int + int ) / real int / real real

Page 6: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 6

Expression Grammar: Type Inference Example

E -> E + E | E * E | x | y | i | j

• Arithmetic Evaluationx, y in {…, -1.1, …, 2.3, …}i, j in {…, -1,0,1,…}

+, * : “infinite table”

• Type Inference

x, y : real i, j : int

Page 7: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 7

+,* int realint int realreal real real

int intreal real

Values can be abstracted as type names and arithmetic operations can be abstracted as operations on these type names.

Page 8: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 8

if true then “5” else 0.5

• Not type correct, but runs fine.

if true then 1.0/0.0 else 3.5

• Type correct, but causes run-time error.

Type correctness is neither necessary nor sufficient for programs to run successfully.

Page 9: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 9

Assigning types to expressions• Uniquely determined

fn s => s ^ “.\n”; val it = fn : string -> string

• Over-constrained (type error without coercion) (2.5 + 2)

• Under-constrained – Overloadingfn x => fn y => x + y; (* resolvable *)fn record => #name(record); (* error *)

– Polymorphism fn x => 1 ;

val it = fn : 'a -> int

Page 10: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 10

Type Signatures

• fun rdivc x y = x / y rdivc : real -> real -> real• fun rdivu (x,y) = x / y rdivu : real * real -> real•fun plusi x y = x + y plusi : int -> int -> int• fun plusr (x:real,y) = x + y plusr : real * real -> real

Page 11: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 11

Polymorphic Types

• Semantics of operations on data structures such as stacks, queues, lists, and tables, are independent of the component type.

• Polymorphic type system provides a natural representation of generic data structures without sacrificing type safety.

• Polymorphism fun I x = x; I 5; I “x”; for all types I:

Page 12: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 12

Composition

val h = f o g; fun comp f g = let fun h x = f (g x) in h; “Scope vs Lifetime : Closure”

comp:

– Generality– Equality constraints

Page 13: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 13

map-functionfun map f [] = [] | map f (x::xs) = f x :: map f xs

map listlist

map (fn x => 0) [1, 2, 3]map (fn x => x::[]) [“a”, “b”]

• list patterns; term matching. • definition by cases; ordering of rules

Page 14: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 14

Conventions

• Function application is left-associative.

f g h = ( ( f g ) h )• -> is right-associative. int->real->bool = int->(real->bool)• :: is right-associative. a::b::c::[] = a::(b::(c::[]))

• Function application binds stronger than ::. f x :: xs = ( f x ) :: xs

Page 15: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 15

Polymorphic Type System

Page 16: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 16

Goals• Allow expression of “for all types T”

fun I x = x

I : ’a -> ’a

• Allow expression of type-equality constraints

fun fst (x,y) = x

fst : ’a *’b -> ’a

• Support notion of instance of a type I 5

I : int -> int

Page 17: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 17

Polymorphic Type System

• Type constants int, bool, …

• Type variables ’a, …, ’’a, …

• Type constructors->, *, …

• Principal type of an expression is the most general type, which ML system infers.

Type Checking RuleType Checking Rule

An expression of a type can legally appear in all contexts where an instance of that type can appear.

Page 18: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 18

Signature of Equality = : ’a * ’a -> bool ?• Equality (“= ”) is not computable for all

types. E.g., function values.

• So types (’a,’b, …) are partitioned into • types that support equality (’’a, ’’b, …)• types that do not support equality.

= : ’’a * ’’a -> bool• int, string, etc. are equality types. They

are closed under cartesian product, but not under function space constructor.

Page 19: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 19

Type Inference

I (3,5) (3,5) (int*int)->(int*int) (int*int)

Principal type of I is the generalization of

all possible types of its uses.

Curry2 : (’a * ’b -> ’c) ->

(’a -> ’b -> ’c)

Uncurry2 : (’a -> ’b -> ’c) ->

(’a * ’b -> ’c)

Page 20: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 20

Subtle Points

• The type of a use of a function must be an instance of the principal type inferred in the definition.

• The type of a value is fixed. So, multiple occurrences of a symbol denoting the same value (such as several uses of a formal parameter in a function body) must have identical type.

Page 21: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 21

Systematic Type Derivation

fun c f g x = f(g(x))• Step1: Assign most general types to left-

hand-side arguments and the (rhs) result. f : t1 g : t2 x : t3 f(g(x)) : t4 Thus, type of c is: c: t1 -> t2 -> t3 -> t4

Page 22: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 22

• Step 2: Analyze and propagate type constraints– Application RuleApplication Rule If f x : t then x : t1 and f : t1 -> t, for some new t1.– Equality RuleEquality Rule If both x:t and x:t1 can be deduced for the value of a variable x, then t = t1.– Function RuleFunction Rule (t->u)=(t1->u1) iff (t=t1) /\ (u=u1)

Page 23: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 23

f(g x): t4

AR

(g x) : t5

f : t5 -> t4

AR

x : t6

g: t6 -> t5

ER

t1 = t5 -> t4

t2 = t6 -> t5

t3 = t6

• Step 3: Overall deduced type

c : (t5 -> t4) ->

(t6 -> t5) ->

(t6 -> t4)

(unary function

composition)

Page 24: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 24

Examplefun f x y = fst x + fst ygiven op + : int ->int -> int fst : ’a * ’b -> ’aStep 1: x: t1 y : t2 (fst_1 x + fst_2 y) : t3 The two instantiations of fst need

not have the same type. fst_1 : u1 * u2 -> u1 fst_2 : v1 * v2 -> v1

f: t1 -> t2 -> t3

Page 25: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 25

• Step 2: Applying rule for +

(fst_1 x) : int

(fst_2 y) : int

t3 = int• Step 3: fst_1 : int*u2 -> int

fst_2 : int*v2 -> int

t1 = int * u2

t2 = int * v2

f: int * ’a -> int * ’b -> int

Page 26: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 26

Example (fixed point)

fun fix f = f (fix f)

1. Assume f : ’a -> ’b

2. From (fix f = f (…)) infer

fix : (’a -> ’b) -> ’b

3. From ( ... = f (fix f)) infer

fix : (’a -> ’b) -> ’a

fix : ’a -> ’a -> ’a

Page 27: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 27

Recursive Definition (curried function)

fun f x y = f (f x) 0;

f: (int -> ’a) -> int -> ’a

fun f x y = f (f x) (f x y);

f: (’a -> ’a) -> ’a -> ’a

fun f f = f; (* identity function *) (* names of formals and functions come from disjoint namespaces *)

fun f x y = f x; (* illegal *)

fun f g = g f; (* illegal *)

Page 28: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 28

Example (ill-typed definition)fun selfApply f = f f

1. f_1:t1 (f_2 f_3):t2

selfApply : t1 -> t2

2. f_3 : t3 f_2 : t3 -> t2

3. t1 = t3 = t3 -> t2

(unsatisfiable)

(cf. val selfApply = I I)

Page 29: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 29

Problematic Case

fn x => (1, “a”);val it = fn : 'a -> int * string

fn f => (f 1, f “a”);

Type error“Least upper bound” of int and string does

not exist, and the expression cannot be typed as ((’a->’b) ->’b*’b) because the following expression is not type correct.

( (fn f => (f 1, f “a”)) (Real.Math.sqrt) );

Page 30: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 30

(cont’d)fn (x,y) => (size x, length y);val it = fn : string * 'a list -> int * int

fn z => (size z, length z);

Type Error

string and list cannot be unified to obtain ’a -> (int * int).

Or else, it will conflict with type instantiation rule, compromising type safety.

Page 31: Type  Checking  and Type  Inference

cs7120 (Prasad) L2-TypeInference 31

Equivalence?

(let val V = E in F end) =/= ((fn V => F) E)

Even though both these expressions have the same behavior, the lambda abstraction is more restricted because it is type checked independently of the context of its use. In particular, the polymorphic type variable introduced in an abstraction must be treated differently from that introduced in a local definition.