什么是需要的电话?

Bar*_*Das 18 evaluation programming-languages evaluation-strategy call-by-value call-by-need

我想知道什么是需要的电话.

虽然我在维基百科搜索并在此处找到它:http://en.wikipedia.org/wiki/Evaluation_strategy,但无法正确理解.如果有人可以用一个例子来解释并指出与按值调用的差异,那将是一个很大的帮助.

Rya*_*per 33

假设我们有这个功能

square(x) = x * x
Run Code Online (Sandbox Code Playgroud)

我们想评估square(1+2).

按值调用时,我们这样做

  1. square(1+2)
  2. square(3)
  3. 3*3
  4. 9

在我们这样做的名义呼吁中

  1. square(1+2)
  2. (1+2)*(1+2)
  3. 3*(1+2)
  4. 3*3
  5. 9

请注意,既然我们使用了两次参数,我们会对它进行两次评估.如果论证评估需要很长时间,那将是浪费.这就是需要修复的问题.

按需调用时,我们执行以下操作:

  1. square(1+2)
  2. let x = 1+2 in x*x
  3. let x = 3 in x*x
  4. 3*3
  5. 9

在第2步中,我们不是复制参数(比如在call-by-name中),而是给它起一个名字.然后在步骤3中,当我们注意到我们需要值时x,我们计算表达式x.只有这样我们才能替代.

顺便说一句,如果参数表达式产生了一些更复杂的东西,比如一个闭包,那么可能会有更多的lets,以消除复制的可能性.记下正式规则有点复杂.

请注意,我们"需要"原始操作的参数值,如+*,但对于其他函数,我们采用"名称,等待和查看"方法.我们可以说原始算术运算是"严格的".它取决于语言,但通常最原始的操作是严格的.

另请注意,"评估"仍然意味着减少到一个值.函数调用始终返回值,而不是表达式.(其中一个答案是错误的.)OTOH,懒惰语言通常具有惰性数据构造函数,它可以具有在需要时评估的组件,即,在提取时.这就是你可以拥有一个"无限"列表的方式---你返回的值是一个懒惰的数据结构.但是,对于懒惰与严格的数据结构,按需调用和按值调用是一个单独的问题.Scheme具有惰性数据构造函数(流),但由于Scheme是按值调用的,因此构造函数是语法形式,而不是普通函数.Haskell是按名称调用的,但它有定义严格数据类型的方法.

如果考虑实现是有帮助的,那么call-by- name的一个实现是将每个参数包装在thunk中; 当需要参数时,你调用thunk并使用该值.需求呼叫的一个实现是类似的,但是thunk是memoizing; 它只运行一次计算,然后保存它,然后只返回保存的答案.

  • Haskell 不是按需要调用而不是按名称调用吗? (3认同)

Jak*_*mpl 10

想象一个功能:

fun add(a, b) {
  return a + b
}
Run Code Online (Sandbox Code Playgroud)

然后我们称之为:

 add(3 * 2, 4 / 2)
Run Code Online (Sandbox Code Playgroud)

在按名称调用语言中,将对此进行评估:

  1. a = 3 * 2 = 6
  2. b = 4 / 2 = 2
  3. return a + b = 6 + 2 = 8

该函数将返回该值8.

在按需调用(也称为惰性语言)中,这样评估如下:

  1. a = 3 * 2
  2. b = 4 / 2
  3. return a + b = 3 * 2 + 4 / 2

该函数将返回表达式3 * 2 + 4 / 2.到目前为止,几乎没有花费任何计算资源.只有在需要它的值时才会计算整个表达式 - 比方说我们要打印结果.

为什么这有用?两个原因.首先,如果您不小心包含死代码,它不会降低您的程序权重,因此可以更高效.其次它允许做很酷的事情,比如用无限列表进行有效计算:

fun takeFirstThree(list) {
  return [list[0], list[1], list[2]]
}

takeFirstThree([0 ... infinity])
Run Code Online (Sandbox Code Playgroud)

尝试按名称语言挂起尝试创建从0到无穷大的列表.懒惰的语言将简单地返回[0,1,2].

  • 我认为你可能会混淆按名称调用,并且需要按名称调用. (10认同)
  • 我也认为这不准确.是不是你提到的名字,实际上是一个按值调用? (2认同)