THE_операции
Как я уже отмечал, в Манифесте также требуется, чтобы для каждого возможного представления данного скалярного типа был "автоматически" определен набор операций, целью которых является раскрытие этого возможного представления. И для этого конкретно предлагается использовать THE_операции. Вот подходящая выдержка из Манифеста (несколько отредактированная):
Пусть PR - это возможное представление скалярного типа T, и пусть у PR имеются компоненты C1, C2, …, Cn. Определим THE_C1, THE_C2, …, THE_Cn как семейство операций таких, что для каждого i (i = 1, 2, …, n) операция THE_Ci обладает следующими свойствами:
Замечание: Термин псевдопеременная взят из PL/1. Однако помните, что псевдопеременные в PL/1 не могут быть вложенными, а THE_псевдопеременные - могут. Другими словами, мы действительно относимся к вызовам псевдопеременных как к ссылкам на переменные, из чего следует, помимо прочего, что они могут появляться в качестве аргументов других таких вызовов.
Вот пример:
TYPE TEMPERATURE POSSREP CELSIUS ( C RATIONAL ) ;
VAR TEMP TEMPERATURE ; VAR CEL RATIONAL ;
CEL : = THE_C ( TEMP ) ; THE_C ( TEMP ) : = CEL ;
В первом из этих присваиваний переменной CEL типа RATONAL присваивавется температура, соответствующая текущему значению переменной TEMP типа TEMPERATURE, преобразованная при необходимости к градусам Цельсия; во втором присваивании текущее значение переменной CEL типа RATIONAL, рассматриваемое как температура в градусах Цельсия, используется для обновления переменной TEMP типа TEMPERATURE.
Таким образом, операция THE_C раскрывает возможное представление "градусы Цельсия" температур (для целей и чтения, и обновления). Однако это возможное представление не обязательно является действительным представлением. Например, температуры могли бы реально представляться в градусах Ференгейта, а не Цельсия.
Вот слегка более сложный пример с использованием ранее определенного типа POINT:
VAR Z RATIONAL ; VAR P POINT ;
Z : = THE_X ( P ) ; THE_X ( P ) : = Z ;
В первом из этих присваиваний переменной Z типа RATIONAL присваивается координата X точки, соответствующей текущему значению переменной P типа POINT; во втором присваивании текущее значение переменной Z типа RATIONAL используется для обновления координаты X переменной P типа POINT (говоря немного вольно). Следовательно, как отмечалось ранее, операции THE_X и THE_Y раскрывают возможное представление точек на основе Декартовых координат для целей и чтения, и обновления; однако снова это возможное представление не обязательно то же, что и какое-либо действительное представление.
И еще один пример, основанный на предыдущем (здесь LINESEG обозначает отрезок прямой):
TYPE LINESEG POSSREP ( BEGIN POINT, END POINT ) ; /* начальная и конечная точки -- соответствующий */ /* селектор по умолчанию называется LINESEG */
VAR Z RATIONAL ; VAR LS LINESEG ;
Z : = THE_X ( THE_BEGIN ( LS ) ) ; THE_X ( THE_BEGIN ( LS ) ) : = Z ;
В первом из этих присваиваний переменной Z присваивается координата X точки начала текущего значения LS. Во втором присваивании текущее значение Z используется для обновления координаты X точки начала переменной LS. (Обратите внимание на вложенность псевдопеременных в этом втором присваивании.) Таким образом, операции THE_BEGIN и THE_END раскрывают возможное представление отрезков на основе "точек начала и конца" -- снова для целей и чтения, и обновления. Однако снова это возможное представление не обязательно совпадает с каким-либо реальным представлением.
Кстати, в Манифесте требуется также поддержка множественной формы присваивания.Так, например, можно использовать оператор
THE_BEGIN ( LS ) : = P , THE_END ( LS ) : = Q ;
для обновления точек начала и конца переменной отрезка LS в одной операции.