1 / 63

Type Inference

Type Inference. David Walker COS 320. Criticisms of Typed Languages. Types overly constrain functions & data polymorphism makes typed constructs useful in more contexts universal polymorphism => code reuse modules & abstract types => code reuse subtyping => code reuse

yama
Download Presentation

Type Inference

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Type Inference David Walker COS 320

  2. Criticisms of Typed Languages • Types overly constrain functions & data • polymorphism makes typed constructs useful in more contexts • universal polymorphism => code reuse • modules & abstract types => code reuse • subtyping => code reuse • Types clutter programs and slow down programmer productivity • type inference • uninformative annotations may be omitted

  3. Type Inference • Type Inference • overview • generation of type constraints from unannotated simply-typed programs • Fun has subtyping and still needed some annotations • There is an algorithm for complete type inference for MinML without subtyping (and of course for full ML, including parametric polymorphism) • solving type constraints

  4. Type Schemes • A type scheme contains type variables (a, b, c) that may be filled in during type inference • s ::= a | int | bool | s1 -> s2 • A term scheme is a term that contains type schemes rather than proper types • e ::= ... | fun f (x:s1) : s2 = e

  5. Example fun map (f, l) = if null (l) then nil else cons (f (hd l), map (f, tl l)))

  6. Step 1: Add Type Schemes fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l), map (f, tl l))) type schemes on functions

  7. Step 2: Generate Constraints fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l), map (f, tl l))) for each expression, perform type inference on sub expressions, assigning them type schemes and generating constraints that must be solved

  8. Step 2: Generate Constraints fun map (f : a, l : b) : c = if null (l)then nil else cons (f (hd l), map (f, tl l))) begin with the if expression & recursively perform type inference on its subexpressions

  9. Step 2: Generate Constraints fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l), map (f, tl l))) b = b’ list since argument to null must be a list

  10. Step 2: Generate Constraints constraints b = b’ list fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l), map (f, tl l))) : d list since nil is some kind of list

  11. Step 2: Generate Constraints constraints b = b’ list fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l), map (f, tl l))) : d list b = b’’’ list b = b’’ list since hd and tl are functions that take list arguments

  12. Step 2: Generate Constraints constraints b = b’ list b = b’’ list b = b’’’ list fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l : b’’), map (f, tl l : b’’’ list))) : d list a = a b = b’’’ list

  13. Step 2: Generate Constraints constraints b = b’ list b = b’’ list b = b’’’ list a = a b = b’’’ list fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l : b’’) : a’, map (f, tl l) : c)) : d list a = b’’ -> a’

  14. Step 2: Generate Constraints constraints b = b’ list b = b’’ list b = b’’’ list a = a b = b’’’ list a = b’’ -> a’ fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l : b’’) : a’, map (f, tl l) : c)) : c’ list : d list c = c’ list a’ = c’

  15. Step 2: Generate Constraints constraints b = b’ list b = b’’ list b = b’’’ list a = a b = b’’’ list a = b’’ -> a’ c = c’ list a’ = c’ fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l : b’’) : a’, map (f, tl l) : c)) : c’ list : d list d list = c’ list

  16. Step 2: Generate Constraints constraints b = b’ list b = b’’ list b = b’’’ list a = a b = b’’’ list a = b’’ -> a’ c = c’ list a’ = c’ d list = c’ list fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l : b’’) : a’, map (f, tl l) : c)) : c’ list : d list : d list d list = c

  17. Step 2: Generate Constraints final constraints b = b’ list b = b’’ list b = b’’’ list a = a b = b’’’ list a = b’’ -> a’ c = c’ list a’ = c’ d list = c’ list d list = c fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l), map (f, tl l)))

  18. Step 3: Solve Constraints • Constraint solution provides all possible solutions to type scheme annotations on terms final constraints b = b’ list b = b’’ list b = b’’’ list a = a ... map (f : a -> b x : a list) : b list = ... solution a = b’ -> c’ b = b’ list c = c’ list

  19. Step 4: Generate types • Generate types from type schemes • Option 1: pick an instance of the most general type when we have completed type inference on the entire program • map : (int -> int) -> int list -> int list • Option 2: generate polymorphic types for program parts and continue (polymorphic) type inference • map : ForAll (a,b,c) (a -> b) -> a list -> b list

  20. Type Inference Details • Type constraints q are sets of equations between type schemes • q ::= {s11 = s12, ..., sn1 = sn2} • eg: {b = b’ list, a = b -> c}

  21. Constraint Generation • Syntax-directed constraint generation • our algorithm crawls over abstract syntax of untyped expressions and generates • a term scheme • a set of constraints • Algorithm defined as set of inference rules • programming notation: tc(G, u) = (e, t, q) • math notation: G |-- u => e : t, q outputs inputs

  22. Constraint Generation G |-- x ==> x : G |-- 3 ==> 3 : G |-- true ==> true : G |-- false ==> false :

  23. Constraint Generation G |-- x ==> x : s, { } (if G(x) = s) G |-- 3 ==> 3 : G |-- true ==> true : G |-- false ==> false :

  24. Constraint Generation G |-- x ==> x : s, { } (if G(x) = s) G |-- 3 ==> 3 : int, { } G |-- true ==> true : G |-- false ==> false :

  25. Constraint Generation G |-- x ==> x : s, { } (if G(x) = s) G |-- 3 ==> 3 : int, { } G |-- true ==> true : bool, { } G |-- false ==> false : bool, { }

  26. Operators ------------------------------------------------------------------------ G |-- u1 + u2 ==>

  27. Operators G |-- u1 ==> G |-- u2 ==> ------------------------------------------------------------------------ G |-- u1 + u2 ==>

  28. Operators G |-- u1 ==> e1 G |-- u2 ==> e2 ------------------------------------------------------------------------ G |-- u1 + u2 ==>

  29. Operators G |-- u1 ==> e1 G |-- u2 ==> e2 ------------------------------------------------------------------------ G |-- u1 + u2 ==> e1 + e2

  30. Operators G |-- u1 ==> e1 G |-- u2 ==> e2 ------------------------------------------------------------------------ G |-- u1 + u2 ==> e1 + e2 : int

  31. Operators G |-- u1 ==> e1 : t1, q1 G |-- u2 ==> e2 : ------------------------------------------------------------------------ G |-- u1 + u2 ==> e1 + e2 : int, q1 U {t1 = int}

  32. Operators G |-- u1 ==> e1 : t1, q1 G |-- u2 ==> e2 : t2, q2 ------------------------------------------------------------------------ G |-- u1 + u2 ==> e1 + e2 : int, q1 U q2 U {t1 = int, t2 = int}

  33. Operators ------------------------------------------------------------------------ G |-- u1 < u2 ==>

  34. Operators G |-- u1 ==> e1 : t1, q1 G |-- u2 ==> e2 : t2, q2 ------------------------------------------------------------------------ G |-- u1 < u2 ==> e1 < e2 : bool,

  35. Operators G |-- u1 ==> e1 : t1, q1 G |-- u2 ==> e2 : t2, q2 ------------------------------------------------------------------------ G |-- u1 < u2 ==> e1 < e2 : bool,

  36. Operators G |-- u1 ==> e1 : t1, q1 G |-- u2 ==> e2 : t2, q2 ------------------------------------------------------------------------ G |-- u1 < u2 ==> e1 + e2 : bool, q1 U q2 U {t1 = int, t2 = int}

  37. If statements ---------------------------------------------------------------- G |-- if u1 then u2 else u3 ==>

  38. If statements G |-- u1 ==> e1 : t1, q1 G |-- u2 ==> e2 : t2, q2 G |-- u3 ==> e3 : t3, q3 ---------------------------------------------------------------- G |-- if u1 then u2 else u3 ==> if e1 then e2 else e3 :

  39. If statements G |-- u1 ==> e1 : t1, q1 G |-- u2 ==> e2 : t2, q2 G |-- u3 ==> e3 : t3, q3 ---------------------------------------------------------------- G |-- if u1 then u2 else u3 ==> if e1 then e2 else e3 : a, q1 U q2 U q3 U {t1 = bool, a = t2, a = t3}

  40. Function Application G |-- u1 ==> e1 : t1, q1 G |-- u2 ==> e2 : t2, q2 ---------------------------------------------------------------- G |-- u1 u2==> e1 e2 : a, q1 U q2 U {t1 = t2 -> a}

  41. Function Application G |-- u1 ==> e1 : t1, q1 G |-- u2 ==> e2 : t2, q2 ---------------------------------------------------------------- G |-- u1 u2==> e1 e2 : a,

  42. Function Declaration G, f : a -> b, x : a |-- u ==> e : t, q ---------------------------------------------------------------- G |-- fun f(x) is u end ==> fun f (x : a) : b is e end : a -> b, q U {t = b}

  43. Function Declaration G, f : a -> b, x : a |-- u ==> e : t, q ---------------------------------------------------------------- G |-- fun f(x) = u ==> fun f (x : a) : b = e :

  44. Solving Constraints • A solution to a system of type constraints is a substitution S • a function from type variables to type schemes, eg: • S(a) = a • S(b) = int • S(c) = a -> a

  45. Substitutions • Applying a substitution S: substitute(S,int) = int substitute(S,s1 -> s2) = substitute(s1) -> substitute(s2) substitute(S,a) = s (if S(a) = s) Due to laziness, I will write S(s) instead of substitute(S, s)

  46. Unification • Unification: An algorithm that provides the principal solution to a set of constraints (if one exists) • Unification systematically simplifies a set of constraints, yielding a substitution • Starting state of unification process: (Id,q) • Final state of unification process: (S, { })

  47. Unification Machine • We can specify unification as a rewriting system: • Given (S, q), systematically pick a constraint from q and simplify it, possibly adding to the substitution • Use inductive definitions to specify rewriting. • Judgment form: • (S,q) -> (S’,q’)

  48. Unification Machine • Base types & simple variables: -------------------------------- (S,{int=int} U q) -> ???

  49. Unification Machine • Base types & simple variables: -------------------------------- (S,{int=int} U q) -> (S, q)

  50. Unification Machine • Base types & simple variables: -------------------------------- (S,{int=int} U q) -> (S, q) ------------------------------------ (S,{bool=bool} U q) -> ??? ----------------------------- (S,{a=a} U q) -> ???

More Related