Иногда необходимо явно контролировать представление структуры. Параметр :type позволяет выбрать представление между списком или некоторым видом вектора и указать соотвествие для размещения слотов в выбранном представлении. Структура также может быть «безымянной» или «именованной». Это означает может ли имя структуры быть сохранено в ней самой (и соответственно, прочитано из неё).
Иногда конкретное представление данных навязывается внешними требованиями и, кроме того, формат данных прекрасно ложится в структурный стиль хранения. Например, рассмотрим выражение созданное из чисел, символов и таких операций как + и *. Операция может быть представлена, как в Lisp’е, списком из оператора и двух операндов. Этот факт может быть выражен кратко в терминах defstruct:
Результатом выполнения make-binop является 3-ёх элементный список:
Выглядит как функция list за исключением того, что принимает именованные параметры и выполняет инициализацию слотов соответствующую концептуальному типу данных binop. Таким же образом, селекторы binop-operator, binop-operand-1 и binop-operand-2 эквивалентны соответственно car, cadr и caddr. (Они, конечно, не полностью эквивалентны, так как реализация может осуществлять проверки типов элементов, длины массивов при использовании селекторов слотов структур.)
Мы говорим о binop как о «концептуальном» типе данных, потому что binop не принадлежит Common Lisp’овой системе типов. Предикат typep не может использовать binop как спецификатор типа, и type-of будет возвращать list для заданной binop структуры. Несомненно, различий между структурой данных, созданной с помощью make-binop, и простым списком нет.
Невозможно даже получить имя структуры для объекта, созданного с помощью make-binop. Однако имя может быть сохранено и получено, если структура содержит «имя».
Структура с «именем» имеет свойство, которое заключается в том, что для любого экземпляра структуры можно получить имя этой структуры. Для структур определённых без указания параметра :type, имя структуры фактически становится частью Common Lisp’овой системы типов. Функция type-of при применении к экземпляру такой структуры будет возвращать имя структуры. Предикат typep будет рассматривать имя структуры, как корректный спецификатор типа.
Для структур определённых с параметром :type, type-of будет возвращать спецификатор типа один из list или (vector t), в зависимости от указанного аргумента параметра :type. Имя структуры не становится корректным спецификатором типа. Однако если также указан параметр :named, тогда первый компонент структуры всегда содержит её имя. Это позволяет получить это имя, имея только экземпляр структуры. Это также позволяет автоматически определить предикат для концептуального типа. Предикат name-p для структуры принимает в качестве первого аргумента объект и истинен, если объект является экземпляром структуры, иначе ложен.
Рассмотрим вышеупомянутый пример binop и модифицируем его, добавив параметр :named:
Как и раньше, конструкция определить функцию-конструктор make-binop и три функции-селектора binop-operator, binop-operand-1 и binop-operand-2. Она также определит предикат binop-p.
Результатом make-binop теперь является список с 4-мя элементами:
Структура имеет такую же разметку как и раньше за исключением имени структуры в первом элементе. Функции-селекторы binop-operator, binop-operand-1и binop-operand-2 эквивалентны соответственно cadr, caddr и cadddr. Предикат binop-p примерно соответствует следующему определению.
Имя binop не является корректным спецификатором типа, и не может использоваться в typep. Но с помощью предиката структура теперь отличима от других структур.
Параметр :initial-offset позволяет указывать начало размещения слотов в представлении структуры. Например, форма
создаст конструктор make-binop со следующим поведением:
Селекторы binop-operator, binop-operand-1 и binop-operand-2 будут эквивалентны соответственно caddr, cadddr, и car от cddddr. Таким же образом, форма
создаст конструктор make-binop со следующим поведением:
Если вместе с параметром :type используется :include, тогда в представлении выделяется столько места, сколько необходимо для родительской структуры, затем пропускается столько места, сколько указано в параметре :initial-offset, и затем начинается расположение элементов определяемой структуры. Например:
Первые два nil элемента пропущены по причине параметра :initial-offset со значением 2 в определении binop. Следующие четыре элемента содержат имя и три слота структуры binop. Следующие три nil элементы пропущено по причине параметра :initial-offset за значением 3 в определении структуры annotated-binop. Последние три элемента содержат три слота, определённых в структуре annotated-binop.