Chapter 5

Types and Classes

# Union Types

Union types represent the union of the instances of two or more other types. Union types are created with the function `type-union`. They are not classes.

Union types are useful as slot specializers, and describe the return types of many common functions. For example, the return type of the collection method on `size` could be expressed as `type-union(<integer>, singleton(#f))`.

```define constant <green-thing> = type-union(<frog>, <broccoli>);

define constant kermit = make(<frog>);

define method red? (x :: <green-thing>)
#f
end method;

red?(kermit)
⇒  #f
```

The following rules govern `subtype?` and `instance?` for union types.

Given

• x is an object.
• s1sm and t1tn are nonunion types.
• The notation `type-union*(t1…tn)` stands for any arrangement of nested calls to `type-union`, where none of the arguments is a subtype of any other, and none of the arguments forms an exhaustive partition of any other type.

Then

`type-union(t1, t1)` is type equivalent to t1.

`type-union(t1, t2)` is type equivalent to `type-union(t2, t1)`.

```type-union(t1, type-union(t2, t3))``` is type equivalent to `type-union(type-union(t1, t2), t3)`.

`type-union(t1, t2)` is type equivalent to t2 when `subtype?(t1, t2)`.

```instance?(x, type-union*(t1…tn))``` will be true if and only if `instance?(x, t)` is true for some t in t1tn.

`subtype?(type-union*(t1…tn), s1)` will be true if and only if `subtype?(t, s1)` is true for every t in t1tn.

```subtype?(s1, type-union*(t1…tn))``` will be true if and only if `subtype?(s1, t)` is true for some t in t1tn.

```subtype?(type-union*(s1…sm), type-union*(t1…tn))``` will be true if and only if every s in s1sm is a subtype of some t in t1tn.

Errata: In the published book, the comma between the arguments to `subtype?` is missing.