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

From Wikisource
Jump to navigation Jump to search
This page has been validated.
Sussman and Steele December 29, 1975 4 The SCHEME Reference Manual
This is the synchronization primitive. It evaluates an expression uninterruptibly; i.e. no other process may run until the expression has returned a value. Note that if a funarg is returned from the scope of an EVALUATE!UNINTERRUPTIBLY, then that funarg will be uninterruptible when it is applied; that is, the uninterruptibility property follows the rules of variable scoping. For example, consider the following function:
(DEFINE SEMGEN
    (LAMBDA (SEMVAL)
        (LIST (LAMBDA ()
                  (EVALUATE!UNINTERRUPTIBLY
                      (ASET' SEMVAL (+ SEMVAL 1))))
              (LABELS (P (LAMBDA ()
                             (EVALUATE!UNINTERRUPTIBLY
                                 (IF (PLUSP SEMVAL)
                                     (ASET' SEMVAL (- SEMVAL 1))
                                     (P)))))
                      P))))

This returns a pair of functions which are V and P operations on a newly created semaphore. The argument to SEMGEN is the initial value for the semaphore. Note that P busy-waits by iterating if necessary; because EVALUATE!UNINTERRUPTIBLY uses variable-scoping rules, other processes have a chance to get in at the beginning of each iteration. This busy-wait can be made much more efficient by replacing the expression (P) in the definition of P with

((LAMBDA (ME)
         (BLOCK (START!PROCESS (CREATE!PROCESS '(START!PROCESS ME)))
                (STOP!PROCESS ME)
                (P)))
 **PROCESS**)

Let's see you figure this one out! Note that a STOP!PROCESS within an EVALUATE!UNINTERRUPTIBLY forces the process to be swapped out even if it is the current one, and so other processes get to run; but as soon as it gets swapped in again, others are locked out as before.

Besides the AINTs, SCHEME has a class of primitives known as AMACROs. These are similar to MacLISP MACROs, in that they are expanded into equivalent code before being executed. Some AMACROs supplied with the SCHEME interpreter:

COND
This is like the MacLISP COND statement, except that singleton clauses (where the result of the predicate is the returned value) are not allowed.
AND, OR
These are also as in MacLISP.