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
首先是一些定义/注释:
- 类似于
的内容称为表单。表单是要计算的Lisp对象(列表1)
- 因为它是一个列表,所以称为复合形式
- 由于复合形式的第一个元素是
,它代表函数,因此称为函数形式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