符号处理:无法比较身份

时间:2016-12-05 19:33:07

标签: lisp common-lisp equality quote

我不明白为什么

(setq a_sym 'abc)
(print (eq a_sym 'abc))

(print (eq 'x 'x))
(print (eq (first '('x 2 3)) 'x))

打印

T 
T 
NIL 

为什么第三个语句中的符号'x的处理方式与第二个不同?而且,脚踏实地,如何比较它们的身份?

2 个答案:

答案 0 :(得分:5)

如果您trace进行比较,您会立即看到错误:

[1]> (eq (first '('x 2 3)) 'x)
NIL
[2]> (trace eq)

** - Continuable Error
TRACE(EQ): #<PACKAGE COMMON-LISP> is locked
If you continue (by typing 'continue'): Ignore the lock and proceed
The following restarts are also available:
ABORT          :R1      Abort main loop
Break 1 [3]> :c
WARNING: TRACE: redefining function EQ in top-level, was defined in C
;; Tracing function EQ.
(EQ)
[4]> (eq (first '('x 2 3)) 'x)
1. Trace: (EQ ''X 'X)  ;    <=======    note 1
1. Trace: EQ ==> NIL
NIL
[5]> (eq (first '(x 2 3)) 'x)
1. Trace: (EQ 'X 'X)   ;    <=======    note 2
1. Trace: EQ ==> T
T

以下,您“过度”了x:当您输入'x时,它与(quote x)相同,因此,您正在检查符号x是否相等列出(quote x),当然还有nil

说明:

  1. (eq ''x 'x):由于eq是一个函数,因此会对其参数进行评估,我们正在将'x == (quote x)x进行比较并获取nil。< / p>

  2. (eq 'x 'x):出于同样的原因,我们将xx进行比较并获得t

  3. 相关:

    1. Lisp quote work internally
    2. Confused by Lisp Quoting
    3. When to use 'quote in Lisp
    4. Lisp: quoting a list of symbols' values

答案 1 :(得分:2)

语法和阅读

您写道:

  

符号'x

请注意,'x不是符号。它是符号前面的引号字符。引号字符在s表达式中具有特殊含义:读取下一个项目并将其括在(quote ...)中。

因此'x实际上就是列表(quote x)

CL-USER 9 > (read-from-string "'x")
(QUOTE X)
2

<强>评价

不评估引用的对象。 quote特殊运算符,这意味着它是Common Lisp中的内置语法/语义,而不是函数而不是宏。求值程序返回引用的对象:

CL-USER 10 > (quote x)
X

您的示例

(eq (first (quote ((quote x) 2 3))) (quote x))

让我们评估第一部分:

CL-USER 13 > (first (quote ((quote x) 2 3)))
(QUOTE X)

结果是列表(quote x)

让我们评估第二部分:

CL-USER 14 > 'x
X

结果是符号x

x(quote x)不是 eq

评估和报价

'('x 2 3)

列表中第二个引用的目的是什么?

第一个引用已经意味着不会评估以下数据结构的 WHOLE 。因此,没有必要在内部引用符号以防止其评估。如果引用列表,则不会评估其子列表或子元素。

<强>摘要

报价不是符号的一部分。它是一个内置的特殊操作符,用于防止评估。