为什么 '(1 2 3) 评估为列表 en Lisp(方案)?

Why does '(1 2 3) evaluate to a list en Lisp (Scheme)?

quote (') 用于引入预评估值,因此 (quote x) 导致符号 x 而不是符号评估的结果.

数字、布尔值、字符和字符串在 Scheme 中是自求值的,所以引用它们并不重要。

但为什么 (quote (1 2 3))(quote ()) 回答 #t 谓词 list?.

结果不应该是 "pre-evaluated" 值吗?但在这种情况下 (1 2 3) 实际上已被评估为 (list 1 2 3)?

谢谢。

pre-evaluated value

我不确定你从哪里得到这个词。我从来没有用过它。它不是 "pre-evaluated",它是未计算的。

这实际上是 Lisp(和 Scheme)的全部工作 Homoiconic:程序的结构确实在下面使用了列表和原子。

quoteeval 的对偶:(eval (list '+ '1 '2 '3))(并且由于引用的数字只是数字,(eval (list '+ 1 2 3)) 也是如此)与(quote '(+ 1 2 3)).

已评估的列表是一个调用,因此未评估的调用是一个列表。

Should't the result be a "pre-evaluated" value? But in this case (1 2 3) has actually been evaluated to (list? 1 2 3)?

您在这里遗漏了一些括号!你得到 (list? '(1 2 3))(或 (list? (quote (1 2 3))。也就是说,(list? (list 1 2 3))。这是真的。

你可以用(eval (list '+ 1 2 3))检查相反的结果:你得到6

注意:有些值只是对其自身求值(例如数字或函​​数。您可以根据需要向其多次抛出 eval,它不会改变任何事情:(eval (eval (eval 1)))只是 1.)

(quote (+ 1 2 3)) = '(+ 1 2 3) = (list '+ '1 '2 '3) = (list '+ 1 2 3)(数字是自我评估的,即评估自我)。

(eval '(+ 1 2 3)) = (+ 1 2 3) = 6。而(eval '(1 2 3))=(1 2 3)=错误.

第一个身份只是语法上的。这里的中心身份是第二个,'(+ 1 2 3) = (list '+ '1 '2 '3)。它成立是因为一切都在 Lisp 中计算,但在此之前,它必须是 read。这意味着, 从文本源代码转换为实际数据结构。

由于 ( ... ) 圆括号表示 lists,阅读 ( ... ) forms 创建 lists。然后,评估 quoted 形式只是 returns 形成 原样 (即未评估)。令牌 + 被读取为 符号 +;文字 1, 2, 3 被读取为 数字 1, 2, 3。所以最终结果 与评估形式 (list '+ '1 '2 '3).

的结果相同

当然,所有这些在没有 + 的情况下仍然适用。

引用引入了一个未评估的值,而不是预评估的值,不管那是什么意思。

当表达式 (quote X) 被视为要计算的形式时,它只是计算为 X 本身。 X 不被视为要评估为值的形式,而是结果值是 语法 X 本身。

引用是程序表达的一种方式,"I want to use a piece of my own syntax as a value"。这正是 "literal" 在计算机科学中的含义:一段程序文本作为 运行 时间值反映回程序。

在 Lisp 中,符号以外的原子在计算时表示它们自己。语法 3 的计算结果为整数 3。它们是同一件事:Lisp 语法是一种数据结构,在该数据结构中,整数文字 3 已经由它表示的对象表示。

因此,正在评估(quote 3)和只是3没有区别。 "Give me the syntax 3 itself" 和 "give me the value of the syntax 3" 是一样的:只有 3.

(quote (1 2 3)) 下,引用的语法是 (1 2 3)。该语法 它看起来像的列表对象;引用只是反刍它。如果要评估 (1 2 3) 形式,那将是一个错误:它看起来像 1 被用作运算符或函数,参数为 23。当 quote 本身被评估时,它会抑制此评估并仅按原样产生 (1 2 3)

因为(1 2 3)是程序语法的一部分,但是语言有限制,不能修改这个列表。像 (inc (car (quote (1 2 3)))) 这样试图将列表更改为 (2 2 3) 的操作会调用未定义的行为。本质上,该程序试图修改自己的语法;如果我们暂时忽略 Lisp 是一种编译语言的额外复杂性,这是 事实上 自修改代码。