19.5 Enumerations
Many languages provide enumeration types both to enforce program correctness and to provide more compact representation of multiple-choice values. Dylan does not have a built-in enumeration type, but you can easily construct enumerations using the type-union and singleton type constructors.
For example, consider the <latitude> and <longitude> classes, where there are only two valid values for the direction slot in each class. Rather than enforcing the restrictions programmatically, as we did in Section 10.6, page 128, we can create types that do the job for us:
define abstract class <directed-angle> (<sixty-unit>) slot direction :: <symbol>, required-init-keyword: direction:; end class <directed-angle>; define constant <latitude-direction> = type-union(singleton(#"north"), singleton(#"south")); define class <latitude> (<directed-angle>) keyword direction:, type: <latitude-direction>; end class <latitude>; define constant <longitude-direction> = type-union(singleton(#"east"), singleton(#"west")); define class <longitude> (<directed-angle>) keyword direction:, type: <longitude-direction>; end class <longitude>;
Here, the abstract superclass specifies that the read-only slot direction must be a <symbol>, and that it must be initialized when an instance is created with the keyword direction:. The constant <latitude-direction> is a type specification that permits only the symbol #"north" or the symbol #"south". The class <latitude> specifies that, when an instance of <latitude> is made, the initial value must be of the <latitude-direction> type. We handled the longitude case similarly.
The use of type-union and singleton to create enumeration types in this fashion is common enough that the function one-of is usually available in a utility library as a shorthand:
define constant one-of
= method (#rest objects)
apply(type-union, map(singleton, objects))
end method;
With this abbreviation, the direction types can be written more compactly:
define constant <latitude-direction> = one-of(#"north", #"south"); define constant <longitude-direction> = one-of(#"east", #"west");
Some Dylan compilers will recognize the idiomatic use of type-union and singleton to represent such enumerations more compactly. For instance, a compiler could represent the direction slot of a latitude or longitude as a single bit, using the getter and setter functions to translate back and forth to the appropriate symbol.




