延迟是如何实现的?

问题描述 投票:0回答:1

我对惰性求值和流的工作原理有深刻的理解。

然而,我在这一点上只是简单地阅读本书时遇到了一些麻烦。我真的不明白它试图告诉我有关

delay
的内容,这就是原因。

在第 321 页上写着

Cons-stream
是一种特殊形式,因此

(cons-stream 〈a〉 〈b〉)

相当于

(cons 〈a〉 (delay 〈b〉))

和相关的脚注

[…] 如果

cons-stream
是一个过程,那么 […] 评估
(cons-stream 〈a〉 〈b〉)
会自动导致
〈b〉
被评估,这正是我们不希望发生的事情。出于同样的原因,
delay
必须是一种特殊形式 [...]

所以我得出结论,我 不能 实现

cons-stream
delay
,至少不能使用我在本书这个阶段提供的工具,所以我不明白上面的引用是什么意思告诉我,除了“有点像,但不完全是”。

后来,虽然,这本书的“部分”标题为

实施
delay
force

上面写着和之前类似的话:

Delay
可以是这样的特殊形式

(delay 〈exp〉)

的语法糖
(lambda () 〈exp〉)

但是,如果我不知道如何定义特殊形式,我该如何定义

delay

自相矛盾的是,在发现之后立即

此实现足以让

delay
force
像宣传的那样工作,但是 […]

(“但是”与特殊形式无关,只与性能有关),但如果它不是这样定义的特殊形式,它如何工作?

即使我想假设

delay
已经在我使用的任何 Scheme 解释器中定义(对于这个在线编译器 就是这种情况),我仍然无法定义一个特殊的形式来使用它,例如
cons-stream
.

最重要的是,我不知道如何写任何练习。

最终,我找到了this answer showing how to define a special form,但关键是其中使用的

define-syntax
整本书都没有提到。

那我应该怎么炼呢?

stream scheme lazy-evaluation sicp
1个回答
1
投票

你可以在任何地方手写语法定义,或者像

   (cons A (delay B))

   (cons A (lambda () B))

甚至

   (cons A (memo (lambda () B)))

代替

   (cons-stream A B)

没那么糟糕。我也做过一两次。

memo
甚至可以非常直接地定义为一个函数。

较长的方法是定义您自己的解释器,并让 it 处理那些额外的 特殊形式 - 而不是“宏” - 根据需要为您服务。

你会把你的程序写成引用列表,并将它们用作解释器的输入。

一种中间方法是将流定义为具有显式拉取请求等的有状态对象,让构造函数将 lambda 函数存储在内部,并在此基础上构建其余部分。

试图定义例如这种流的汉明序列实际上是一个有趣的练习,迫使你明确地处理各种问题,否则这些问题可能会隐含。

© www.soinside.com 2019 - 2024. All rights reserved.