Lisp HUG Maillist Archive

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.

(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)))

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.

(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
web: http://refined-audiometrics.com



Re: Who says Lisp doesn't have continuations?

Hi,

Careful, this only works with some potentially serious restrictions: (1) This is not "full" call/cc, in the sense that you cannot invoke a continuation more than once; (2), a more serious issue, the dynamic environment gets changed when you invoke call/cc. (It may be possible to fix the latter to some extent with ContextL's first-class dynamic environments...)

Pascal

On 20 Apr 2010, at 02:08, David McClain wrote:

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.

(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)))

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.

(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
web: http://refined-audiometrics.com




-- 
Pascal Costanza, mailto:pc@p-cos.net, http://p-cos.net
Vrije Universiteit Brussel
Software Languages Lab
Pleinlaan 2, B-1050 Brussel, Belgium






Updated at: 2020-12-10 08:39 UTC