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



--
Marco Antoniotti, Professor                           tel. +39 - 02 64 48 79 01
DISCo, Università Milano Bicocca U14 2043   http://dcb.disco.unimib.it
Viale Sarca 336
I-20126 Milan (MI) ITALY