【问题标题】:symbols handling: cannot compare for identity符号处理:无法比较身份
【发布时间】:2017-04-20 07:08:54
【问题描述】:

我不明白为什么

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

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

打印

T 
T 
NIL 

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

【问题讨论】:

标签: lisp common-lisp equality quote


【解决方案1】:

如果你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

IOW,您“过度引用”了您的 x:当您输入 'x 时,它与 (quote x) 相同,因此,您正在检查符号 x 和列表 (quote x) 的相等性,当然还有,得到nil

注意事项:

  1. (eq ''x 'x):因为eq 是一个函数,所以它的参数被评估,我们将'x == (quote x)x 进行比较,得到nil

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

相关:

  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

【讨论】:

  • 不客气!作为练习,您可能想(trace first) 看看会发生什么。
  • 好吧,我试过(step ...)。细节水平和缺乏经验让我感到压力……例如,当我点击 :n 时,我无法预测调试器的答案。我会试试(trace ...),再次感谢
  • lisp 需要时间来适应,但它的力量和美丽是无与伦比的! :-)
【解决方案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 以下数据结构不被评估。因此,没有必要在内部引用符号来防止其评估。如果引用了列表,则不会评估其子列表或子元素。

总结

引号不是符号的一部分。它是一个内置的特殊运算符,用于防止评估。

【讨论】:

    猜你喜欢
    • 2012-07-28
    • 1970-01-01
    • 2019-04-17
    • 2011-07-21
    • 2016-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多