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>
оно будет расцениваться компилятором как ошибочное, поскольку аргумент наружного вызова функции "+" состоит из трех символов, а не из двух, как предписано ее входным форматом.Таким образом, информация о входных и выходных форматах функций позволяет находить многие ошибки в программе еще на стадии компиляции.