scheme - 方案中循环定义的问题

标签 scheme sicp guile

我目前正在通过 SICP 进行工作,使用 Guile 作为我的主要练习语言。在实现第 3.5 章中的练习时,我发现了一个奇怪的行为。我已经在各种平台上使用 Guile 1.4、Guile 1.8.6 和 Guile 1.8.7 重现了此行为,并且确信它不是特定于我的设置。

这段代码工作正常(并计算 e):

  (define y (integral (delay dy) 1 0.001))
  (define dy (stream-map (lambda (x) x) y))
  (stream-ref y 1000)

以下代码应该给出相同的结果:

  (define (solve f y0 dt)
    (define y (integral (delay dy) y0 dt))
    (define dy (stream-map f y))
    y)
  (stream-ref (solve (lambda (x) x) 1 0.001) 1000)

但它会产生错误消息:

standard input:7:14: While evaluating arguments to stream-map in expression (stream-map f y):
standard input:7:14: Unbound variable:
y ABORT: (unbound-variable)

因此,当嵌入过程定义中时, (define y ...) 不起作用,而在 REPL 的全局环境中的过程之外,它可以正常工作。

我在这里做错了什么?如果有必要,我也可以发布辅助代码(即积分、流映射等的定义)。除了 cons-stream 的系统相关代码之外,它们都在书中。我自己的 Guile cons-stream 实现如下:

(define-macro (cons-stream a b)
  `(cons ,a (delay ,b)))

最佳答案

您不能拥有相互依赖的内部 DEFINE;语言规范明确指出了这一点(R5RS 5.2.2):

... it must be possible to evaluate each expression of every internal definition in a body without assigning or referring to the value of any variable being defined.

您可以将其视为解释器正在收集所有定义并在正文之前以随机顺序评估它们。由于顺序是随机的,因此如果您希望它能够正常工作,就不会存在任何相互依赖性。

SOLVE 定义 (#71) 中甚至还附加了一个脚注,表明它并不适用于所有方案。

您必须编写代码,以便一个定义非常清楚地位于另一个定义的范围内,就像嵌套的 LET 一样:

(define (solve f y0 dt)
  (let ((y (integral (delay dy) y0 dt)))
    (let ((dy (stream-map f y)))
      y)))

关于scheme - 方案中循环定义的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2828996/

相关文章:

linux - 使用 shell 打开 telnet 并传递命令

scheme - 更改 REPL 以显示用户名、主机名和当前工作目录?

scheme - MIT Scheme 9.2 中 SICP 中的剩余程序是什么?

scheme - 如何在 Racket 中自定义程序的打印?

lisp - 如何在 plt 方案中使用 'destroy/dispose' frame%?

emacs - emacs 的 Racket Flymake 模式

python - 用 python 进行 SICP 的 Material ?

javascript - Streamjs和linqjs有什么关系

scheme - 如何在方案中将数字分解为整数和小数部分?

CMake:如何对多个文件运行自定义命令以生成源文件?