1.3.3. ФОРМАТЫ ФУНКЦИЙ

С чисто формальной точки зрения все функции в языке Рефал Плюс имеют ровно один аргумент и всегда выдают ровно один результат. Однако, во многих случаях, мы заранее знаем, какую структуру должны иметь аргумент и результат. Например, функция "+" всегда должна получать на входе объектное выражение, состоящее из двух символов и всегда выдает на выходе объектное выражение, состоящее из одного символа.

Ограничения, накладываемые на структуру аргументов и результатов функций, описываются с помощью объявлений функций.

Так, например, объявление функции "+" имеет вид:

$func "+" sX sY = sZ;

В общем случае объявление функции Fname имеет вид

$func Fname Fin = Fout;

где Fin входной формат функции, а Fout - ее выходной формат.

Форматы функции могут содержать символы, круглые скобки и переменные. Индексы переменных никакой информации не несут, используются в качестве комментариев и могут опускаться. Входной и выходной форматы должны быть "жесткими", т.е. на одном уровне скобок может находиться не более чем одна e-переменная. Например, формат (e)(e) является жестким, а формат e A e - не является.

Все аргументы и результаты функции должны иметь структуру,предписанную ее объявлением. Объявление функции должно предшествовать ее первому использованию в каком-либо результатном выражении в программе. При этом, если функция определена в самой программе, ее объявление появляется в тексте программы явно. Если же функция определена в другом модуле, ее объявление должно быть импортировано в программу с помощью директивы $use.

Во время компиляции программы производится проверка того, что во всех вызовах функции структура ее аргумента соответствует ее входному формату. Например, результатное выражение

<"+" 2 <"+" sX sY>>

построено правильно. По отношению ко внутреннему вызову функции это очевидно, но для того, чтобы проверить корректность наружного вызова, уже требуется привлечь информацию о структуре результата функции "+". А именно, заменяем <"+" sX sY> на выходной формат функции "+", в результате чего получается <"+" 2 s>.

Отсюда видно, что аргумент наружного вызова соответствует входному формату функции "+". С другой стороны, если мы напишем в программе результатное выражение

<"+" 2 <"+" sX sY> 3>

оно будет расцениваться компилятором как ошибочное, поскольку аргумент наружного вызова функции "+" состоит из трех символов, а не из двух, как предписано ее входным форматом.

Таким образом, информация о входных и выходных форматах функций позволяет находить многие ошибки в программе еще на стадии компиляции.