Page:Scheme - An interpreter for extended lambda calculus.djvu/4

This page has been validated.
Sussman and Steele December 22, 1975 3 The SCHEME Reference Manual
evaluates <expression> in an environment where <identifier> is bound to a continuation which is "just about to return from the CATCH"; that is, if the continuation is called as a function of one argument, then control proceeds as if the CATCH expression had returned with the supplied (evaluated) argument as its value. For example, consider the following obscure definition of SQRT (Sussman's favorite style/Steele's least favorite):
(DEFINE SQRT
    (LAMBDA (X EPSILON)
        ((LAMBDA (ANS LOOPTAG)
             (CATCH RETURNTAG
                    (PROGN
                     (ASET 'LOOPTAG (CATCH M M))        ;CREATE PROG TAG
                     (IF (< (ABS (-$ (*$ ANS ANS) X)) EPSILON)
                         (RETURNTAG ANS)                ;RETURN
                         NIL)                           ;JFCL
                     (ASET 'ANS (//$ (+$ (//$ X ANS) ANS) 2.0))
                     (LOOPTAG LOOPTAG))))               ;GOTO
         1.0
         NIL)))

Anyone who doesn't understand how this manages to work probably should not attempt to use CATCH.

As another example, we can define a THROW function, which may then be used with CATCH much as they are in LISP:

(DEFINE THROW (LAMBDA (TAG RESULT) (TAG RESULT)))
CREATE!PROCESS
This is the process generator for multiprocessing. It takes one argument, an expression to be evaluated in the current environment as a separate parallel process. If the expression ever returns a value, the process automatically terminates. The value of CREATE!PROCESS is a process id for the newly generated process. Note that the newly created process will not actually run until it is explicitly started.
START!PROCESS
This takes one argument, a process id, and starts up that process. It then runs.
STOP!PROCESS
This also takes a process id, but stops the process. The stopped process may be continued from where it was stopped by using START!PROCESS again on it. The magic global variable **PROCESS** always contains the process id of the currently running process; thus a process can stop itself by doing (STOP!PROCESS **PROCESS**). A stopped process is garbage collected if no live process has a pointer to its process id.
EVALUATE!UNINTERRUPTIBLY