(defun memo-proc (proc)
(let ((has-value? nil)
(value 'unknown))
#'(lambda ()
(cond (has-value? value)
(t
(setf value (funcall proc))
(setf has-value? t)
value)))))
(defmacro delay (expression)
`(memo-proc #'(lambda () ,expression)))
(defun force (promise)
(funcall promise))
(defmacro cons-stream (head tail)
`(cons ,head (delay ,tail)))
(defun stream-car (s)
(car s))
(defun stream-cdr (s)
(force (cdr s)))
(defun stream-ref (s n)
(if (= n 0)
(stream-car s)
(stream-ref (stream-cdr s) (- n 1))))
(defun stream-map (f &rest streams)
(print (car streams))
(cons-stream
(apply f (mapcar #'stream-car streams))
(apply #'stream-map f (mapcar #'stream-cdr streams))))
(defun add-streams (&rest streams)
(apply #'stream-map #'+ streams))
;; Examples
(defvar ones (cons-stream 1 ones))
(defvar fibs
(cons-stream 0
(cons-stream 1
(add-streams fibs
(stream-cdr fibs)))))
-