符号平等

dav*_*ugh 1 symbols common-lisp

他说,在Paul Graham的书" ANSI Common Lisp"中,他讨论了符号与字符串操作

符号可以一步比较eql......"

(P138).以下是符号比较的两种情况:

(setq x 3)
3
(setq a 'x)
X
(setq b 'x)
X
(eq a b)
T
Run Code Online (Sandbox Code Playgroud)

因此,由于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
Run Code Online (Sandbox Code Playgroud)

现在,a和b指向不同的符号对象,即使它们具有相同的符号名称和相同的打印名称.我的问题是:

  1. 为什么格雷厄姆说eql而不是eq,而且
  2. 在第二种情况下,为什么a和b至少不是equalp

sds*_*sds 5

eql结束eq

eql从某种程度上来说,它更依赖于实现,因此"更具可预测性".例如,非直接数字(即非fixnums)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
Run Code Online (Sandbox Code Playgroud)

为什么不是同名的符号equalp呢?

这就是规范说的:-)

请注意,它确实违反了经验法则:

一个粗略的经验法则是,equal当且仅当它们的印刷表示是相同的时,两个对象才是.

主要非histerical原因这是该符号,而被"原子",仍然带有许多行李(例如,变量和函数绑定).IOW,a symbol远不止它的名字.

此外,人们通常期望equal表单评估为 equal值,如果不同的符号(可能具有不同的绑定!)被评估为,则不是这种情况equal.

现在,equal和之间的唯一区别equalp

  1. 不区分大小写的字符(和字符串)比较
  2. 用数字比较数字 =
  3. 递归下降到 structure, arrayhash-table.

这些更改都不会影响上面的"类似评估规则",因此没有理由equalp根据名称比较符号.

如果要按名称比较符号,可以使用string=:

(eq '#:a '#:a)
==> NIL
(equalp '#:a '#:a)
==> NIL
(string= '#:a '#:a)
==> T
Run Code Online (Sandbox Code Playgroud)