我从来没有真正想过一个符号是否可以成为Lisp中的数字,所以我今天玩弄了它:
> '1
1
> (+ '1 '1)
2
> (+ '1 1)
2
> (define a '1)
> (+ a 1)
2
上面的代码是方案,但它在Common Lisp和Clojure中似乎大致相同。 1和引用1之间有什么区别吗?
答案 0 :(得分:26)
在Common Lisp中,'1是(QUOTE 1)的简写。评估时,(QUOTE 某事)返回某事部分,未评估。但是,1评估和1未评估之间没有区别。
所以读者有所不同:'1读作(QUOTE 1),1读作1.但是评估时没有区别。
答案 1 :(得分:14)
数字为self-evaluating objects。这就是为什么你不必担心引用它们,就像你使用列表一样。
符号可以由任何字符串组成。如果您想要名称为单个字符1
的符号,您可以说:
(intern "1")
打印|1|
,提示输入它的另一种方式:
'|1|
答案 2 :(得分:11)
引用可防止在以后对表达式进行求值。例如,以下内容不是正确的列表:
(1 2 3)
这是因为Lisp将1解释为函数,而不是。所以必须引用该列表:
'(1 2 3)
当引用一个非常简单的表达式(如数字)时,Lisp实际上不会改变其行为。
请参阅Wikipedia: Lisp。
答案 3 :(得分:9)
嗯,事实上他们非常不同。然而,'1
与(quote 1)
完全相同。 (car ''x)
计算符号'quote'。
1
是一个S表达式,它是一个数据的外部表示,一个数字1.要说1
是一个'数字对象'或一个S表达式来输入该对象都是可以接受的。通常会说1
是实际数字对象的外部表示。
(quote 1)
是另一个S表达式,它是 list 的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
)
自我评估数据真正地评估自己,它们不是某些类型的“预定义符号”。
答案 4 :(得分:1)
在Lisp中,撇号阻止了符号的评估。在不禁止数字之前使用撇号,没有必要,因为数字代表它们自己。但是,与任何其他列表一样,它会自动转换为适当的函数调用。口译员认为这些数字与其价值一致。
答案 5 :(得分:1)
正如已经指出的那样,没有区别,因为数字会对自己进行评估。您可以使用eval
:
(eval 1) ;=> 1
顺便说一下,这不仅限于数字。事实上,在Common Lisp中,大多数事情都是自我评估的。只是对数字,字符串,符号和列表以外的其他东西进行评估是非常罕见的。例如,以下工作:
(eval (make-hash-table)) ;equivalent to just (make-hash-table)
答案 6 :(得分:1)
在Lisp中,quote
阻止评估以下表达式。 '
是quote
的简写。因此,'1
与(quote 1)
相同。
但是,在Lisp中,符号永远不能是数字。我的意思是,'abc
是一个符号,但'123
不是(评估成)一个符号。我认为这是Lisp设计的错误。另一种情况不仅#t
或#f
可以用作布尔表达式。