符号相等
Symbol equality
在 Paul Graham's book ANSI Common Lisp 中,在讨论符号与字符串操作时,他说
Symbols can be compared in one step with eql
..."
(p138)。下面是符号比较的两种情况:
(setq x 3)
3
(setq a 'x)
X
(setq b 'x)
X
(eq a b)
T
因此,由于 a
和 b
指向同一个符号对象,名为 "X"
,因此它们是 eq
。然而,这与
(setq a (copy-symbol 'x))
#:X
(setq b (copy-symbol 'x))
#:X
(symbol-name a)
"X"
(symbol-name b)
"X"
(eq a b)
NIL
(eql a b)
NIL
(equal a b)
NIL
(equalp a b)
NIL
现在,a
和 b
指向不同的 symbol
对象,即使它们具有相同的 symbol-name
和相同的打印名称。我的问题是:
- 为什么格雷厄姆说
eql
而不是 eq
,并且
- 第二种情况,为什么
a
和b
不是至少equalp
?
eql
over eq
?
eql
是 "more predictable",因为它小于 implementation-dependent。
例如,non-immediate 个数字(即
非fixnum
s) can be non-eq
在某些实现中,在其他实现中 eq
:
(= 1.5d0 1.5d0)
=> T
(eql 1.5d0 1.5d0)
=> T
(eq 1.5d0 1.5d0)
=> T in some implementations, NIL in others
为什么同名符号不是 equalp
?
规范就是这么说的:-)
请注意,它确实违反了经验法则:
A rough rule of thumb is that two objects are equal
if and only if their printed representations are the same.
主要的非histerical reason是那个符号,同时
"atomic",仍然背负着很多包袱(例如,变量和函数
绑定)。 IOW,symbol
是
远不止它的名字。
此外,人们通常期望 equal
表单的计算结果为
equal
值,如果不同的符号(带有
可能不同的绑定!)被评估为 equal
.
- case-insensitive 字符(和字符串)比较
- 使用
=
比较数字
- 递归下降到
structure
,
array
, 和
hash-table
.
None 这些变化会影响上面的 "similar evaluation rule",
所以 equalp
没有理由根据
他们的名字。
如果你想通过名称比较符号,你可以
使用 string=
:
(eq '#:a '#:a)
==> NIL
(equalp '#:a '#:a)
==> NIL
(string= '#:a '#:a)
==> T
在 Paul Graham's book ANSI Common Lisp 中,在讨论符号与字符串操作时,他说
Symbols can be compared in one step with
eql
..."
(p138)。下面是符号比较的两种情况:
(setq x 3)
3
(setq a 'x)
X
(setq b 'x)
X
(eq a b)
T
因此,由于 a
和 b
指向同一个符号对象,名为 "X"
,因此它们是 eq
。然而,这与
(setq a (copy-symbol 'x))
#:X
(setq b (copy-symbol 'x))
#:X
(symbol-name a)
"X"
(symbol-name b)
"X"
(eq a b)
NIL
(eql a b)
NIL
(equal a b)
NIL
(equalp a b)
NIL
现在,a
和 b
指向不同的 symbol
对象,即使它们具有相同的 symbol-name
和相同的打印名称。我的问题是:
- 为什么格雷厄姆说
eql
而不是eq
,并且 - 第二种情况,为什么
a
和b
不是至少equalp
?
eql
over eq
?
eql
是 "more predictable",因为它小于 implementation-dependent。
例如,non-immediate 个数字(即
非fixnum
s) can be non-eq
在某些实现中,在其他实现中 eq
:
(= 1.5d0 1.5d0)
=> T
(eql 1.5d0 1.5d0)
=> T
(eq 1.5d0 1.5d0)
=> T in some implementations, NIL in others
为什么同名符号不是 equalp
?
规范就是这么说的:-)
请注意,它确实违反了经验法则:
A rough rule of thumb is that two objects are
equal
if and only if their printed representations are the same.
主要的非histerical reason是那个符号,同时
"atomic",仍然背负着很多包袱(例如,变量和函数
绑定)。 IOW,symbol
是
远不止它的名字。
此外,人们通常期望 equal
表单的计算结果为
equal
值,如果不同的符号(带有
可能不同的绑定!)被评估为 equal
.
- case-insensitive 字符(和字符串)比较
- 使用
=
比较数字
- 递归下降到
structure
,array
, 和hash-table
.
None 这些变化会影响上面的 "similar evaluation rule",
所以 equalp
没有理由根据
他们的名字。
如果你想通过名称比较符号,你可以
使用 string=
:
(eq '#:a '#:a)
==> NIL
(equalp '#:a '#:a)
==> NIL
(string= '#:a '#:a)
==> T