Селекторные операции
Для каждого типа данных (в частности, для любого скалярного типа) в Манифесте требуется, помимо прочего, определение операции, назначение которой состоит просто в "выборке" конкретного значения данного типа. Такие селекторные операции являются обобщением знакомого понятия литерала. (Литерал - это специальный случай вызова селектора, но не все вызовы селектора являются литералами.) Например, рассмотрим следующий фрагмент кода:
VAR X RATIONAL INIT ( +4.0 ) ; VAR Y RATIONAL INIT ( -3.0 ) ; VAR P POINT ;
P : = POINT ( X, Y ) ;
(Пример выражен на языке Tutorial D; напомним, что три месяца тому назад я говорил, что Tutorial D - это язык, определенный главным образом как средство для иллюстрации и обсуждения особенностей Манифеста. Я должен также пояснить, что везде в Манифесте мы используем более точный термин RETIONAL вместо традиционного REAL; в конце концов, числа с плавающей точкой по определению являются рациональными числами, а не действительными числами общего вида.)
Действие приведенного фрагмента кода состоит в присвоении переменной P конкретного значения POINT -- а именно, точки с Декартовыми координатами (4.0, -3.0). Выражение в правой части операции присваивания в точности представляет собой вызов селектора типа POINT; эффект вызова в точности состоит в выборе точки с указанными Декартовыми координатами. (Замечание: Если бы я написал просто POINT (4.0, -3.0) вместо POINT (X, Y), то использовал бы вызов селектора, представляющий в действительности литерал. Кроме того, для читателей, знакомых с объектными системами, я должен подчеркнуть тот факт, что в нашей модели переменная P теперь в действительности содержит точку как таковую, а не "ссылку на" точку или "объектный ID" точки. В нашей модели явно отвергаются объектные ID.)
Следовательно, заметим, что параметры данного селектора S составляют -- обязательным образом -- возможное представление PR объектов соответствующего типа T. В приведенном примере Декартовы координаты X и Y составляют возможное представление точек.
В действительности в объектных системах имеются некоторые аналоги наших селекторных операций (более обычным объектным термином является функции- конструкторы), и поэтому пользователи таких систем необходимым образом знакомы с некоторыми возможными представлениями. Однако в объектных системах, вообще говоря, не требуется, чтобы эти возможные представления раскрывались для произвольных целей. Например, пользователи могут знать на основе формата соответствующей функции-конструктора, что для точек существует возможное представление на основе Декартовых координат, но если система не обеспечивает операций для "взятия" координат X и Y для любой заданной точки, эти пользователи не смогут выполнять все разновидности простых операций. Развивая приведенный фрагмент кода, если не существует операция "get Y", то пользователь не сможет узнать, какова координата Y точки P, даже если он или она знают, что значение этой координаты есть -3.0! Другими словами, кажется, что объектная ориентация допускает не слишком разумную политику разработки.
В свете приведенных наблюдений мы решили в своем Манифесте настаивать на некоторой подходящей дисциплине. Более конкретно, мы настаиваем на следующем:
Определение скалярного типа должно включать спецификацию по меньшей мере одного возможного представления значений этого типа. Спецификация возможного представления вызывает "автоматическое" определение соответствующей селекторной операции. Поэтому заметим, что для любого возможного представления имеется соответствующий селектор (и в Tutorial D мы применяем очевидное соглашение, что любое данное возможное представление и соответствующий ему селектор имеют одно и то же имя, что подчеркивает их связь вида "рука в перчатке"). Спецификация возможного представления также вызывает "автоматическое" определение набора операций, раскрывающих это возможное представление для произвольных целей.
Вот пример (опять Tutorial D):
TYPE POINT POSSREP POINT ( X RATIONAL, Y RATIONAL ) POSSREP POLAR ( X RATIONAL, Y RATIONAL ) ;
Этот оператор определяет уже использовавшийся в предыдущих примерах тип POINT. У типа POINT имеются два возможных представления, называемых POINT (Декартовы координаты) и POLAR (полярные координаты) соответственного, и два соответствующих селектора с такими же именами. (В Tutorial D мы используем еще одно соглашение, в соответствии с которым возможное представление без собственного явно заданного имени по умолчанию наследует имя соответствующего типа; таким образом, в первой из двух спецификаций POSSREP в приведенном примере явное имя POINT можно было бы опустить.)
Конечно, в Манифесте требуется, чтобы типы кортежей и отношений также обладали селекторами. Однако для простоты здесь я буду концентрироваться на скалярных типах.