|20-CS-4003-001||Organization of Programming Languages||Fall 2018|
Simple producer-consumer example
(define call/cc call-with-current-continuation) (define cont '()) (define step-and-swap (lambda (value) (call/cc (lambda (k) (let ((old cont)) (set! cont k) (old value)))))) (define addit (lambda (x) (step-and-swap x) (addit (+ x 1)))) (define looper (lambda () (step-and-swap '()) (addit 1))) (define create (lambda () (call/cc (lambda (k) (set! cont k) (looper))))) (define demand (lambda () (step-and-swap '())))
Use this code as follows:
prompt> (create) ;Value: '() prompt> (demand) ;Value: 1 prompt> (demand) ;Value: 2 prompt> (demand) ;Value: 3 ...The values returned are integers which increase in value. The producer of these values is the procedure addit which calls itself recursively with no conventional stopping condition. On each recursion the value of its argument is increased by 1. We would never see this if it weren't for step-and-swap which gets in the way and momentarily stops the computation. Every time step-and-swap is invoked (it is a continuation) addit is allowed to go one extra iteration (it is tail-recursive).
Here are the details. First, prompt> (create) grabs a current continuation and saves it in the variable cont, then looper is invoked. Procedure looper invokes (step-and-swap '()) which grabs its own continuation, saves the old continuation in old, saves its own continuation in cont and invokes the old continuation. At this point the old continuation takes us back to the first invocation of create with value '(). Hence computation ends. Now invoke prompt> (demand). This calls step-and-swap which grabs its own continuation, saves the old continuation of cont (the one going back to within looper) in old and saves its new continuation in cont. It then invokes old sending control back to looper. Procedure looper calls addit with argument 1 and the infinite loop is started.