【问题标题】:Scheme and R5RS questions about eq关于 eq 的 Scheme 和 R5RS 问题
【发布时间】:2020-06-06 10:19:55
【问题描述】:

你能解释一下为什么第一个是假的,第二个是真的吗?

这是如何工作的?谢谢。

(eq? '(1 2 3) '(1 2 3)) ;False
(eq? '() '()) ;True

【问题讨论】:

  • 您可能会感兴趣,标准明确规定(eq? '() '()) 必须是#t。见:schemers.org/Documents/Standards/R5RS/HTML
  • (eq? '(1 2 3) '(1 2 3)) 的结果可以是#t 或#f 中的任何一个,具体取决于实现是否重用文字。这就是错误的陈述并不总是正确的。

标签: scheme r5rs


【解决方案1】:

只有一个空列表,所以() 的所有用法都引用该列表,而它本身就是eq?。存储模型的Scheme Specification 描述说:

尽管如此,但可以理解的是,空列表不能 新分配的,因为它是唯一的对象。

并且eqv? 的规范(由eq? 描述引用)说两个对象是等效的,如果

obj1 和 obj2 都是空列表

但是当你创建一个非空列表时,它每次都会创建一个新的,即使它们包含相同的元素,它们也不是eq?。

【讨论】:

  • 其实'()是和一个符号相关联的,这个符号对于所有的空列表都是唯一的......所以它有一个唯一的地址。
  • @alinsoar 在 Lisp 中是符号 NIL。我不认为这在 Scheme 中是正确的。
  • 我认为它就像一个内部符号,而不是 obarray 中存储用户可见符号的内部符号。
  • @alinsoar R7RS 说“空列表是它自己类型的特殊对象。”
  • 你可以随心所欲地想它,但最好把它想象成一个专门用于此目的的特殊对象。 Scheme 刻意避免将空列表与 Lisp 那样的符号混为一谈; Lisp 的 NIL 严重超载。
【解决方案2】:

引用自TSPL3:

[..] 如果两个对象在内部由相同的指针值表示,则认为它们是相同的 [..] 空列表 () 无论出现在哪里,都与它自己相同。 [..] 由 cons、vector、string 等的不同应用创建的两对、向量或字符串是不同的。

如果你改写

(let ((x '(1 2 3)))
  (eq? x x))

它将是#t。

【讨论】:

  • TSPL 不是寻找语言规范的官方场所。 RNRS reports 是。 (eq? '(1 2 3) '(1 2 3)) 的结果可以是 #t 或 #f 中的任何一个,并且仍然符合 RNRS 规范。
猜你喜欢
  • 2011-07-28
  • 2020-06-06
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多