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

From Wikisource
Jump to: navigation, 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:
        (LIST (LAMBDA ()
                      (ASET' SEMVAL (+ SEMVAL 1))))
              (LABELS (P (LAMBDA ()
                                 (IF (PLUSP SEMVAL)
                                     (ASET' SEMVAL (- SEMVAL 1))

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

                (STOP!PROCESS ME)

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:

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