programming-languages - 什么是按需调用?

标签 programming-languages evaluation call-by-value evaluation-strategy call-by-need

我想知道什么是按需调用。

虽然我在维基百科中搜索并在这里找到了它:http://en.wikipedia.org/wiki/Evaluation_strategy ,
但无法正确理解。
如果有人可以举例说明并指出按值调用的区别,那将是一个很大的帮助。

最佳答案

假设我们有函数

square(x) = x * x

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

按值调用 , 我们的确是
  • square(1+2)
  • square(3)
  • 3*3
  • 9

  • 点名 , 我们的确是
  • square(1+2)
  • (1+2)*(1+2)
  • 3*(1+2)
  • 3*3
  • 9

  • 请注意,由于我们使用了两次参数,因此我们对其进行了两次评估。如果参数评估需要很长时间,那将是一种浪费。这就是按需调用解决的问题。

    按需来电 ,我们执行以下操作:
  • square(1+2)
  • let x = 1+2 in x*x
  • let x = 3 in x*x
  • 3*3
  • 9

  • 在第 2 步中,我们没有复制参数(如按名称调用),而是给它一个名称。然后在第 3 步中,当我们注意到我们需要 x 的值时,我们计算 x 的表达式.只有这样我们才能替代。

    顺便说一句,如果参数表达式产生更复杂的东西,比如闭包,可能会有更多 let 的改组。 s左右,杜绝抄袭的可能。正式的规则写起来有些复杂。

    请注意,我们“需要”原始操作(如 +)的参数值。和 * ,但对于其他功能,我们采用“命名、等待和查看”的方法。我们会说原始算术运算是“严格的”。这取决于语言,但通常大多数原始操作都是严格的。

    另请注意,“评估”仍然意味着减少到一个值。函数调用总是返回一个值,而不是表达式。 (其他答案之一弄错了。)OTOH,惰性语言通常具有惰性数据构造函数,它可以具有按需评估的组件,即在提取时。这就是你可以拥有一个“无限”列表的方式——你返回的值是一个惰性数据结构。但是按需调用与按值调用是与惰性数据结构与严格数据结构不同的问题。 Scheme 有惰性数据构造函数(流),尽管由于 Scheme 是按值调用的,构造函数是语法形式,而不是普通函数。 Haskell 是按名称调用的,但它有定义严格数据类型的方法。

    如果它有助于考虑实现,那么调用的一种实现- 姓名 是将每个参数包装在一个 thunk 中;当需要参数时,调用 thunk 并使用该值。 call-by- 的一种实现需要是相似的,但 thunk 正在内存;它只运行一次计算,然后保存它,然后返回保存的答案。

    关于programming-languages - 什么是按需调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5526059/

    相关文章:

    programming-languages - 在程序中使用括号会降低可读性的例子有哪些?

    c++ - 对 is_array 模板类的评估感到困惑

    c++ - 为什么合并的上限和下限比较总是评估为真?

    java - 重访按值调用与按引用调用

    c++ - 为什么我在传递 vl 或 vl1 时得到与输出相同的值 (0x7fff5fbff808)?地址应该不同

    javascript - 还有哪些其他语言像 JavaScript 一样是松散类型的?

    data-binding - 初学者问题 : What is binding?

    programming-languages - 如何开发像 Coffee Script 这样的编程语言?

    package - SLIME 交互式开发 - 将代码粘贴到 SLIME REPL != 来自缓冲区的 eval 命令

    java - 通过引用调用 - 或 - 通过值调用