为什么Scheme需要程序位置标记的特殊概念?
标准说:
作为评估lambda表达式的结果创建的每个过程 (概念上)用存储位置标记,以便 的当量?和eq?处理程序
eqv?过程返回#t if:
- obj1和obj2是位置标记相等的程序
等式?和eqv?保证在......程序中具有相同的行为......
但与此同时:
变量和对象(如对,向量和字符串)隐式表示位置或位置序列
eqv?过程返回#t if:
- obj1和obj2是表示商店中相同位置的对,向量或字符串
等式?和eqv?保证在......对...和非空字符串和向量
上具有相同的行为
为什么不直接将“隐含地表示位置或位置序列”应用于程序呢? 我认为这也与他们有关 我没有看到关于这个问题的程序有什么特别之处
答案 0 :(得分:4)
对,向量和字符串是可变的。因此,这些对象的身份(或位置)很重要。
程序是不可变的,因此可以任意复制或合并它们,但行为没有明显差异。实际上,这意味着一些优化编译器可以内联它们,有效地使它们成为“多个副本”。特别是R6RS表示像
这样的表达式(let ((p (lambda (x) x)))
(eqv? p p))
the result is not guaranteed to be true,因为它可以内联为(eqv? (lambda (x) x) (lambda (x) x))
。
R7RS的位置标记概念是为了确保该表达式确实导致为true,即使实现内联也是如此。
答案 1 :(得分:1)
将处理程序作为值在ML等语言中工作,它们是真正不可变的。但是在Scheme中,程序实际上可以变异,因为它们的局部变量可以是。实际上,程序是穷人的对象(尽管也可以说OO风格的对象只是穷人的程序!)位置标记用于区分两个对象标识的目的相同配对相同的汽车和cdrs。
特别是,给出全局过程标识意味着可以直接询问我们传递的谓词是否具体为eq?还是eqv?或等于?,这在R6RS中是不可能的(尽管在实践中可能在R6RS实现中)。