110 likes | 241 Views
Type Inference II. David Walker CS 510. ML-style Polymorphism. 2 characteristics: prenex (let) polymorphism let f : all [a,b,c].t = ... in e polymorphic quantifiers appear in outermost positions polymorphic values can’t be arguments/results of functions, can’t be stored
E N D
Type Inference II David Walker CS 510
ML-style Polymorphism • 2 characteristics: • prenex (let) polymorphism • let f : all [a,b,c].t = ... in e • polymorphic quantifiers appear in outermost positions • polymorphic values can’t be arguments/results of functions, can’t be stored • reason: completeness of type inference • value restriction • let x = v in e • reason: soundness of type inference
Value restriction • Polymorphic generalization may occur over values only • Generalization over non-values causes unsoundness • Functions, lists, pairs,data cons. are values • references, expressions that raise exns, perform I/O, function applications are not • let x : (all [a]. (a -> a) ref) = ref (fn x => x) in • x := (fn x => x + 1); • (!x) true (* error *) not a value
1st-Class Polymorphism • Question: • where to generalize values with (monomorphic) schematic types to polymorphic types • eg: fn(x).fn(y).y has type • all [a].all [b]. a -> b -> b • all [a]. a -> (all [b] . b -> b) • which one do we pick? • the first can be an argument to • (int -> bool -> bool) -> bool • the second returns polymorphic functions z that can be applied to values with different types • z true; z 3
Prenex Polymorphism • Solution: • restrict to prenex quantification (type inference for the general case undecideable) • generalize at let-bound values: • a polymorphic value is always instantiated: G |- v : t, q (I,q) -> (S,{}) a1,...,an = FV(S(t)) - FV(G) G,x:all[a1,...,an].S(t) |- e : t’,q’ ------------------------------------------------------------- G |- let x = v in e : t’,q’ G(f) = all[a1,...,an].t (a1,...,an are fresh) ----------------------------------------------------- G |- f : t,{}
Advanced Type Inf • ML pushes the limit of complete type inf. • 1st-class universal and existential poly, subtyping, bounded quantification make complete type inference impossible • Nex step: Require some type annotations • goal: require annotations where useful as documentation • goal: omit type annotations where they are “obvious” and common • Most languages (Java, C++, C) require some type annotations anyway
Some Stats [PT 98] • Type instantiation occurs all the time • every third line of code • Anonymous function declarations occurs fairly often • 1/10 lines to 1/100 lines depending on style • Local variable declarations • 1/12 lines • Local functions bound to variables • 1/66 lines
Consequences • Type instantiation is the first priority • every third line of ML-style code • Anonymous function declarations are the next priority • 1/10 lines to 1/100 lines depending on style • Local variable declarations would be nice • 1/12 lines • 1/66 lines (functions)
Bi-directional Type Inf • Two interacting judgements • type checking • G |- e <= t • we can check that e has the type t • type t is an input to the judgement • type synthesis • G |- e => t • we can synthesize the most general type t from the expression e and context G • type t is an output of the judgement • Note: we have been doing type synthesis all along
More on Bi-Directional TI • ..... on your next homework!