我想知道什么是按需调用。
虽然我在维基百科中搜索并在这里找到了它: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/