Class 32: Type Checking
Held Wednesday, April 21
- Group selections and presentation proposals are due today. The groups
that have come forward so far have all had three people. I'll be adding
a 4th to some groups (14 students = two groups of 3 and two groups of 4).
- If you haven't done so already, please read the chapter of Louden on
- Of the many reasons we use types, one of the most important is
in ensuring that objects are only used in ``appropriate'' places.
- Arithmetic operations should only be applied to objects on which
you can perform arithmetic (and often only to objects of an
- Values should only be assigned to variables of an equivalent type.
- The parameters to a function should only be of the appropriate
- Hence, it is important to determine when two types are equivalent
(in the senses used above).
- Often, type equivalence is attacked from a practical perspective: what
equivalencies can we reasonably determine?
- Recall the definition of
eqv? in Scheme requires
some careful consideration of when functions or pairs are equivalent.
- To answer this question, we'll consider a few basic types and variable
declarations. It is often easiest to ask whether we can assign a
variable of one type to a variable of another type. Here are some
sample types and corresponding variables.
type xy = record
xy_alias = xy;
ab = record
yx = record
abc = record
intrec = record
iarr = array[1..10] of integer;
iare = array[2..11] of integer;
rec5,rec6: record a: integer; b: real; end;
rec7: record a: integer; b: real; end;
arr3,arr4: array[1..10] of integer;
arr5: array[1..10] of integer;
- There are a number of strategies one might use to determine equivalence,
- structural equivalence,
- structural equivalence with naming,
- name equivalence, and
- declaration equivalence.
- In structural equivalence, two types are equivalent if they
have the same structure.
rec3 are structurally equivalent as
they are both pairs of (integer,real).
rec8 are not structurally equivalent,
as they order their elements differently.
- In structural equivalence under naming, two types are equivalent if
they have the same structure and the named components of each structure
have the same names.
rec3 are not structurally
equivalent under naming as they name their pairs differently.
rec6 are structurally equivalent
- In name equivalence, two types are equivalent if they are
named and have the same name.
rec2 are not name equivalent.
rec10 are name equivalent.
- In declaration equivalence, two types are equivalent if they
lead back to the same type name. This accommodates variables.
- While structural equivalence is attractive because it seems to get
closest to ``real'' equivalence, it may be difficult to determine
in the presence of pointers (explicit or implicit) and inclusion.
- As a start, consider
alpha = record
aardvark = record
beta = record
bandicoot = record
aardvark are clearly equivalent.
bandicoot? How do you tell?
- If you're willing to follow indirections, consider
listp = pointer to list;
list = record
lstp = pointer to lst;
lst = record
- What if indirections aren't direct?
gammap = pointer to gamma;
deltap = pointer to delta;
gamma = record
delta = record
- The cleverer among you might be able to prove that type equivalence
(or type constructor equivalence) is uncomputable.
- A related concept is assignment compatibility: can we safely
assign a variable of one type to another type?
- This differs from equivalence in that equivalence is bidirectional,
but assignment compatibility is unidirectional (just because you can
assign a to b, it doesn't mean that you can assign b to a).
- Assignment compatibility often makes the most sense when we think of
types as sets of values. You can assign a value in a subset to a variable
in a superset, but not vice-versa.
- Often, we may need to do some coercion when working with
values of different types. In effect, we change a value of one
type to a value of a more general type.
- When you add the integer 3 and the real number 4.5, we need to
coerce 3 to a real.
- When you print the real number 4.5, you need to coerce it to a string.
- How do we handle such issues?
- Disallow them and consider them violations of standard usage.
- Allow them, but require programmers to explicitly coerce from one
type to another.
- Allow them, and automatically determine an appropriate coercion.
- Are there reasons to make each choice? Certainly. We'll
- How do we convert, given the underlying representation?
- Interpret the bit sequence for one as if it were the bit sequence
for the other.
- Build an equivalent object.
- What kinds of coercions should we allow (explicitly or implicitly)?
- ``More general'' types to ``less general'' types?
(E.g., real to int.)
- ``Less general'' types to ``more general'' types?
(E.g., int to real.)
- What if neither type is more/less general than the other?
(E.g., two enumerated types.)
- Should we permit a loss of accuracy? If so, how do we determine
that loss of accuracy?
- If multiple coercions are possible, which should we choose? Consider
3 + "4" in languages that can convert strings to integers.
- Should we notify the programmer if we coerce?
- Should we coerce only simple types, or should we also coerce
- Instead of reflecting on ``what is'' in type systems, we might also
reflect on ``what might be''.
- What are some questions we might ask ourselves as we design a type
- Some questions have to do with the use of types.
- Do we type objects in our language?
- If so, do we type at run time, compile time, both?
- Are types explicit or implicit?
- Some questions have to do with the ``base types'' in our system.
- What primitive types do we provide?
- What compound types do we provide?
- Some questions might have to do with user-definable types in our
- Can users define new types?
- Can they define new primitive types?
- Can they define new compound types?
- Can they define new type constructors?
- Some might have to do with the interpretation of types.
- Do we treat types as having fixed-size or arbitrary-size
- Can you think of any others?
- Created Tuesday, January 19, 1999 as a blank outline.
- Filled in the details on Wednesday, April 21, 1999.
(particularly the sections on type equivalence and coercion) were based on
outline 12 of