我对惰性求值和流的工作原理有深刻的理解。
然而,我在这一点上只是简单地阅读本书时遇到了一些麻烦。我真的不明白它试图告诉我有关
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
整本书都没有提到。
那我应该怎么炼呢?
你可以在任何地方手写语法定义,或者像
(cons A (delay B))
或
(cons A (lambda () B))
甚至
(cons A (memo (lambda () B)))
代替
(cons-stream A B)
没那么糟糕。我也做过一两次。
memo
甚至可以非常直接地定义为一个函数。
较长的方法是定义您自己的解释器,并让 it 处理那些额外的 特殊形式 - 而不是“宏” - 根据需要为您服务。
你会把你的程序写成引用列表,并将它们用作解释器的输入。
一种中间方法是将流定义为具有显式拉取请求等的有状态对象,让构造函数将 lambda 函数存储在内部,并在此基础上构建其余部分。
试图定义例如这种流的汉明序列实际上是一个有趣的练习,迫使你明确地处理各种问题,否则这些问题可能会隐含。