Version 1, March 1993
This design note introduces a new facility for creating a union type as a union of two other types. Union types are useful as slot specializers, and describe the return types of many common functions. For example, (union <integer> (singleton #f)) describes the return type of size.
Union types are not classes. See Dylan Design Note #5: Regularization of the Type System for a general description of types that are not classes.
Add a new facility for creating a type as a union of two other types.
union type1 type2 #key => type [Method]
Returns a type whose instances are each an instance of type1 or type2. No keyword arguments are accepted (the union method for sequences has a test: argument, hence the #key in the parameter list). This type is not instantiable.
The result of size is of type (union <integer> (singleton #f)). The result of find-method is of type (union <method> (singleton #f)). The first argument to union must be of type (union <sequence> <type>).If x is an object, s1, ..., sm, t1, ..., tn are non-union types, and the notation (union* t1 ... tn) stands for any arrangement of nested calls of union, where none of the arguments is a subtype of any other, and none of the arguments form an exhaustive partition of any other type:
(union t1 t1) = t1 (union t1 t2) = (union t2 t1) (union t1 (union t2 t3)) = (union (union t1 t2) t3) (union t1 t2) = t2 when (subtype? t1 t2) (union t1 t2) = t3 when t1 and t2 form an exhaustive partition of t3 e.g. (union <integer> <ratio>) = <rational>. (instance? x (union* t1 ... tn)) iff (or (instance? x t1) ... (instance? x tn)) (subtype? (union* t1 ... tn) s1) iff (and (subtype? t1 s1) ... (subtype? tn s1)) (subtype? s1 (union* t1 ... tn)) iff (or (subtype? s1 t1) ... (subtype? s1 tn)) (subtype? (union* s1 ... sm) (union* t1 ... tn)) iff (and (or (subtype? s1 t1) ... (subtype? s1 tn)) ... (or (subtype? sm t1) ... (subtype? sm tn)))
The union, instance?, and subtype? methods for unions are straightforward to implement. Adding unions to the method dispatch mechanism simply makes a union-specialized method applicable to each type in the union.
Dispatching to a union-specialized method should be no slower than dispatching to separate methods applicable to each type in the union, and should take less space.
Next chapter: #8: Method Dispatch Ambiguity (Clarification)