Previous chapter: #6: Limited Types (Addition)

Dylan Design Notes: #7: Union Types (Addition)

## Dylan Design Notes

# #7: Union Types (Addition)

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.

For example:

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)))

Notes:

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)