Lecture 12, CSE341, Spring 2004 summary Type Inference, Parametric Polymorphism, Type Constructors, ML Summary * Note: Type Inference and Parametric Polymorphism have an intertwined history, but they are separable concepts and orthogonal issues. * Type Inference * ML is strongly-typed, statically typed, and implicitly typed. * How types are inferred is actually straightforward: * given an expression and the types of earlier bindings, figure out "constraints" that must hold * when you get to a val-binding, give the most-general type you can * this is why variable bindings cannot be desugared to anonymous functions. * key fact: ML happens to have a type system where there is a unique most-general type * Most-general (a.k.a. principal types) may not exist for more powerful or less powerful type systems (where power here means number of terms that type-check). Or they might exist but there's no algorithm to find them; it depends on the type system. * If so, can require some annotations or infer less-general types. * Notice ML does not have subtyping. * Additional restrictions required for references. * Parametric Polymorphism * "forall types" * separate from inference: we could require explicit types on all bindings. * ML only allows "forall" "all the way on the left" * t ::= int | string | bool | t1 -> t2 | {l1:t1, ... ln:tn} | dtname | 'a | 'b | ... s ::= t | forall 'a. s (We just don't explicitly write the forall since it's implicitly on the left.) * this make type inference decidable (though still really slow in some pathological cases) * but does eliminate some perfectly sensible programs. * we have seen "forall" types make perfect sense for folds and combinators. * make much more sense than subtyping, such as java.lang.object. * they also make more sense for container types, e.g. lists and options * Type constructors * lists and options are just sugar -- programmers can define their own "container types" * type constructors take types and produce types; basically "functions" that operate on types at compile-time * they are not "forall" types, though usually you write polymoprhic functions with argument-types that are type constructors applied to type variables. * ML Summary * expression and recursion oriented * mutation rare (cycles, state) * higher-order functions * datatypes * pattern-matching * static types * polymorphic types * implicit types * module system for namespace-management, binding-hiding, and type abstraction