首页 文章

使用DrRacket从SICP部分3.5.4运行代码

提问于
浏览
3

我在运行SICP(计算机程序的结构和解释)第3.5.4节(流和延迟评估)中的示例代码时遇到了问题; SICP部分可以在这里找到:http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-24.html#%_sec_3.5.4 .

我正在使用DrRacket版本5.2.1,使用Neil Van Dyke( SICP PLaneT 1.17 )的SICP支持语言进行设置,可在此处找到:http://www.neilvandyke.org/racket-sicp/#%28part._installation%29 .

如下所示,代码使用流 . 如上所述设置环境,DrRacket已经提供了程序 cons-streamforcedelay . 但 stream-carstream-cdr 不可用;所以,我必须定义它们 . 在下面的代码中,我还定义了一些通用流函数: stream-map ,_ stream-refadd-streamsscale-stream .

我正在努力完成的整个代码如下 . 它包括使用积分过程( 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>

发生此错误时,DrRacket会突出显示过程 stream-car 的定义正文,如下图所示:

DrRacket error


导致此错误的原因是什么?我已经在前面的例子中使用了上面的流程序( stream-car ,_ 1178064stream-mapadd-streamsscale-stream )并且它们有效 . 当我在 solve 程序之外使用它时, integral 程序也有效;例如,如果我定义 (define ones (cons-stream 1 ones)) 然后我定义 (define s (integral (delay ones) 1 1)) 然后我执行 (stream-ref s 1000) ,它正确地给出输出 1001 .

1 回答

  • 4

    你're reporting is rather weird, I can'看到 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
    

相关问题