Thanks.
My brain was not working AND I did not do the necessary RTFM of SICP. The
(let ((somestuff nil)) (setf somestuff (something-with-somestuff-closed-over-and-delayed)))
works of course.
The rest is easy macrology.
All the best
Marco
On Tue, Dec 14, 2021 at 6:44 AM Vibhu Mohindra vibhu.mohindra@gmail.com wrote:
Hi Marco,
The last function below is the Common Lisp equivalent. The function before that contains the essence of it. Because cons-stream's second arg is evaluated only much later, by the time it is evaluated the setf has completed and int has been fully installed. (SICP section 4.1.6 shows that Scheme's inner defines are really just syntactic sugar for the same kind of thing.)
;SICP doesn't delay cars (defstruct my-stream delayed-car delayed-cdr)
(defvar *to-init* (gensym))
;SICP's memo-proc approach avoids creating memo symbols (defmacro delay (x) (let ((memo (gensym))) `(let ((,memo *to-init*)) #'(lambda () (cond ((eql ,memo *to-init*) (setf ,memo ,x)) (t ,memo)))))) (defun force (delayed-val) (funcall delayed-val))
(defmacro cons-stream (x y) `(make-my-stream :delayed-car (delay ,x) :delayed-cdr (delay ,y)))
(defvar *stream-nil* (gensym))
(defun stream-car (s) (force (my-stream-delayed-car s))) (defun stream-cdr (s) (force (my-stream-delayed-cdr s))) (defun stream-null (s) (eql s *stream-nil*))
(defun example1 (x) (let ((int nil)) (setf int (cons-stream x int)))) ; (stream-car (stream-cdr (stream-cdr (rec-stream 'a)))) ; -> A
; omitting defs of add-streams scale-stream (defun integral (integrand initial-value dt) (let ((int nil)) (setf int (cons-stream initial-value (add-streams (scale-stream integrand dt) int)))))
-- Vibhu