Download Constructed Types - Compiler Design - Lecture Slides and more Slides Computer Science in PDF only on Docsity!
Lecture #12, Feb. 21, 2007
- Basic Types
- Constructed Types
- Representing types as data
- Describing type systems as rules
- Type rules for ML
- Type equality
- Type coercions
- Sub typing
- Purpose of type systems
- Kinds of type systems
- Primitive types
- Constructed types
- Type checking
- Attribute grammars
- Inherited attributes
- Synthesized attributes
- Adding attributes to trees
- Programs for computing attribute computations.
Type Checking
• Type Checking, assigns a consistent type to every
expression and statement.
• Generally there are two kinds of types:
- Basic types: int, real, bool, string etc.
- Constructed types: array, list, products (pairs, triples, etc),
pointers, records, functions. These contain instances of other
types.
• In ML types are quite simple. Constructed types include
things like functions ( int - > string ), tuples
(intboolstring), lists (int list), etc.
• In mini Java types are more complex because of classes and
inheritance
Describing Type Systems
- A type system gives rules for assigning types to expressions and
statements based upon the types of their sub-expressions and sub-
statements.
- A standard way to talk about type systems is to use an inference
notation.
- Let S (or some other symbol) stand for a mapping from names to
types.
- Then rules are of the form:
S |- x S |- w
-------------------- (usually x & w are “sub-pieces” of y)
S |- y
- Which is read as: “To show S derives y, show S derives x, and S
derives w”.
Simple Rules
• We always have simple rules, such as:
(S x) = t
S |- x : t
and
S |- 5 : int
- To show S derives x (x a variable) has type t, show that the mapping S applied to x is t.
- And the integer 5 has type int (regardless of what's derivable from S, that’s why there is nothing above the line).
Think of S as a table. In this table we look up the types of simple objects like variables. So (S x) = t means that when we look up the type of x we find the type t
For Primitives, like constants, we just know their types.
Rules for ML expressions
(S x) = t
S |- x : t (where x = is a variable)
S |- n : int (where n = an integer constant like 5 or 23 )
S |- c : char (where c = character constant like #”a” )
S |- b : bool (where b = boolean like true or false)
ML expression types (cont)
S |- x : a
S |- f : a -> t
S |- f x : t
S |- x : t1 S |- y : t
(S <+>)= t1 * t2 -> t
----------------------------- where <+> is a binary operator like + or *
S |- x <+> y : t
Note how the domain of the function must have the same type as the actual argument.,
Assignment and If expressions
S |- x : t ref S |- y : t
S |- x := y : unit
S |- x : bool S |= s1 : t
S |- s2 : t
S |- if x then s1 else s2 : t
ML while stmt
S |- e : bool S |- s : a
S |- while e do s : unit
Implementing the Rules
- To implement the rules, use an inductive function which takes an
expression and returns a MLtype.
- Any error that occurs indicates the expression can’t be well typed.
- The mapping S is an inherited attribute.
- That means it changes as we move around the program
- If a type appears more than once in any rule, it must be the same
for all occurrences.
- This requires that we check that two types are equal.
- In an language without polymorphic types, this is simple. The
function below illustrates structural equality for types
Type Equality
fun typeeq (x,y) =
case (x,y) of
(Void,Void) => true
| (Int,Int) => true
| (Char,Char) => true
| (Bool,Bool) => true
| (Arrow(d1,r1),Arrow(d2,r2)) => typeeq(d1,d2) andalso
typeeq(r1,r2)
| (Product(ss),Product(ts)) => (listeq ss ts)
| (,) => false
and listeq (x::xs) (y::ys) =
typeeq(x,y) andalso listeq xs ys | listeq [] [] = true | listeq _ _ = false Note we need mutually recursive functions
Example
type intlist =
pointer(variant record
tag nil {},
tag cons { car : int;
cdr : intlist });
datatype 'a list =
nil | cons of 'a * 'a list;
• If we tried to compare two recursive things for
equality using structural equality we could get
into an infinite loop.
Type Coercions
- Using type systems to infer coercions.
- Sometimes we would like operators to be overloaded, so we have
to infer which one to use.
- Type checking not only annotates the tree it might insert things as
well.
typecheck:
(string -> Pascaltype) ->
(string Exp) -> (string Exp')
where Exp' is an annotated type similar to Exp but with type
annotations.
Sub Typing
- In some languages there is subtyping.
- For example the type 3 .. 12 is a subtype of the type Int.
- A function that expects an Int could take an element which was a subtype of
Int. This is called subsumption.
- Such rules might be expressed as:
S |- xi : si & (si <= ti )
S |- P : t1 * ... * tn -> Void
S |- P(x1, ... ,xn) : Void
- The type system would have to be able to check the <= relationship between
types, just as we computed type equality.
Types
- Purpose
- Types describe both the form and behavior of valid programs
- Safety
- Expressiveness
- Operator overloading
- Context sensiitve meaning
- Can’t be expressed in the syntax of the language without richer types of grammars.
- Efficiency
- By choosing implementation that depend on type information the most efficient ones can be used
- Representation information
- Types often express knowledge about how a value is represented
- How much space it takes up
- Whether it is a pointer