I'm having trouble running an example code from SICP (Structure and Interpretation of Computer Programs) Section 3.5.4 (Streams and Delayed Evaluation); the SICP section can be found here: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-24.html#%_sec_3.5.4.
I'm using DrRacket version 5.2.1, set up with the SICP support language by Neil Van Dyke (SICP PLaneT 1.17), which can be found here: http://www.neilvandyke.org/racket-sicp/#%28part._installation%29.
The code, shown below, makes use of streams. With the environment set up as above, the procedures cons-stream
, force
and delay
are already available from DrRacket. But stream-car
and stream-cdr
weren't available; so, I had to define them. In the code below, I also define some generic stream functions: stream-map
, stream-ref
, add-streams
and scale-stream
.
The whole code I'm trying to make work is the following. It includes a procedure to solve first-order differential equations numerically (solve
), using an integration procedure (integral
), which uses a delayed argument (delayed-integrand
); these procedures come from Section 3.5.4.
(define (stream-car stream) (car stream))
(define (stream-cdr stream) (force (cdr stream)))
(define (stream-map proc . argstreams)
(if (stream-null? (car argstreams))
the-empty-stream
(cons-stream
(apply proc (map stream-car argstreams))
(apply stream-map
(cons proc (map stream-cdr argstreams))))))
(define (stream-ref s n)
(if (= n 0)
(stream-car s)
(stream-ref (stream-cdr s) (- n 1))))
(define (add-streams s1 s2)
(stream-map + s1 s2))
(define (scale-stream stream factor)
(stream-map (lambda (x) (* x factor)) stream))
(define (integral delayed-integrand initial-value dt)
(define int
(cons-stream initial-value
(let ((integrand (force delayed-integrand)))
(add-streams (scale-stream integrand dt)
int))))
int)
(define (solve f y0 dt)
(define y (integral (delay dy) y0 dt))
(define dy (stream-map f y))
y)
When I put the definitions above in DrRacket and click Run, no error occurs. However, an error occurs when I try to execute the following line in the interactions window:
(stream-ref (solve (lambda (y) y) 1 0.001) 1000)
The error message is:
mcar: expects argument of type <mutable-pair>; given #<undefined>
When this error occurs, DrRacket highlights the body of the definition of the procedure stream-car
, as shown in the picture below:
What is causing this error? I have already used the stream procedures above in previous examples (stream-car
, stream-cdr
, stream-map
, add-streams
and scale-stream
) and they worked. The integral
procedure also works when I use it outside of the solve
procedure; for example, if I define (define ones (cons-stream 1 ones))
and then I define (define s (integral (delay ones) 1 1))
and then I execute (stream-ref s 1000)
, it correctly gives the output 1001
.