Back to lecture notes -- Keyboard shortcut: 'u'                      Lecture 3 - slide 38 : 43
 

; Producer consumer - functional programming variant.

(define (stop-value? x) (and (boolean? x) x))  
(define STOP-VALUE #t)
(define NO-CONTINUATION #f)

(define (producer initial-consumer-continuation)
  (call-with-current-continuation
    (lambda (exit)
       (let ((producer-values (list 2 3 4 5 6)))  
         (letrec ((producer-iter  
                    (lambda (values consumer-continuation)
                      (cond ((null? values) (consumer-continuation (cons STOP-VALUE NO-CONTINUATION)))   
                            (else 
                              (let* ((new-consumer-continuation
                                      (call-with-current-continuation       
                                       (lambda (here)
                                         (if consumer-continuation
                                             (consumer-continuation (cons (car values) here)) 
                                             (exit here)))))) 
                                (producer-iter (cdr values) new-consumer-continuation)))))))
            (producer-iter (cons 'no-value producer-values) initial-consumer-continuation))))))

(define (consumer initial-producer-continuation)
 (letrec ((consumer-processor (lambda (x) (* x x)))) 
  (call-with-current-continuation
    (lambda (exit)
      (letrec ((consumer-iter  
                (lambda (producer-continutation)
                  (let* ((from-producer (call-with-current-continuation  
                                         (lambda (here)
                                           (producer-continutation here)))) 
                         (value-from-producer (car from-producer))
                        )
                    (if (stop-value? value-from-producer)
                        '()
                        (let ((processed-value (consumer-processor value-from-producer))  
                              (new-producer-continuation (cdr from-producer))
                             )
                          (cons processed-value (consumer-iter new-producer-continuation)))))))) 
        (consumer-iter initial-producer-continuation))))))


; Setup: Start producer first. Pass initial-producer-cont to consumer.
(let ((initial-producer-cont (producer NO-CONTINUATION)))  
  (consumer initial-producer-cont) 
)  ; => (4 9 16 25 36)