Logo

26 января 2014 г.

Общий и чистый вызовы

Рассмотренная ранее трактовка параметров функций в Канторе объединяет понятие вызова функции с трактовкой порожденных функций как синонимов. На уровне модели (байт-кода) обобщенная форма обращения к функциям носит название общего вызова.

Обращение к чистым функциям, четко разделяемое на левую и правую части, может быть записано в альтернативной, более привычной форме, — при помощи оператора сопоставления (знака равенства). Форма записи в виде оператора сопоставления называется в Канторе чистым вызовом.

Упоминание общего и чистого вызова уже встречалось в статье про параметры, но их раскрытие было временно отложено с расчетом описать в отдельной статье, которую вы сейчас и читаете.

Общий вызов

Предположим, что имеется функция, возвращающая название страны по числовому коду ISO. Пусть ее объявление выглядит так:
countryName(out :Core:String; :Core:ShortWord);
Объявлена out-функция (чистая) в абстрактной форме — без реализации. На практике функция может быть реализована разными способами, в том числе и памятью — как массив строк.

Вне зависимости от реализации получение названия России при помощи этой функции в форме общего вызова записывается следующим образом:
countryName(russia, 643);
Трактовка этой записи не совсем привычна: здесь в общей форме записан оператор сопоставления, объявляющий локальную функцию-синоним russia, результатом которой является чистый вызов countryName[643].

Понятие общего вызова Канторе наиболее близко оператору defun в Лиспе: объявляемое имя в нем так же пишется внутри скобок, что соответствует внутреннему представлению Лиспа.

Форма общего вызова, как следует из названия, принята в Канторе в качестве основы, — в байт-коде функции хранятся «как в Лиспе». Однако, поскольку такая запись не отвечает формальному понятию удобства с точки зрения когнитивной психологии1, да и попросту непривычна большинству программистов, для чистых вызовов в Канторе предусмотрена также традиционная форма.

Чистый вызов

В чистой форме функция получения названия России выглядит вполне привычно:
russia = countryName[643];
Обратите внимание, что данная форма чистого вызова полностью эквивалентна рассмотренному ранее общему вызову, приведенная выше трактовка общего вызова применима и к чистому вызову, а в байт-коде обе записи будут идентичны — «как в Лиспе». Обратимость байт-кода позволяет иметь несколько форм записи, выбирая нужную при отекстовке.

Синтаксические правила чистого вызова просты:
  • Чистый вызов возможен только для чистых функций (out-функций). Правила объявления чистых функций описаны в статье про параметры.
  • При объявлении функции out-параметры должны идти первыми в списке параметров. Попытка разместить out-параметры в середине или в конце списка вызовет ошибку компиляции, если только функция не импортируется из внешней библиотеки (написанной не на Канторе).
  • Вызов чистой функции может быть записан в виде оператора сопоставления, в левой части которого стоят сопоставляемые имена (синонимы или переменные), а в правой — вызов функции с входными параметрами.

Круглые и квадратные скобки

Для синтаксического выделения чистых вызовов и лучшего восприятия их программистом используются круглые и квадратные скобки:
  • Круглые скобки соответствуют общему вызову. Внутри круглых скобок могут стоять как входные, так и выходные и мутирующие параметры (out-, и var-параметры).
  • Квадратные скобки могут использоваться только в чистых вызовах. Внутри квадратных скобок могут стоять только входные параметры.
Таким образом, квадратные скобки являются дополнительным признаком чистого вызова, страхуя программиста от нежелательных побочных эффектов в функциях. Попытка передать в квадратных скобках out- или var-параметр вызовет ошибку компиляции.

Для функций-кортежей, возвращающих несколько значений, в Канторе допустима промежуточная форма вызова, записываемая со знаком равенства, но часть out-параметров при этом остается справа:
// некая функция
countryCodeAndName(out :Core:String[2] code; out :Core:String name;
  :Core:ShortWord numericCode);

// вызовы
ru = countryAndCodeName(russia, 643); // частичное сопоставление
(by, belarus) = countryCodeAndName[112]; // полное сопоставление
Оба вызова являются чистыми, но попытка записать частичное сопоставление с квадратными скобками вызовет ошибку компиляции.

Возможность чистого вызова как показатель качества кода

Строгие правила чистых вызовов позволяют использовать их как показатель качества кода, поощряя тем самым использование именно функционального стиля, что важно для мультипарадигменного языка. Злоупотребление переменными, излишние побочные эффекты, использование циклов вместо контейнерной арифметики, — всё это не только может быть посчитано путем статистического (статического) анализа байт-кода, но и будет наблюдаться визуально — в том числе и как отсутствие чистых вызовов там, где они могли бы быть.

Предполагается, что умолчательные настройки отекстовщика будут генерировать максимально строгий код, способствуя тем самым повышению общего качества кода и распространению лучших практик программирования среди бо́льшего числа разработчиков.


1 Попросту говоря, глаза разбегаются.

Комментариев нет :

Отправить комментарий

Выбрав в выпадающем списке пункт «Имя/URL», можно оставить комментарий от своего имени без предварительной регистрации.