【问题标题】:Why does '(1 2 3) evaluate to a list en Lisp (Scheme)?为什么 '(1 2 3) 评估为一个列表 en Lisp (Scheme)?
【发布时间】:2016-09-01 08:43:55
【问题描述】:

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

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

但是为什么(quote (1 2 3)) 或(quote ()) 将#t 回答为谓词list?。

结果不应该是“预先评估”的值吗?但在这种情况下,(1 2 3) 实际上已经被评估为(list 1 2 3)?

谢谢。

【问题讨论】:

标签: scheme lisp evaluation quote


【解决方案1】:

预评估值

我不确定你从哪里得到这个词。我从来没有用过它。它不是“预先评估”,而是未经评估。

这实际上是因为 Lisp(和 Scheme)是 Homoiconic 的所有工作:程序的结构实际上在下面使用列表和原子。

quote 是 eval 的对偶:(eval (list '+ '1 '2 '3))(由于引用的数字只是数字,(eval (list '+ 1 2 3)) 也是如此)与 (quote '(+ 1 2 3)) 相反。

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

结果不应该是“预先评估”的值吗?但是在这种情况下,(1 2 3) 实际上已经被评估为 (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。 )

【讨论】:

  • 已编辑:应该是列表而不是列表?
  • (eval (list + 1 2 3)) 在我的方案中返回错误:“异常:无效语法 #”
  • 您可能需要(list '+ 1 2 3)。抱歉,我只安装了球拍。
  • 假设每个eval 删除quote 的级别。 quote 是“评估障碍”,eval 是评估者。
  • 谢谢你,牧师。我想我明白了。
【解决方案2】:

(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 中进行评估,但在此之前,必须读取。这意味着,将从文本源代码转换为实际的数据结构。

由于( ... ) 括号表示列表,阅读( ... ) forms 会创建列表。然后,评估 quoted 表单只会返回该表单 as is(即未评估)。令牌+ 被读取为符号 +;文字 1, 2, 3 被读取为 numbers 1, 2, 3。所以最终结果与评估表单(list '+ '1 '2 '3) 的结果相同。

当然,如果没有 + 内部,所有这些仍然适用。

【讨论】:

    【解决方案3】:

    这句话引入了一个未评估值,而不是预评估,不管这意味着什么。

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

    引用是程序表达的一种方式,“我想使用我自己的一段语法作为值”。这正是计算机科学中的“文字”:一段程序文本作为运行时值反射回程序中。

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

    因此,正在评估中,(quote 3) 和 3 之间没有区别。 “给我语法 3 本身”和“给我语法 3 的值”是一样的:只有 3。

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

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

    【讨论】:

      猜你喜欢
      • 2015-12-23
      • 1970-01-01
      • 2017-12-21
      • 1970-01-01
      • 1970-01-01
      • 2018-03-07
      • 1970-01-01
      • 1970-01-01
      • 2010-10-02
      相关资源
      最近更新 更多