Page:AIM-353.djvu/13

From Wikisource
Jump to navigation Jump to search
This page has been validated.
Steele and Sussman March 10, 1976 11 LAMBDA: The Ultimate Imperative

do something like this:

begin
    integer ans;
    procedure temp(x); value x; integer x;
        ans := x;
    fact(3, temp);
    comment Now the variable "ans" has 6;
end;

Procedure fact does not return a value, nor does temp; we must use a side effect to get the answer out.

FACT is somewhat easier to use in SCHEME. We can call it like an ordinary function in SCHEME if we supply an identity function as the second argument. For example, (FACT 3 (LAMBDA (X) X)) returns 6. Alternatively, we could write (FACT 3 (LAMBDA (X) (PRINT X))); we do not care about the value of this, but about what gets printed. A third way to use the value is to write

(FACT 3 (LAMBDA (X) (SQRT X)))

instead of

(SQRT (FACT 3 (LAMBDA (X) X)))

In either of these cases we care about the value of the continuation given to FACT. Thus we care about the value of FACT if and only if we care about the value of its continuation!

We can redefine other functions to take continuations in the same way. For example, suppose we had arithmetic primitives which took continuations; to prevent confusion, call the version of "+" which takes a continuation "++", etc. Instead of writing

(- (↑ B 2) (* 4 A C))

we can write

(↑↑ B 2
    (LAMBDA (X)
            (** 4 A C
                (LAMBDA (Y)
                        (-- X Y <the-continuation>)))))

where <the-continuation> is the continuation for the entire expression.

This is an obscure way to write an algebraic expression, and we would not advise writing code this way in general, but continuation-passing brings out certain important features of the computation:

  1. The operations to be performed appear in the order in which they are performed. In fact, they must be performed in this order. Continuation-passing removes the need for the rule about left-to-right argument evaluation.