Common Lisp’овая иерархия типов данных запутана и намеренно оставлена
несколько открытой, так что разработчики могут экспериментировать с
новыми типами данных в качестве расширения языка. В этом разделе чётко
оговариваются все определённые связи между типами, в том числе
отношения подтипа/супертипа, непересекаемость и исчерпывающее
разбиение. Пользователь Common Lisp’а не должен зависеть от любых
отношений, явно здесь не указанных. Например, недопустимо предположить,
что, поскольку число это не комплексное и не рациональное, то оно должно
быть float. Реализация может содержать другие виды чисел.
В первую очередь нам необходимо определить термины. Если x супертип
y, тогда любой объект типа y принадлежит также типу x, и считается, что y
подтип x. Если типы x и y не пересекаются, то ни один объект (ни в одно
реализации) не может принадлежать одновременно двум этим типам x и y.
Типы с a1 по an являются исчерпывающим множеством типа x, если
каждый aj является подтипом x, и любой объект обязательно принадлежит
одному из типов aj. a1 по an являются исчерпывающим разбиением, если они
также попарно не пересекаются.
- Тип t является супертипом всех остальных типов. Каждый объект
принадлежит типу t.
- Тип nil является подтипом любого типа. Объектов типа nil не
существует.
- Типы cons, symbol, array, number, character, hash-table,
readtable, package, pathname, stream, random-state и любой
другой тип, созданный с помощью defstruct or defclass являются
попарно непересекающимися.
Тип function не пересекается с типами cons, symbol, array,
number, and character.
Тип compiled-function является подтипом function. Реализация
может также содержать другие потипы function.
- Типы real and complex попарно непересекающиеся подтипы
number.
___________________________________________________________
Обоснование: Может показаться, что real и complex должны формировать
исчерпывающее множество типа number. Но это специально сделано не так, для
того чтобы расширения Common Lisp’а могли экспериментировать с числовой
системой.
___________________________________________________________________________________________________________
- Типы rational и float попарно непересекающиеся подтипы real.
___
Обоснование: Может показаться, что rational и float должны формировать
исчерпывающее множество типа real. Но это специально сделано не так, для того
чтобы расширения Common Lisp’а могли экспериментировать с числовой
системой.
___________________________________________________________________________________________________________
- Типы integer и ratio непересекающиеся подтипы rational.
_________
Обоснование: Может показаться, что integer и ratio должны формировать
исчерпывающее множество типа rational. Но это специально сделано не так, для
того чтобы расширения Common Lisp’а могли экспериментировать с числовой
системой.
___________________________________________________________________________________________________________
Types fixnum and bignum do in fact form an exhaustive partition of the
type integer; more precisely, they voted to specify that the type bignum is by
definition equivalent to (and integer (not fixnum)). This is consistent with
the first edition text in section 2.1.1.
I interpret this to mean that implementators could still experiment with such
extensions as adding explicit representations of infinity, but such infinities would
necessarily be of type bignum.
- Типы short-float, single-float, double-float
и long-float являются подтипами float. Любые два из них могут
быть не пересекающимися или идентичными. Если идентичные,
тогда любые другие типы между ними в перечисленном порядке
должны быть также им идентичны (например, если single-float
и long-float идентичны, то double-float должен быть также им
идентичен).
- Тип null является подтипом symbol; только один объект nil
принадлежит типу null.
- Типы cons и null являются исчерпывающими частями типа list.
- Тип standard-char является
подтипом base-char. Типы base-char и extended-char являются
исчерпывающими частями character.
- Тип string является подтипом vector. Множество всех типов
(vector c), включает себя такие типы, как например, когда c
является подтипом character.
- Тип bit-vector является подтипом vector, для bit-vector означает
(vector bit).
- Типы (vector t), string, и bit-vector являются
непересекающимися.
- Тип vector является подтипом array; для всех типов x, тип
(vector x) является тем же, что и тип (array x (*)).
- Тип simple-array является подтипом array.
- Типы simple-vector, simple-string и simple-bit-vector являются
непересекающимися подтипами simple-array, для них значит
(simple-array t (*)), множество все типов (simple-array c
(*)), в котором, например, c является подтипом character, и
(simple-array bit (*)), соответственно.
- Тип simple-vector является подтипом vector и, конечно,
подтипом (vector t).
- Тип simple-string является подтипом string. (Следует отметить,
что string является подтипом vector, simple-string не является
подтипом simple-vector.)
__________________________________________
Обоснование: The hypothetical name simple-general-vector would have been
more accurate than simple-vector, but in this instance euphony and user
convenience were deemed more important to the design of Common Lisp than a rigid
symmetry.
___________________________________________________________________________________________________________
- Тип simple-bit-vector является подтипом
bit-vector. (Следует отметить, что bit-vector является подтипом
vector, simple-bit-vector не является подтипом simple-vector.)
- Типы vector и list является непересекающимися подтипами
sequence.
- Типы random-state, readtable, package, pathname, stream и
hash-table являются попарно непересекающимися.
random-state, readtable, package, pathname, stream, and hash-table
попарно не пересекаются с другим типами. Смотрите заметку выше.
- Типы two-way-stream, echo-stream,
broadcast-stream, file-stream, synonym-stream, string-stream
и concatenated-stream являются попарно непересекающимися
подтипами stream.
- Любые два типа созданные с помощью defstruct являются
непересекающимися, если только один из них не является
супертипом для другого, в котором была указанная опция :include
с именем этого супертипа.