我从来没有真正考虑过符号是否可以在 Lisp 中成为数字,所以我今天玩弄了它:
> '1
1
> (+ '1 '1)
2
> (+ '1 1)
2
> (define a '1)
> (+ a 1)
2
上面的代码是方案,但在 Common Lisp 和 Clojure 中似乎也大致相同。 1和引用的1有什么区别吗?
我从来没有真正考虑过符号是否可以在 Lisp 中成为数字,所以我今天玩弄了它:
> '1
1
> (+ '1 '1)
2
> (+ '1 1)
2
> (define a '1)
> (+ a 1)
2
上面的代码是方案,但在 Common Lisp 和 Clojure 中似乎也大致相同。 1和引用的1有什么区别吗?
在 Common Lisp 中,'1 是 (QUOTE 1) 的简写。评估时, (QUOTE something ) 返回未评估的 某物部分。但是,1 个已评估和 1 个未评估之间没有区别。
所以对读者来说是有区别的:'1 读作 (QUOTE 1) 和 1 读作 1。但在评估时没有区别。
数字是自我评估的对象。这就是为什么您不必担心引用它们,就像您处理列表一样。
符号可以由任何字符串组成。如果您想要名称为单个字符的符号1
,您可以说:
(intern "1")
哪个打印|1|
,建议另一种输入方式:
'|1|
引用可以防止表达式在以后被评估。例如,以下不是正确的列表:
(1 2 3)
这是因为 Lisp 将 1 解释为一个函数,而事实并非如此。所以必须引用该列表:
'(1 2 3)
当您引用一个非常简单的表达式(例如数字)时,Lisp 实际上不会改变它的行为。
参见维基百科:Lisp。
好吧,它们实际上是非常不同的。'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
)
自我评估数据真正评估自己,它们不是某种“预定义符号”。
在 Lisp 中,撇号防止符号被计算。不禁止在数字前使用撇号,因为数字代表自己,所以没有必要。但是,与任何其他列表一样,它会自动转换为适当的函数调用。解释器认为这些数字与它们的值一致。
正如已经指出的那样,没有区别,因为数字对自己进行评估。您可以使用以下方法确认这一点eval
:
(eval 1) ;=> 1
顺便说一下,这不仅限于数字。事实上,在 Common Lisp 中,大多数事情都会对自己进行评估。只是对于数字、字符串、符号和列表以外的东西进行评估是非常罕见的。例如,以下工作:
(eval (make-hash-table)) ;equivalent to just (make-hash-table)
在 Lisp 中,quote
防止对以下表达式求值。'
是 的简写quote
。结果,'1
与 相同(quote 1)
。
然而,在 Lisp 中,符号永远不能是数字。我的意思是,'abc
是一个符号,但'123
不是(被评估为)一个符号。我认为这是 Lisp 设计的错误。另一种情况是不仅#t
或#f
可以用作布尔表达式。