Lisp 为什么(列表';引号1)的计算结果为';1而不是1?

Lisp 为什么(列表';引号1)的计算结果为';1而不是1?,lisp,Lisp,结合使用list和quote,我需要一些启示 以下是我看到的: [1]> (list '1) (1) 很公平(列表“1)变为“('1)”,其计算结果为(1),因为”只返回它后面的内容 [2]> (list 'quote 1) '1 为什么不1,为什么“在这里不被评估,因为: [3]> '1 1 作为一个一般性问题,我是否错误地认为评估过程将试图递归地解决它能找到的所有问题 因为list应该构造一个参数列表,如果它返回一个数字,那就很奇怪了。实际上,'1是一个双元素列表,包

结合使用
list
quote
,我需要一些启示

以下是我看到的:

[1]> (list '1)
(1)
很公平<代码>(列表“1)变为
“('1)”
,其计算结果为
(1)
,因为
只返回它后面的内容

[2]> (list 'quote 1)
'1
为什么不
1
,为什么
在这里不被评估,因为:

[3]> '1
1

作为一个一般性问题,我是否错误地认为评估过程将试图递归地解决它能找到的所有问题

因为
list
应该构造一个参数列表,如果它返回一个数字,那就很奇怪了。实际上,
'1
是一个双元素列表,包含符号
引号
和数字1作为其元素:

CL-USER> (first (list 'quote 1))
QUOTE
CL-USER> (second (list 'quote 1))
1
它显示为
'1
而不是
(QUOTE 1)
的原因是您的Lisp系统打印以
QUOTE
开头的单个元素列表

(列表“1)
变为
“('1)”
,其计算结果为
(1)


这是不对的。由于
list
是一个普通函数,因此对其参数形式进行求值以给出每个参数的值。在这种情况下,表单
'1
将被计算为值
1
,该值
list
将作为其单个参数接收。没有对返回值的计算。

注意,我在这里假设使用公共Lisp

首先是一些定义/注释

  • 类似于
    (列表1)
    的内容称为表单。表单是要计算的Lisp对象
  • 因为它是一个列表,所以称为复合形式
  • 由于复合形式的第一个元素是
    list
    ,它代表函数,因此称为函数形式
  • 函数形式的第一个元素是函数,其余元素是参数
打印报价表

'foo
(quote foo)
相同,因为quote字符是一个reader宏,它将读取时的格式
'foo
转换为
(quote foo)

但是它是如何印刷的呢?可以根据变量
*print pretty*
的值来确定。如果此变量的值为
T
,则打印机使用漂亮的打印机

但当我们不使用漂亮的打印机打印结果值时:

* (setf *print-pretty* nil)

NIL
* '(quote 1)

(QUOTE 1)
因此,Lisp可以根据其配置以不同的方式打印相同的内容

函数形式的评估

当计算函数形式时,我们已经知道第一个元素是函数,其余元素是参数

因此,在
(列表'1)
中,我们看到:

  • list
    是函数
  • '1
    是唯一的参数
现在,每个参数的计算值为:

  • '1
    的计算结果为
    1
    ,因为
    quote
    操作符只返回封闭的对象。因此,结果值为
    1
由于所有参数都经过计算,因此我们可以使用参数值
1
调用
list

然后返回
(1)
,因为
list
返回所有提供的参数值的列表

第二个示例

现在让我们看第二个示例:
(列表“引号1)

我们还有一个函数表单,其中包含函数
列表
。但是现在我们有两个参数
'quote
1

我们需要从左到右评估每个参数

'quote
计算为符号
quote

1
计算为
1
,因为数字与大多数对象一样是自评估的(符号和列表除外)

因此,我们使用参数值
quote
1
调用函数
list

List列出了它的参数值。因此,结果是
(引号1)

现在请记住:
(引号1)
'1)
相同。因此,打印机可以打印后一种变体

因此,我们有一个列表,可以打印为
(引号1)
'1
。但这在其他方面没有区别:

CL-USER 7 > (equal (quote (quote 1)) ''1)
T
评估完成一次

作为一个一般性问题,我是否错误地认为评估过程将试图递归地解决它能找到的所有问题

表单的结果不会再次求值。对的求值只执行一次:对表单本身进行求值

CL-USER 7 > (equal (quote (quote 1)) ''1)
T