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.mohin...@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