【发布时间】:2012-11-28 09:56:51
【问题描述】:
我已经开始尝试学习 Scheme 评估的内容,而 quasiquotation、unquoting、evaluation 和 cons-cells 的一个方面让我感到困惑。如果您能推荐任何关于该主题的好的参考资料,我将不胜感激。
R7RS 草案在关于准引用的第 4.2.8 节中有这个例子。
`(( foo ,(- 10 3)) ,@(cdr '(c)) . ,(car '(cons)))
(它也在 R4RS 规范中,所以这不是新事物。)
根据规范,这应该评估为:
((foo 7) . cons)
我很难理解为什么。在我看来,.从内部列表的开头删除取消引用,这意味着它不会被评估为过程。
这里有一个更简单的表达式来演示同样的问题:
`(foo . ,(car '(bar)))
使用与上述相同的逻辑,这应该评估为:
(foo . bar)
确实,在我尝试过的 Scheme 系统上,它的评估结果确实如此。
但是,据我了解,它不应该这样评估,所以我想找出我哪里出错了。
我对 Scheme 评估的理解是(好的,简化的)如果它是左括号之后的第一个关键字,则调用该过程并将列表的其余部分作为参数。
我对规范的理解是,',' 完全等同于将下一个表达式包装在 '(unquote' 过程中。
我对点符号的理解是,出于一般显示目的,您删除点和左括号(以及匹配的右括号),如下所述:
所以:
`(foo . ,(car '(bar)))
同样可以呈现为:
(quasiquote (foo unquote (car (quote (bar)))))
(事实上,这就是jsScheme 在其日志窗口中呈现输入的方式。)
但是,在评估这个时:
(quasiquote (foo unquote (car (quote (bar)))))
为什么要评估“取消引用”(作为过程?),取消引用和评估(汽车...)列表?当然它应该被视为一个带引号的符号,因为它不在左括号之后?
我可以想到许多可能的答案 - “取消引用”不是常规过程,“取消引用”是在常规评估过程之外评估的,还有一种不同的方式来指示要调用的过程,而不是'(' 后跟过程的符号 - 但我不确定哪个是正确的,或者如何挖掘更多信息。
我见过的大多数方案实现都使用宏而不是使用与评估器相同的语言来处理这个问题,而且我很难弄清楚应该发生什么。有人可以解释一下,或向我展示有关该主题的任何好的参考资料吗?
【问题讨论】:
标签: scheme