1.5.6. ОТКАТНЫЕ И БЕЗОТКАТНЫЕ ФУНКЦИИ

Все функции, определяемые и используемые в программе на Рефале Плюс делятся на две категории: откатные и безоткатные. Если функция Fname - безоткатная, то вычисление вызова <Fname Re> не может закончиться получением неуспеха. Если же функция Fname - откатная, то вычисление вызова <Fname Re> вообще говоря может закончиться получением неуспеха в качестве результата. До сих пор мы считали, что объявления функций имеют вид

$func Fname Fin = Fout;

однако это верно только в том случае, если функция Fname - безоткатная. Если же Fname - откатная, ее объявление должно иметь вид

$func? Fname Fin = Fout;

Теперь мы можем более точно описать семантику определений функций. Пусть определение функции Fname имеет вид

Fname Palt

где Palt - образцовое распутье вида

\{P1 R1; P2 R2; ... Pn Rn;}

или

{P1 R1; P2 R2; ... Pn Rn;}

, и пусть требуется вычислить ее вызов <Fname Re>. Тогда прежде всего вычисляется результатное выражение Re. Если при этом получается неуспех, то вызов функции Fname не выполняется и считается, что результатом вычисления <Fname Re> является неуспех. Предположим теперь, что в результате вычисления Re получилось объектное выражение Oe. Тогда выполняется вызов функции, а именно, вычисляется источник

Oe : Palt

в пустой среде, т.е. в среде, в которой ни одна переменная не имеет значения. Пусть в результате этого получилось значение X. Если X - объектное выражение, то X считается результатом вызова <Fname Re>. Если же X является неуспехом, то дальнейшие действия зависят от того, является ли функция Fname откатной. Если Fname - откатная, и X является неуспехом, то результатом вызова <Fname Re> считается неуспех. Если Fname - безоткатная, и X является неуспехом, то этот неуспех "перехватывается" и преобразуется в ошибку

$error(Fname "Unexpected fail").