Steele and Sussman | March 10, 1976 | 13 | LAMBDA: The Ultimate Imperative |
Escape Expressions
Reynolds [Reynolds 72] defines the construction
escape x in r
to evaluate the expression r
in an environment such that the variable x
is bound to an escape function. If the escape function is never applied, then the value of the escape expression is the value of r
. If the escape function is applied to an argument a, however, then evaluation of r
is aborted and the escape expression returns a. {Note J-operator} (Reynolds points out that this definition is not quite accurate, since the escape function may be called even after the escape expression has returned a value; if this happens it "returns again"!)
As as example of the use of an escape expression, consider this procedure to compute the harmonic mean of an array of numbers. If any of the numbers is zero, we want the answer to be zero. We have a function harmsum
which will sum the reciprocals of numbers in an array, or call an escape function with zero if any of the numbers is zero. (The implementation shown here is awkward because ALGOL requires that a function return its value by assignment.)
begin
real procedure harmsum(a, n, escfun);
real array a; integer n; real procedure escfun(real);
begin
real sum;
sum := 0;
for i := 0 until n-1 do
begin
if a[i]=0 then escfun(0);
sum := sum + 1/a[i];
end;
real array b[0:99];
print(escape x in 100/harmsum(b, 100, x));
end
If harmsum
exits normally, the number of elements is divided by the sum and printed. Otherwise, zero is returned from the escape expression and printed without the division ever occurring.
This program can be written in SCHEME using the built-in escape operator CATCH
: