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

This page has been proofread, but needs to be validated.
Sussman and Steele December 29, 1975 13 SCHEME Programming Examples

A Useless Multiprocessing Example

One thing we might want to use multiprocessing for is to try two things in parallel, and terminate as soon as one succeeds. We can do this with the following function.

(DEFINE TRY!TWO!THINGS!IN!PARALLEL
  (LAMBDA (F1 F2)
     (CATCH C
        ((LAMBDA (P1 P2)
            ((LAMBDA (F1 F2)
                 (EVALUATE!UNINTERRUPTIBLY
                   (BLOCK (ASET 'P1 (CREATE!PROCESS '(F1)))
                          (ASET 'P2 (CREATE!PROCESS '(F2)))
                          (START!PROCESS P1)
                          (START!PROCESS P2)
                          (STOP!PROCESS **PROCESS**))))
             (LAMBDA ()
                ((LAMBDA (VALUE)
                    (EVALUATE!UNINTERRUPTIBLY
                     (BLOCK (STOP!PROCESS P2) (C VALUE))))
                 (Fl)))
             (LAMBDA ()
                ((LAMBDA (VALUE)
                    (EVALUATE!UNINTERRUPTIBLY
                     (BLOCK (STOP!PROCESS P1) (C VALUE))))
                 (F2)))))
         NIL NIL))))

TRY!TWO!THINGS!IN!PARALLEL takes two functions of no arguments (in order to pass an unevaluated expression and its environment in for later use, so as to avoid variable conflicts). It creates two processes to run them, and returns the value of whichever completes first.

As an example of how to misuse TRY!TWO!THINGS!IN!PARALLEL, here is a function which determines the sign of an integer using only ADD1, SUB1, and EQUAL.

(DEFINE SIGN
    (LAMBDA (N)
        (IF (EQUAL N 0) 'ZERO
            (TRY!TWO!THINGS!IN!PARALLEL
                (LAMBDA ()
                    (DO ((I 0 (ADD1 1)))
                        ((EQUAL I N) 'POSITIVE)))
                (LAMBDA ()
                    (DO ((I 0 (SUB1 1)))
                        ((EQUAL I N) 'NEGATIVE)))))))