The or (union) type specifier is understood, and is meaningfully applied in many contexts. The use of or allows assertions to be made about types in dynamically typed programs. For example:
The type assertion on the top slot ensures that an error will be signalled when there is an attempt to store an illegal value (such as :rmoved.) Although somewhat weak, these union type assertions provide a useful input into type inference, allowing the cost of type checking to be reduced. For example, this loop is safely compiled with no type checks:(defstruct box (next nil :type (or box null)) (top :removed :type (or box-top (member :removed))))
(defun find-box-with-top (box) (declare (type (or box null) box)) (do ((current box (box-next current))) ((null current)) (unless (eq (box-top current) :removed) (return current))))
Union types are also useful in type inference for representing types that are partially constrained. For example, the result of this expression:
can be expressed as (or integer cons).(if foo (logior x y) (list x y))