方案中的''quote`和''lambda`的奇怪比较(guile)

tra*_*ang 2 scheme guile switch-statement quote

让我看看我的代码

代码1:

(eqv? 'lambda 'quote)
Run Code Online (Sandbox Code Playgroud)

返回 #f

代码2:

(case 'lambda ('quote "equal") (else "not equal"))
Run Code Online (Sandbox Code Playgroud)

返回"not equal"但生成警告;;; <stdin>:17:0: warning: duplicate datum quote in clause ((quote quote) "equal") of case expression (case (quote lambda) ((quote quote) "equal") (else "not equal"))

Code3:奇怪的结果

 (case 'quote ('lambda "equal"))
Run Code Online (Sandbox Code Playgroud)

返回"equal",没有警告

我使用了解释代码guile (GNU Guile) 2.0.11.以下是gnucase语法的描述

使用eqv将评估结果与所有基准进行比较?

Jos*_*lor 5

'<something>是一个缩写列表 (quote <something>).在Scheme中,case表单应该是一个列表(在一些Lisp中,例如,Common Lisp,它也可以是一个单独的非list元素,代表那个元素的列表),这样你就可以做到,例如:

(case n
  ((0) 'zero)                 ; in Common Lisp, could also be (0 'zero)
  ((1 2 3) 'one-two-or-three)
  ((4 5) 'four-or-five))
Run Code Online (Sandbox Code Playgroud)

当你这样做时:

(case some-symbol
   ('quote 'it-was-quote))
Run Code Online (Sandbox Code Playgroud)

你在做

(case some-symbol
  ((quote quote) 'it-was-quote))
Run Code Online (Sandbox Code Playgroud)

所以你提供了一个列表,它有一个重复的元素.这没有什么不对,但它通常是意料之外的,所以你得到一个警告.

通过这个推理

(case 'quote ('lambda "equal"))
Run Code Online (Sandbox Code Playgroud)

是相同的

(case 'quote ((quote lambda) "equal"))
Run Code Online (Sandbox Code Playgroud)

并且,由于符号引用在列表中(引用lambda),案例匹配,并且您得到"相等".这个故事的寓意是:"不要在案件中引用案件." 也就是说,你应该这样做:

(case 'quote
  ((lambda) "equal"))
Run Code Online (Sandbox Code Playgroud)