Last active
May 19, 2016 07:36
-
-
Save vseloved/eafb2b3ab96f222c6e88d58af1374715 to your computer and use it in GitHub Desktop.
Implement generator send with restarts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(define-condition generated () | |
((item :initarg :item :reader generated-item))) | |
(defun yield (&optional item) | |
(restart-case (signal 'generated :item item) | |
(resume (&optional item) item))) | |
(defun send (item generator) | |
(let (already-triggered) | |
(handler-bind ((generated (lambda (e) | |
(declare (ignore e)) | |
(when already-triggered | |
(return-from send)) | |
(:= already-triggered t) | |
(invoke-restart (find-restart 'resume) | |
item)))))) | |
(call generator)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defun get-data () | |
(loop :repeat 3 :collect (random 10))) | |
(defun consume () | |
(let ((running-sum 0) | |
(data-items-seen 0) | |
data) | |
(loop | |
(:= data (yield)) | |
(:+ data-items-seen (length data)) | |
(:+ running-sum (reduce '+ data)) | |
(format t "Consumed ~A. The running average is ~A~%" | |
data (float (/ running-sum data-items-seen))) | |
(sleep 1)))) | |
(defun produce () | |
(loop | |
(let ((data (get-data))) | |
(format t "Produced ~A~%" data) | |
(send data 'consume)))) | |
CL-USER> (produce) | |
Produced (0 3 7) | |
Consumed (0 3 7). The running average is 3.3333333 | |
Produced (0 5 2) | |
Consumed (0 5 2). The running average is 2.3333333 | |
Produced (9 8 3) | |
Consumed (9 8 3). The running average is 6.6666665 | |
Produced (1 7 1) | |
Consumed (1 7 1). The running average is 3.0 | |
Produced (1 6 8) | |
Consumed (1 6 8). The running average is 5.0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment