Lisp中的汽车和报价

时间:2016-09-14 13:56:06

标签: lisp quote

我目前正在研究Lisp,但我仍然没有得到报价。

为什么在Lisp中使用引用?

我在这里遇到了一个很难理解的问题。

(car (car '((a b) c d))) 

上面给出了A

但我不知道为什么结果是A,因为之后没有引用第一辆车。

2 个答案:

答案 0 :(得分:4)

quote是一名运营商;它的含义只有当它是被评估的Lisp表达式的头部时才会启动。语法'X代表(quote X):Lisp阅读器将前缀撇号(后跟任何表示一个对象的语法单元X)转换为语法(quote X)。评估时,quote表达式返回语法X 本身作为值,而不是语法的值。例如,(quote (+ 1 2))返回三个元素列表(+ 1 2),而不是(+ 1 2)的表达式3的值。 quote有效地一段程序基于列表的语法反映为正在运行的程序中作为值。

在表达式中:

(car (car '((a b) c d)))

我们只是将一个嵌套函数应用程序放到一个值:

(car (car value))

此值是quote表达式的结果,因此值为对象((a b) c d)。这个对象最初是作为一个包含在quote中的语法,但现在是传递给car函数的运行时值。内部car生成列表的第一个元素,返回(a b)。此(a b)值会传递到外部car,后者会检索a

Lisp提供quote因为它是一种同性语言。在该语言中操作的主要数据结构具有打印符号,并且该打印符号也用于编写程序。因此,程序被理解为由数据结构构成。在这种语言中,假设您希望能够将任何数据结构用作文字。当然,这会产生混淆,因为数据使用与代码相同的符号,并且一些数据结构看起来像有效语法。你需要一个运算符,你可以用一段语法来表示,"这是文字数据;不要将此作为表达式进行评估,而只将其评估为"。

这与我们使用英语谈论关于英语的情况完全一样。我们必须使用引号 - 至少在我们写下这个讲话时。一句话:

  

一分钱得救是一分钱,是一句古老的谚语。

编写得很糟糕。当然,我们理解这意味着什么,因为我们的大脑善于处理歧义和错误,但它似乎是说一分钱是一句谚语。我们需要引用:

  

"节省的一分钱是赢得的一分钱"是一句古老的谚语。

请参阅?引述说这句话不是我判刑的相关条款;我的句子正在讨论的文本(恰好与我用来谈论它的语言相同)。这就是Lisp运算符被称为quote的原因:它与这种类型的引用有关。

答案 1 :(得分:3)

为什么要使用引用

将引用视为其数据的指示,而不是将其视为代码:

(cons 1 2)  ; ==> (1 . 2)    (a cons with car as 1 and cdr as 2)
'(cons 1 2) ; ==> (cons 1 2) (a list with the symbol cons and the numbers 1 and 2)

你在第一个中看到它没有被引用它被执行,结果是cons函数的结果。在第二个中你可以说quote被执行并且它评估了它的参数。请注意,'x只是(quote x)的缩写,因此评估为x而没有引用它会评估为绑定到变量x的值。

嵌套函数

当您嵌套(car (car '((a b) c d))))之类的函数时,您需要引用为什么需要引用,因为函数中的所有参数都会被计算。因此,在可以应用外部car之前,它需要评估它的参数(car '((a b) c d))),并且在内部汽车能够完成它的工作之前,它需要评估它的参数'((a b) c d))。我们知道'((a b) c d))变为((a b) c d))car(a b)。外部汽车然后在(a b)上工作,因此a就是结果。如果你把这个引用放在这个(car '(car ((a b) c d))))之内,那么这个引用的汽车只是数据结构中的一个符号,而不是一个函数。 car评估其参数为(car ((a b) c d)))carcar符号。

'((a b) c d))             ; ==> ((a b) c d))
(car '((a b) c d))        ; ==> (a b)
(car (car '((a b) c d)))  ; ==> a

'(car ((a b) c d))        ; ==> (car ((a b) c d))
(car '(car ((a b) c d)))  ; ==> car

另外要知道,如果在引用数据中加上引号,例如''x,则仅取消外引号,其余为数据。结果为(quote x)'x,具体取决于显示设置,但由于此处已有数据quote,因此这只是一个符号。 (car ''x) ; ==> quote (symbol)