Lisp中1和1之间有什么区别?

时间:2010-06-03 14:15:56

标签: lisp clojure scheme common-lisp quote

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

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

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

7 个答案:

答案 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可以用作布尔表达式。