急切求值/应用顺序和惰性求值/正常顺序

发布于 2024-10-11 11:00:00 字数 158 浏览 8 评论 0原文

据我所知,急切评估/应用顺序在应用函数之前评估函数的所有参数,另一方面,惰性评估/正常顺序仅在需要时评估参数。

那么,急切求值应用顺序这对术语以及惰性求值正常顺序之间有什么区别>?

谢谢。

As far as I know, eager evaluation/applicative order evaluates all arguments to a function before applying it, on the other hand, lazy evaluation/normal order evaluates the arguments only when needed.

So, what are the differences between the pair of terms eager evaluation and applicative order, and lazy evaluation and normal order?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

锦欢 2024-10-18 11:00:00

惰性求值最多对一个术语求值一次,而正常顺序会按照它出现的次数对其求值。例如,如果您有 f(x) = x+x 并将其称为 f(g(42))g(42) code> 在惰性求值或应用顺序下调用一次,但在正常顺序下调用两次。

热切求值和应用顺序是同义词,至少在使用《计算机程序的结构和解释》中的应用顺序定义时是如此,这似乎与您的定义相符。 (Wikipedia 定义的应用顺序有点不同,并将其作为热切求值的特殊情况) 。

Lazy evaluation evaluates a term at most once, while normal order would evaluate it as often as it appears. So for example if you have f(x) = x+x and you call it as f(g(42)) then g(42) is called once under lazy evaluation or applicative order, but twice under normal order.

Eager evaluation and applicative order are synonymous, at least when using the definition of applicative order found in Structure and Interpretation of Computer Programs, which seems to match yours. (Wikipedia defines applicative order a bit differently and has it as a special case of eager evaluation).

月依秋水 2024-10-18 11:00:00

我也在读SICP,我对作者给出的正常顺序的定义很好奇。对我来说,它似乎与惰性评估非常相似,所以我去寻找有关两者的更多信息。

我知道这个问题很久以前就被问过,但我查看了常见问题解答,发现没有提到回答旧问题,所以我想我应该把我在这里找到的内容留下,以便其他人将来可以使用它。

这是我发现的,我倾向于同意这些:

我认为(和其他人一样)懒惰的评估和
NormalOrderEvaluation 是两个不同的东西;区别在于
上面已经提到了。在惰性求值中,参数的求值是
推迟到需要时为止,此时对参数进行求值
并保存(记忆)其结果。论证中的进一步使用
函数使用计算值。 C/C++ 运算符 ||、&& 和 ? :
都是惰性求值的例子。 (除非是一些新手 C/C++
程序员愚蠢到可以重载 &&或||,在这种情况下
重载版本按照严格的顺序进行评估;这就是为什么 &&
和||切勿在 C++ 中重载运算符)。

换句话说,每个参数最多被评估一次,可能不会
完全没有。

NormalOrderEvaluation 另一方面,重新评估表达式
每次使用时。想想 C 宏、CallByName 语言中的
支持它,以及循环控制结构的语义等。
正常顺序评估可能比应用顺序评估花费更长的时间
评估,并可能导致副作用不止一次发生。
(当然,这就是为什么带有副作用的陈述通常应该
不能作为 C/C++ 中宏的参数给出)

如果参数是不变的并且没有副作用,则唯一的
两者之间的区别在于性能。确实,在纯粹的
函数式语言中,lazy eval 可以被视为一种优化
正态顺序评估。存在副作用或表达
重新计算时可以返回不同的值,两者有
不同的行为;正常顺序评估尤其不好
由于推理困难而在过程语言中享有盛誉
关于没有 ReferentialTransparency 的此类程序

还应该注意,严格顺序评估(以及惰性评估)
评估)可以用支持正常顺序的语言来实现
通过显式记忆进行评估。反之则不然。它需要
传入可调用/消息传递的 thunk、函数或对象
以便推迟/重复评估。

惰性求值结合了正态顺序求值和共享:

• 除非必要,否则切勿评估某些事物(正常顺序)

• 切勿多次评估某事物(共享)

http://c2.com/cgi/wiki?LazyEvaluation

http://cs.anu.edu.au/student/comp3610/lectures/Lazy.pdf

I'm reading SICP too, and I've been curious by the definition of normal order given by the authors. It seemed rather similar to Lazy evaluation to me, so I went looking for some more information regarding both.

I know this question was asked a long time ago, but I looked at the FAQ and found no mention of answering old questions, so I thought I'd leave what I've found here so other people could use it in the future.

This is what I've found, and I'm inclined to agree with those:

I would argue (as have others) that lazy evaluation and
NormalOrderEvaluation are two different things; the difference is
alluded to above. In lazy evaluation, evaluation of the argument is
deferred until it is needed, at which point the argument is evaluated
and its result saved (memoized). Further uses of the argument in the
function use the computed value. The C/C++ operators ||, &&, and ? :
are both examples of lazy evaluation. (Unless some newbie C/C++
programmer is daft enough to overload && or ||, in which case the
overloaded versions are evaluated in strict order; which is why the &&
and || operators should NEVER be overloaded in C++).

In other words, each argument is evaluated at most once, possibly not
at all.

NormalOrderEvaluation, on the other hand, re-evaluates the expression
each time it is used. Think of C macros, CallByName in languages which
support it, and the semantics of looping control structures, etc.
Normal-order evaluation can take much longer than applicative order
evaluation, and can cause side effects to happen more than once.
(Which is why, of course, statements with side effects generally ought
not be given as arguments to macros in C/C++)

If the argument is invariant and has no side effects, the only
difference between the two is performance. Indeed, in a purely
functional language, lazy eval can be viewed as an optimization of
normal-order evaluation. With side effects present, or expressions
which can return a different value when re-evaluated, the two have
different behavior; normal order eval in particular has a bad
reputation in procedural languages due to the difficulty of reasoning
about such programs without ReferentialTransparency

Should also be noted that strict-order evaluation (as well as lazy
evaluation) can be achieved in a language which supports normal-order
evaluation via explicit memoing. The opposite isn't true; it requires
passing in thunks, functions, or objects which can be called/messaged
in order to defer/repeat the evaluation.

And

Lazy evaluation combines normal-order evaluation and sharing:

• Never evaluate something until you have to (normal-order)

• Never evaluate something more than once (sharing)

http://c2.com/cgi/wiki?LazyEvaluation

http://cs.anu.edu.au/student/comp3610/lectures/Lazy.pdf

避讳 2024-10-18 11:00:00

来自 Kevin Sookocheff正常、应用和惰性评估帖子(强调,我的风格改变):

惰性评估

虽然正态顺序评估可能会导致做额外的工作
要求函数参数被评估多次,
应用顺序评估可能会导致程序不
在其正常顺序等价物所在的地方终止。在实践中,大多数
函数式编程语言使用lazy解决这个问题
评价。

通过惰性求值,我们以一种避免以下情况的方式延迟函数求值:
对同一函数进行多次评估——从而结合
正态顺序应用顺序评估的好处。

懒惰
评估,我们在需要时评估一个值,然后
评估该表达式的所有副本都更新为新的
价值。实际上,传递给函数的参数存储在
内存中的单个位置,以便仅需要评估参数
一次。也就是说,我们记住了我们特定的所有地点。
将使用参数,当我们计算一个函数时,我们替换
与值的争论。

因此,通过惰性评估每个
参数最多评估一次

这太长了,无法作为问题下的评论发布,并且用它更新现有答案似乎不合适,因此这个答案。

From Kevin Sookocheff's Normal, Applicative and Lazy Evaluation post (emphases, stylistic changes mine):

Lazy Evaluation

While normal-order evaluation may result in doing extra work by
requiring function arguments to be evaluated more than once,
applicative-order evaluation may result in programs that do not
terminate where their normal-order equivalents do. In practise, most
functional programming languages solve this problem using lazy
evaluation
.

With lazy evalution, we delay function evaluation in a way that avoids
multiple evaluations of the same function — thus combining the
benefits of normal-order and applicative-order evaluation.

With lazy
evaluation
, we evaluate a value when it is needed, and after
evaluation all copies of that expression are updated with the new
value. In effect, a parameter passed into a function is stored in a
single location in memory so that the parameter need only be evaluated
once. That is, we remember all of the locations where we a certain
argument will be used, and when we evaluate a function, we replace the
argument with the value.

As a result, with lazy evaluation, every
parameter is evaluated at most once
.

This was too long to post as a comment beneath the question, and updating existing answers with it seemed inappropriate, hence this answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文