Я думаю, что важно уйти от реализации вещей, и вместо этого сосредоточиться на том, как язык думает о них.Очевидно, что реализация должна иметь достаточно информации, чтобы знать, что представляет собой данный объект, и она будет делать это с неким «тегом» (который может быть или не быть некоторыми дополнительными битами, прикрепленными к объекту - некоторые изэто могут быть, например, ведущие биты адреса).Ниже я назвал это «представительский тип».Но вы действительно почти не имеете доступа к этой детали реализации из языка.Заманчиво думать, что type-of
говорит вам что-то, что отображает 1-1 на тип представления, но это не так: (type-of (cons 1 2)
разрешено, например, возвращать (cons integer integer)
, и я думаю, что, вероятно, разрешено возвращать (cons integer number)
или (cons (integer 1 1) (integer 2 2))
.Маловероятно, что существуют разные репрезентативные типы для всех этих: действительно, не может быть, поскольку (type-of 1)
может возвращать (integer m n)
для бесконечного числа значений m
& n
.
Итак, рассмотрим, как язык думает о вещах, и различия между классами и типами в CL.
И система типов, и система классов состоят из ограниченной решетки типов / классов.Быть решеткой означает, что для любой пары объектов существует уникальный супремум (так, для типов, уникальный тип, оба типа которых являются подтипами, и который не имеет подтипов, для которых это верно) и инфимум(обратное). ограниченный означает, что есть верхний и нижний тип / класс.
Классы
- Классы являются первоклассными объектами (вы можете хранить класс внапример, переменная).
- Все объекты (включая классы) принадлежат классу, и существует четко определенный оператор для нахождения непосредственного класса, к которому принадлежит любой объект.
- Естьконечное число классов.
- Класс объекта довольно близко соответствует его типу представления, но не полностью (могут быть специализированные типы массивов, которые, например, не имеют соответствующих классов).
- Классы могут служить типами:
(type-of 1 (class-of 1))
работает, как и (subtypep (class-of 1) '(integer 0 1))
(ответы: t
и nil, t
соответственно).
Типы
Типы - это способыобозначают коллекции объектов с общими свойствами, но сами они не являются объектами: они, во всяком случае, просто имена для коллекций вещей - спецификация языка называет эти «спецификаторы типа».В частности существует бесконечное количество типов : например, тип (integer m n)
.Небольшое количество этой бесконечности типов соответствует репрезентативным типам - фактической информации, которая сообщает системе, что это за вещь - но, очевидно, большинство из них этого не делают.Могут быть типы представлений, которые не имеют соответствующих типов.
Типы на практике служат трем целям, я думаю.
- Информация о типах может рассказать системе о том, какие представительные типы использовать, которые могутпомогите ему проверить, что вещи имеют правильный тип представления, и оптимизировать вещи.
- Информация о типе может позволить системе сделать выводы, которые могут существенно помочь.
- Информация о типе может позволить программистам говорить о том, какого родавещи, с которыми они имеют дело, даже когда эта информация не помогает системе.Система может рассматривать такие объявления как утверждения о типах, которые могут сделать программы более безопасными и более простыми в отладке.Это важная причина для типов: даже если система не проверяет их, человеку, читающему ваш код, полезно знать, что он ожидает, скажем, целое число в [0, 30], то есть
(integer 0 30)
.Действительно, даже если система не выполняет автоматическую проверку объявлений, вы можете выполнить принудительную проверку, скажем, (check-type x '(integer 0 30) ...)
.
Второй случай интересен.Допустим, у меня есть кое-что, что, как я сказал, система имеет тип (double-float 0.0d0)
.Это вряд ли будет более полезным с точки зрения репрезентативного типа, чем double-float
.Но если я возьму квадратный корень этой вещи, то знание этого типа может быть действительно очень полезным: система может знать, что результатом является double-float
, а не (complex double-float)
, и эти типы крайне маловероятно представляютсятак же.Таким образом, система может использовать мое объявление типа, чтобы сделать выводы таким образом (и эти выводы могут каскадно проходить через программу).Обратите внимание, что классы не могут сделать это (по крайней мере, классы CL не могут), как и тип представления объекта: вам нужно больше информации, чем это.
Так что да,типы служат ряду очень полезных целей, которые не удовлетворяются классами.