![]() | Lecture 3 - slide 38 : 43 |
; 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)