33

我从来没有真正考虑过符号是否可以在 Lisp 中成为数字,所以我今天玩弄了它:

> '1
1
> (+ '1 '1)
2
> (+ '1 1)
2
> (define a '1)
> (+ a 1)
2

上面的代码是方案,但在 Common Lisp 和 Clojure 中似乎也大致相同。 1和引用的1有什么区别吗

4

7 回答 7

26

在 Common Lisp 中,'1 是 (QUOTE 1) 的简写。评估时, (QUOTE something ) 返回未评估的 某物部分。但是,1 个已评估和 1 个未评估之间没有区别。

所以对读者来说是有区别的:'1 读作 (QUOTE 1) 和 1 读作 1。但在评估时没有区别。

于 2010-06-03T15:02:53.380 回答
14

数字是自我评估的对象。这就是为什么您不必担心引用它们,就像您处理列表一样。

符号可以由任何字符串组成。如果您想要名称为单个字符的符号1,您可以说:

(intern "1")

哪个打印|1|,建议另一种输入方式:

'|1|
于 2010-06-03T14:39:00.197 回答
11

引用可以防止表达式在以后被评估。例如,以下不是正确的列表:

(1 2 3)

这是因为 Lisp 将 1 解释为一个函数,而事实并非如此。所以必须引用该列表:

'(1 2 3)

当您引用一个非常简单的表达式(例如数字)时,Lisp 实际上不会改变它的行为。

参见维基百科:Lisp

于 2010-06-03T14:20:19.447 回答
9

好吧,它们实际上是非常不同的。'1然而,与 完全相同(quote 1)(car ''x)计算为符号“报价”。

1是一个 S 表达式,它是数据的外部表示,一个数字 1。说这1是一个“数字对象”或输入该对象的 S 表达式都是可以接受的。通常说这1是实际数字对象的外部表示。

(quote 1)是另一个 S 表达式,它是一个列表的 S 表达式,它的第一个元素是符号 'quote',第二个元素是数字 1。这就是它已经不同的地方,语法关键字与函数不同,不被视为对象语言,他们不会对他们进行评估。

但是,两者都是评估为相同数据的对象(数据)的外部表示。外部表示为 的数字1,但它们肯定不是相同的对象,相同的代码,相同的数据相同的任何东西,它们只是评估相同的东西。数字对自己进行评估。说它们是相同的就是说:

(+ 1 (* 3 3))

(if "Strings are true" (* 5 (- 5 3)) "Strings are not true? This must be a bug!")

是“相同的”,它们不是,它们都是不同的程序,只是碰巧终止于相同的值,lisp 形式也是一个程序,一个形式是一个数据,它也是一个程序,记住。

此外,有一次我学到了一个方便的技巧,表明输入时自我评估数据确实不是符号:

(let ((num 4))
  (symbol? num) ; ====> evaluates to #f
  (symbol? 'num) ; ====> evaluates to #t
  (symbol? '4) ; ====> evaluates to #f
  (symbol? '#\c) ; #f again, et cetera
  (symbol? (car ''x)) ; #t
  (symbol? quote) ; error, in most implementations
)

自我评估数据真正评估自己,它们不是某种“预定义符号”。

于 2010-06-04T17:49:47.420 回答
1

在 Lisp 中,撇号防止符号被计算。不禁止在数字前使用撇号,因为数字代表自己,所以没有必要。但是,与任何其他列表一样,它会自动转换为适当的函数调用。解释器认为这些数字与它们的值一致。

于 2010-06-03T17:40:39.910 回答
1

正如已经指出的那样,没有区别,因为数字对自己进行评估。您可以使用以下方法确认这一点eval

(eval 1)  ;=> 1

顺便说一下,这不仅限于数字。事实上,在 Common Lisp 中,大多数事情都会对自己进行评估。只是对于数字、字符串、符号和列表以外的东西进行评估是非常罕见的。例如,以下工作:

(eval (make-hash-table))  ;equivalent to just (make-hash-table)
于 2010-06-03T19:30:01.580 回答
1

在 Lisp 中,quote防止对以下表达式求值。'是 的简写quote。结果,'1与 相同(quote 1)

然而,在 Lisp 中,符号永远不能是数字。我的意思是,'abc是一个符号,但'123不是(被评估为)一个符号。我认为这是 Lisp 设计的错误。另一种情况是不仅#t#f可以用作布尔表达式。

于 2014-08-26T02:34:29.700 回答