Class notes for Monday, March 20, 2006 Introduction to type checking ------------------------------------------------------------------------------ Type expressions ::= int | bool | ( * * ... * -> ) Base types: int bool Function types: (int -> bool) (int * int -> int) (int * int * int -> bool) (int -> (int -> int)) (int * int * (int * int -> bool) -> bool) ((int -> int) -> (int -> int)) Example: (define fact (Y (lambda (r) (lambda (n) (if (= n 0) 1 (* n (r (- n 1)))))))) (fact 5) => 120 What can we deduce about the type of Y in the above expression? fact : (int -> int) r : (int -> int) (lambda (n) ...) : (int -> int) (lambda (r) ...) : ((int -> int) -> (int -> int)) Y : (((int -> int) -> (int -> int)) -> (int -> int)) ------------------------------------------------------------------------------ Grammar for a simple typed language ::= | | ( ) | (if ) | (let (( )*) ) | (fun (*) -> ) | ( *) ::= ( ) in {+, -, *, /, ^, >, <, =} The only difference is that the formal parameters of fun expressions are now labeled according to their type. For example: (fun ((int n) (bool b) ((int -> int) f)) -> (f n)) We will store types in a "type environment" called tenv, which maps symbols to type expressions such as int, bool, or (int * int -> bool). Typing rules for each category of expression in our language are given below. ----------------------------------------------------------------------------- Example: 3 => int Typing rule: (type-of tenv) = int ----------------------------------------------------------------------------- Examples: true => bool square => (int -> int) not => (bool -> bool) Typing rule: (type-of tenv) = (lookup-type tenv) ----------------------------------------------------------------------------- ::= ( ) Example: (2 + 3) => int Typing rule: IF these conditions hold: (type-of tenv) = t1 (type-of tenv) = t2 (type-of tenv) = (t1 * t2 -> t) - - - - - - - - - - - - - - - - - - - - - - - - - THEN we can conclude: (type-of tenv) = t ----------------------------------------------------------------------------- ::= (let (( ) ( ) ... ( )) ) Example: (let ((x 3)) x) => int Typing rule: (type-of tenv) = t1 (type-of tenv) = t2 ... (type-of tenv) = tN - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (type-of tenv) = (type-of extended-tenv) where extended-tenv is (extend tenv ( ... ) (t1 t2 ... tN)) ----------------------------------------------------------------------------- ::= (if ) Examples: (if true 1 2) => int (if true 1 false) => ERROR! (if 0 1 2) => ERROR! Typing rule: (type-of tenv) = bool (type-of tenv) = t (type-of tenv) = t - - - - - - - - - - - - - - - - - (type-of tenv) = t ----------------------------------------------------------------------------- ::= ( ... ) Examples: (square 3) => int (not true) => bool Typing rule: (type-of tenv) = (t1 * t2 * ... * tN -> t) (type-of tenv) = t1 (type-of tenv) = t2 ... (type-of tenv) = tN - - - - - - - - - - - - - - - - - - - - - - - - - - - (type-of tenv) = t ----------------------------------------------------------------------------- ::= (fun (( ) ( ) ... ( )) -> ) Examples: (fun ((int x) (int y)) -> (not (x = y))) => (int * int -> bool) (fun ((int n)) -> (if (n = 0) square cube)) => (int -> (int -> int)) Typing rule: (type-of extended-tenv) = t where extended-tenv is (extend tenv ( ... ) ( ... )) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (type-of tenv) = ( * * ... * -> t) -----------------------------------------------------------------------------