Version 1, March 1993
This design note outlines a more expressive type system for Dylan. Not all types in Dylan are classes. For example, singleton types are not classes. The new type system allows for a variety of types, including classes and singleton types, and also provides a framework for introducing additional types that are not classes.
See Dylan Design Note #6: Limited Types, and Dylan Design Note #7: Union Types for descriptions of new Dylan types that are not classes.
Add a new abstract class, <type>, to be the class of all objects that represent types, i.e. obey the type protocol described below. <class> and <singleton> are subclasses of <type> and behave the same as before.
An object can be an instance of an indefinite number of types, but object-class always returns a class. The object is not an instance of any subclass of that class but it can be an instance of subtypes of that class that are not themselves classes.
The type protocol comprises the following:
The function subtype? replaces the existing function subclass?. It is mathematically a partial ordering. Type t1 is a subtype of type t2, i.e. (subtype? t1 t2) => true, if it is impossible to encounter an object that is an instance of t1 but not an instance of t2. Every type is a subtype of itself. subtype? on classes is defined by inheritance. If x is an object and t is a type, (subtype? (singleton x) t) iff (instance? x t). Each proposed new type includes detailed rules for the behavior of subtype?.
We made this change because the existing Dylan type system was not sufficiently expressive for some of the things we want to do. The two main needs for more expressive types are for documentation of the programmer's intent, and to enable more compiler optimization, especially for numeric code. It would also be nice if the return type(s) of every function described in the Dylan book could be described in Dylan's type system; this is currently not the case.
This change was based on the following principles:
We needed to define the basic structure of types before we could coherently propose adding new types. The class <type> exists because every protocol should have a corresponding abstract class so a method can be specialized to objects that support that protocol. It makes sense to rename subclass? to subtype? for consistency. The last bullet in the type protocol extends the existing statement (page 97) about singletons.
This design note does not define explicitly how users can define their own non-class types. However, if the relevant classes and generic functions are not sealed, a user can define a subclass of <type> with methods for instance?, subtype?, and make. This supports the entire Type Protocol with the exception of specializers; we could require specializers of user-defined classes to be implemented entirely in terms of the generic functions instance? and subtype?. However, this design note does not require this.
Next chapter: #6: Limited Types (Addition)