Steele and Sussman | March 10, 1976 | 11 | LAMBDA: The Ultimate Imperative |

do something like this:

begin

integerans;

proceduretemp(x); valuex; integerx;

ans:=x;

fact(3,temp);

commentNow 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:

- 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.