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