Who says Lisp doesn't have continuations?
In a multiprocessing Lisp we have continuations, in brute force form. So we can invert imperative code to become event driven with the use of continuations as co-routines:In the following code, dispatch-par is a function that dispatched a function to another thread. Choose your poison here -- use GCD work queues, or spawn a new thread... The ignore-errors is inserted (in my case) because I'm using a pool of worker threads and I don't want them to die because of something bad happening in the called function. Functions are expected to take a continuation as their first argument.
Example: this simple example shows the called function printing :HELLO on the background stream, then returning 15 to the caller. The second print statement is not executed.
(defclass continuation ()
()
(:metaclass funcallable-standard-class))
(defmethod initialize-instance ((c continuation) &key mbox catch-sym)
(clos:set-funcallable-instance-function
c
(lambda (v)
(mp:mailbox-send mbox v)
(throw catch-sym nil) )))
(defun call/cc (fn &rest args)
(let* ((mbox (mp:make-mailbox))
(catch-sym (gensym))
(cont (make-instance 'continuation
:mbox mbox
:catch-sym catch-sym)))
(dispatch-par (lambda ()
(catch catch-sym
(ignore-errors
(apply fn cont args)))))
(mp:mailbox-read mbox)))
(call/cc
(lambda (k)
(print :hello mp:*background-standard-output*)
(funcall k 15)
(print :hello-again mp:*background-standard-output*)))
Dr. David McClain
Chief Technical Officer
Refined Audiometrics Laboratory
4391 N. Camino Ferreo
Tucson, AZ 85750
email: dbm@refined-audiometrics.com
phone: 1.520.390.3995