; Producer consumer - a variant where the continuation of "the other coroutine" is ; maintained in the state variable other-coroutine (define (stop-value? x) (and (boolean? x) x)) (define STOP-VALUE #t) (define NO-CONTINUATION #f) (define other-coroutine #f) (define (exchange new) (let ((old-other other-coroutine)) (set! other-coroutine new) old-other)) (define (producer) (call-with-current-continuation (lambda (exit) (let ((producer-values (list 2 3 4 5 6))) (letrec ((producer-iter (lambda (values) (cond ((null? values) (other-coroutine STOP-VALUE)) (else (let* ((new-consumer-continuation (call-with-current-continuation (lambda (here) (if other-coroutine ((exchange here) (car values)) (exit here)))))) (producer-iter (cdr values)))))))) (producer-iter (cons 'no-value producer-values))))))) (define (consumer) (letrec ((consumer-processor (lambda (x) (* x x)))) (call-with-current-continuation (lambda (exit) (letrec ((consumer-iter (lambda () (let* ((value-from-producer (call-with-current-continuation (lambda (here) ((exchange here) 'no-value)))) ) (if (stop-value? value-from-producer) '() (let ((processed-value (consumer-processor value-from-producer))) (cons processed-value (consumer-iter)))))))) (consumer-iter)))))) ; Setup: Start producer first. Assign initial-producer-cont to other-coroutine. (let ((initial-producer-cont (producer))) (set! other-coroutine initial-producer-cont) (consumer) ) ; => (4 9 16 25 36)