Scheme 使用DrRacket运行SICP第3.5.4节中的代码
我在运行SICP(计算机程序的结构和解释)第3.5.4节(流和延迟评估)中的示例代码时遇到问题;可以在此处找到SICP部分: 我使用的是DrRacket版本5.2.1,由Neil Van Dyke(SICP PLaneT 1.17)使用SICP支持语言设置,可以在这里找到: 下面显示的代码使用流。通过如上所述的环境设置,DrRacket已经提供了程序Scheme 使用DrRacket运行SICP第3.5.4节中的代码,scheme,sicp,racket,Scheme,Sicp,Racket,我在运行SICP(计算机程序的结构和解释)第3.5.4节(流和延迟评估)中的示例代码时遇到问题;可以在此处找到SICP部分: 我使用的是DrRacket版本5.2.1,由Neil Van Dyke(SICP PLaneT 1.17)使用SICP支持语言设置,可以在这里找到: 下面显示的代码使用流。通过如上所述的环境设置,DrRacket已经提供了程序cons stream、force和delay。但是streamcar和streamcdr不可用;所以,我必须定义它们。在下面的代码中,我还定义了一
cons stream
、force
和delay
。但是streamcar
和streamcdr
不可用;所以,我必须定义它们。在下面的代码中,我还定义了一些通用流函数:流映射
、流引用
、添加流
和缩放流
我试图使其工作的全部代码如下。它包括一个使用积分过程(integral
)数值求解一阶微分方程的过程(solve
),积分过程使用延迟变元(delayed integrand
);这些程序来自第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)
当我将上面的定义放入DrRacket并单击Run时,不会发生错误。但是,尝试在“交互”窗口中执行以下行时出错:
(stream-ref (solve (lambda (y) y) 1 0.001) 1000)
错误消息是:
mcar: expects argument of type <mutable-pair>; given #<undefined>
mcar:需要类型为的参数;给定#
出现此错误时,DrRacket将突出显示过程定义的主体流车
,如下图所示:
是什么导致了这个错误?我已经在前面的示例中使用了上述流程序(
流车
,流cdr
,流地图
,添加流
和缩放流
),它们都起到了作用。当我在solve
过程之外使用时,integral
过程也可以工作;例如,如果我定义(define one(cons stream 1 one))
,然后我定义(define s(integral(delay one)1 1))
,然后我执行(stream ref s 1000)
,它会正确地给出输出1001您报告的错误相当奇怪,我看不出在哪里使用了mcar
,也看不到可变状态。尝试此设置,它不使用Neil Van Dyke的支持语言对我有效:
#lang racket
(define the-empty-stream '())
(define (stream-null? stream)
(null? stream))
(define-syntax cons-stream
(syntax-rules ()
((cons-stream head tail)
(cons head (delay tail)))))
(define (stream-car stream)
(car stream))
(define (stream-cdr stream)
(force (cdr stream)))
; ... the rest is the same as in your question
谢谢你的回答。但奇怪的是,当我使用这个设置运行相同的命令(stream ref(solve(lambda(y)y)1 0.001)1000)
时,我还得到一个错误:force:reentrant promise |…mentos\sicp\3-77.rkt:14:16 |
。显然,这发生在执行stream cdr
的阶段。更改语言,而不是选择“从源代码确定语言”,然后再次尝试之前更改过的语言,但我一定是做了其他错误的事情。我又试了一次,现在成功了。谢谢你的帮助。