Eq Eqv Equal

区别

抄来的。我懒得翻译了。一句话:

eq? 只有在两个参数指向同一个对象时才为 #t. 它跟 eqv? 的区别 只能在不同的 Scheme 实现里体现出来。

不同 implementation 的比较

下面是测试结果:

Scheme48

Scheme48 里,我发现的 eq? 和 eqv? 唯一的不同点,只有这个:

(define a 10.#)
(eq? 10.# a)
; #f
(eqv? 10.# a)
; #t

MzScheme.

MzScheme 里测试,eq? 和 eqv? 区别很多:

(eq? 4# 4##)
(eq? 4.# 4.#)
(eq? "abc" "abc")
(eq? '(1 2) '(1 2))
(eq? "" "")
(eq? 1234567890 1234567890)

都给出 #f. 而这些在 Scheme 48 里都是 #t.

结论

Scheme 48 大部分 eq? 都跟 eqv? 的结果一样。说明 Scheme 48 采 用了大量共享数据结构。这种共享特性还体现在 Scheme 48 的模块 名称中,请参考 ModuleExperiment.

eq? 的特殊用途

eq? 可以判断两个变量是不是指向同一个对象。这样有很多用处。

比如 tex2page 里定义了一个对象 *invisible-space*:

(define *invisible-space* (list '*invisible-space*))

以后遇到一个对象,就用一个函数 invisible-space? 函数来判断它 是否是我们这个独一无二的对象:

(define invisible-space?
  (lambda (x)
    (eq? x *invisible-space*)))

*invisible-space* 是用来在输入的 stream 中 表示一个 TeX 命令的开始(大概是这样吧),如果我们使用任何一个 字符,比如 *, &, 甚至那些不可打印的字符,来表示这个“开始”, 那么万一输入文档中真的出现了这个符号呢?我们就会出现很多错误 的命令开始。

所以,用这种“独一无二”的对象,可以避免出现这种问题。