applicative-order/call-by-value 和 normal-order/call-by-name 的区别

Arc*_*520 3 evaluation scheme programming-languages sicp operator-precedence

背景

我正在根据在线课程学习 sicp,但对它的讲义感到困惑。在讲义中,applicative order 似乎等于 cbv 和 normal order 等于 cbn。

困惑

但是wiki指出,除了求值顺序(从左到右,从右到左,或者同时),applicative order和cbv是有区别的:

与按值调用不同,应用顺序评估在应用函数之前尽可能地减少函数体内的术语。

我不明白减少是什么意思。在进入函数计算之前,应用顺序和 cbv 都不会获得变量的确切值。

而对于正常的顺序和cbv,根据wiki,我更加困惑。

相比之下,按名称调用策略不会在未应用的函数体内求值。

我猜这是否意味着正常顺序会在未应用的函数体内进行评估。怎么会这样?

  1. 有人能给我一些关于四种策略的更具体的定义吗?
  2. 有人可以使用任何编程语言为每种策略展示一个示例。

非常感谢?

Rpt*_*ptx 6

应用顺序(不考虑评估顺序,在方案中是未定义的)将等同于 cbv。在进入函数体之前,函数调用的所有参数都被完全评估。这是 SICP 中给出的示例

(define (try a b)
  (if (= a 0) 1 b))
Run Code Online (Sandbox Code Playgroud)

如果您定义函数,并使用以下参数调用它:

(try 0 (/ 1 0))
Run Code Online (Sandbox Code Playgroud)

当使用应用顺序评估(方案中的默认值)时,这将产生错误。它会(/ 1 0)在进入身体之前进行评估 。使用正常顺序求值时,这将返回 1。参数将在不求值的情况下传递给函数体,并且(/ 1 0)永远不会被求值,因为它(= a 1)为真,从而避免了错误。

在您链接到的文章中,当他们提到 Applicative 和 Normal 阶评估时,他们在谈论 Lambda 微积分。在这篇文章wiki 中,我认为解释得更清楚。缩减意味着将缩减规则应用于表达式。(也在链接中)。

?-转换:改变绑定变量(alpha);

?-reduction:将函数应用于它们的参数(测试版);

正常顺序:

最左边、最外面的 redex 总是首先减少。也就是说,只要有可能,在减少参数之前将参数替换到抽象的主体中。

直呼

按照正常顺序,但在抽象内部不执行缩减。例如 ?x.(?xx)x 根据此策略是正常形式,尽管它包含 redex (?xx)x。

范式是一个等价的表达式,在形式强加的规则下不能进一步简化

在同一篇文章中,他们谈到了按价值调用

只有最外层的 redex 会减少:只有当它的右侧减少到一个值(变量或 lambda 抽象)时,才会减少 redex。

及适用顺序:

最左边、最里面的 redex 总是首先减少。直观地说,这意味着函数的参数总是在函数本身之前减少。

您可以阅读我链接的文章以获取有关 lambda 演算的更多信息。还有编程语言基础