Most programming languages require all the values making up a type to be determinable during compilation, since this is a prerequisite for static type checking. If one drops the insistence that type checks should be static where possible and very simple otherwise, it becomes possible to consider whether sets of values, that vary at run-time, should be allowed to serve as types.
Such ``dynamic'' types would be very useful in database-oriented languages. For example, one would be able to declare:
Parts : set of
Suppliers : set of
Parts-supplied : Suppliers set of Parts
Since Suppliers is a variable, values of type Suppliers can be created and destroyed as time progresses, simply by including and excluding values from set Suppliers. Moreover, the domain constraint of function Parts-supplied dynamically adjusts to the creation and destruction of supplier values. (In other words, the type system takes care of referential integrity.)
Although any sets of values can make up types Parts and Suppliers, it is better not to press numeric, string, array or record values into service as part or supplier values. Parts and Suppliers are abstract data types and a means must be provided to populate them with abstract values. In other words, it must be made possible to get hold of values that belong to , but to no other set. Providing a built-in function called new comes to mind.
By making it possible to create new values at run-time and to include these values into one or more run-time sets that can serve as types, one makes it possible for types to intersect in arbitrary ways. With classical sub typing, the set of types to which a newly created value can belong can be determined by the compiler and types can only intersect if the one is a subtype of the other or if both types share a common subtype.
Prof Herman Venter