【问题标题】:With applicative order, what order are the arguments evaluated? Left to right or right to left?使用应用顺序,评估参数的顺序是什么?从左到右还是从右到左?
【发布时间】:2020-01-22 12:07:46
【问题描述】:

在 SICP 部分 1.1.5 过程应用的替换模型我很好奇求值的应用顺序。

我了解应用顺序会在应用外部过程之前评估参数。

我的问题是它通过参数的顺序是什么?

例如,

(+ (+ 2 1) (/ 10 2))

(+ 2 1)(/ 10 2) 会先得到评估吗?

【问题讨论】:

  • defines 不仅仅是稍后使用的旁注。它们是实际的计算动作,即刻定义指定的变量。
  • 我用更合适的例子编辑了帖子。

标签: scheme lisp sicp


【解决方案1】:

我假设您仍在阅读本书的第 1 章。请放心,本书的其余部分将更详细地向您解释这一点。目前,您可能对此footnote from section 3.2.1 The Rules for Evaluation 感兴趣:

...这个顺序 [从左到右或从右到左] 应该始终被视为一个实现细节,并且应该永远不要编写依赖于某些特定顺序的程序。例如,复杂的编译器可能会通过改变评估子表达式的顺序来优化程序。

后面的章节会越来越详细地讨论这个问题。例如:

  • Exercise 3.8:“定义一个简单的过程f,这样如果+ 的参数从左到右求值,(+ (f 0) (f 1)) 的求值将返回0,但如果参数从右到右求值,则返回1左”
  • Exercise 4.1 - 更改元循环评估器中的评估顺序。
  • Section 5.4.1 The Core of the Explicit-Control Evaluator评估过程应用程序小节)- 显示如何在显式控制评估器中实现过程应用程序。在这里您可以清楚地看到参数-求值循环的细节如何确定求值顺序。

【讨论】:

  • 请注意,“复杂的编译器”不需要语言规范来保持这样的顺序未定义。一个复杂的编译器可以在不改变从左到右顺序所需的结果的情况下重新排列实际顺序。
  • 在 C 中,指定了求值顺序,因为从历史上看,这允许开发 哑编译器。从历史上看,执行复杂的优化是 C 程序员的工作。编译器的工作只是进行非常基本的优化:选择好的指令,充分利用寄存器,避免明显的浪费(比如跳转到无条件跳转指令)。函数调用按照方便调用约定的顺序编译。例如。如果需要先将最左边的参数压入堆栈,则首先对其进行评估。
【解决方案2】:

在您的具体示例中,xy 之前被评估,因为两个 define 是按顺序评估的。

在函数调用中,例如:(+ (+ 2 3) (- 4 5)) (+ 2 3)(- 4 5) 的评估顺序在 Scheme 中未指定,与其他答案一样。而在其他 lisp 语言中,比如在 Common Lisp 中,是从左到右的。

【讨论】:

  • 那么它是随机的吗?
  • 它可以是随机的,也可以是任何其他顺序。未指定仅表示您在编写调用时不能假设任何顺序,可能不同调用中的顺序可能不同。
  • @joejoemac 通过不指定顺序,您可以选择许多路径之一进行扩展,但要求它应该保持一致。因此它不会是随机的。
【解决方案3】:

未指定。

procedure calls 小节中,您可以找到规范。

当一个过程调用被求值时,运算符和操作数表达式被求值(以未指定的顺序)并且结果过程被传递结果参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-13
    • 2019-10-26
    • 2011-06-09
    • 2021-02-20
    • 1970-01-01
    • 2019-09-13
    • 2014-08-16
    • 1970-01-01
    相关资源
    最近更新 更多