19.3. Именные и структурные системы типов 201
У именных систем типов есть как преимущества, так и недостатки в сравнении со структурными.
Возможно, самое большое преимущество состоит в том, что имена типов в именных системах полез-
ны не только на стадии проверки типов, но и во время выполнения. В большинстве именных языков
каждый объект во время выполнения помечается словом-заголовком, которое содержит имя типа, пред-
ставленное как указатель на структуру времени выполнения, описывающую тип и указывающую на его
непосредственные надтипы. Такие метки типов полезны в нескольких отношениях, в том числе для те-
стирования во время выполнения (например, в Java, для теста instanceOf и при операции приведения
вниз), для печати, для сериализации структур данных в бинарные строки, предназначенные для хра-
нения в файлах или передачи по сети, а также для рефлексии, позволяющей программе динамически
исследовать поля и методы данного ей объекта. Метки типа, присутствующие во время выполнения, мо-
гут поддерживаться и в структурных системах (см. Glew 1999; League, Shao and Trifonov 1999; League,
Trifonov and Shao 2001, а также списки литературы в этих работах), однако там они представляют
собой дополнительный, отдельный механизм; в именных системах метки типа совпадают с типами,
проверяемыми на стадии компиляции.
Менее существенное, но тоже приятное, свойство именных систем — то, что они предлагают есте-
ственный и интуитивно ясный подход к рекурсивным типам, — типам, определение которых упоминает
сам тип. (Мы будем подробно обсуждать рекурсивные типы в Главе 20.) Такие типы встречаются при
серьезном программировании на каждом шагу, они требуются для описания таких распространенных
структур, как деревья и списки, и в именных системах они поддерживаются самым естественным из
возможных способов: сослаться на List в теле его собственного объявления так же просто, как и на лю-
бой другой тип. Даже взаимно рекурсивные типы не требуют никаких специальных усилий. Множество
имен типов рассматривается как заданное с самого начала, так что, если определение типа A упоминает
тип B, а определение типа B — тип A, не возникает вопроса, «кто из них раньше определен». Разумеет-
ся, рекурсивные типы можно описать и в структурных системах типов. Более того, высокоуровневые
языки вроде ML обычно «упаковывают» рекурсивные типы вместе с другими характеристиками си-
стемы, так что для программиста их использование выглядит так же естественно, как и в именных
языках. Однако в исчислениях, предназначенных для более фундаментальных задач, например, для
построения доказательств типовой безопасности, механизмы строгой работы с рекурсивными типами
могут оказаться достаточно громоздкими, особенно если разрешены взаимно рекурсивные типы. То,
что в именных языках мы получаем рекурсивные типы бесплатно, – несомненное преимущество.
Еще одно преимущество именных систем состоит в том, что проверка, является ли один тип подти-
пом другого, оказывается почти тривиальна. Разумеется, компилятор по-прежнему обязан проделать
работу по проверке, что объявленные отношения наследования безопасны, что, по существу, дублирует
структурное отношение наследования, но эту работу требуется проделать только один раз для каждого
типа, там, где этот тип определен, а не при каждой проверке на наследование. Поэтому в программах
проверки типов для именных систем типов несколько проще достигнуть хорошей производительно-
сти. Впрочем, в более серьезных компиляторах становится труднее определить, оказывает ли различие
между структурными и именными системами какое-либо влияние на производительность, поскольку
правильно спроектированные программы проверки типов для структурных систем включают методы
представления данных, сводящие большинство проверок на наследование к простому сравнению, — см.
стр. 178.
Наконец, еще одно часто указываемое преимущество явных объявлений наследования — то, что они
избегают «случайного включения», когда проверка типов ошибочно допускает программу, где вместо
значения одного типа используется значение другого, совместимого с первым структурно. Этот вопрос
более дискуссионен, чем предыдущие, поскольку есть другие, — вероятно, более изящные, — способы
избегать случайного включения, например, через типы данных с одним конструктором (стр. 112) или
абстрактные типы данных (Глава 24).
При всех этих преимуществах, — особенно полезны метки типа и простое обращение с рекурсивными
типами, – неудивительно, что именные системы типов более распространены в промышленных языках
программирования. С другой стороны, исследовательская литература по языкам программирования
работает почти исключительно со структурными системами типов.
Одна из непосредственных причин этого — то, что, по крайней мере без учета рекурсивных типов,
структурные системы несколько изящнее и проще. В структурной системе выражение, обозначающее
тип — замкнутая сущность; оно содержит в себе все необходимое, чтобы понять его значение. В именной
rev. 104