我目前正在研究Lisp,但我仍然没有得到报价。
为什么在Lisp中使用引用?
我在这里遇到了一个很难理解的问题。
(car (car '((a b) c d)))
上面给出了A
。
但我不知道为什么结果是A
,因为之后没有引用第一辆车。
答案 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)))
,car
为car
符号。
'((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)