Evaluación ansiosa / orden de aplicación y evaluación perezosa / orden normal

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 evaluación entusiasta y orden aplicativo, evaluación perezosa y orden normal?


preguntado el 08 de enero de 11 a las 15:01

3 Respuestas

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)) luego 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).

Respondido el 08 de enero de 11 a las 18:01

Yes I am reading SICP. I followed the Wikipedia link and found this in Evaluación perezosa: "The expression is never evaluated more than once, called applicative-order evaluation." That means applicative order could also be used as a subtype of lazy evaluation? I'm a bit confused. - Ryan Li

@Ryan: Apparently the "Lazy evaluation" page uses a different definition of applicative order than the "Evaluation strategy" page does. I think in this case it's best to just ignore Wikipedia and go with what SICP says. - sepp2k

The Wikipedia article is very muddled concerning these concepts, unfortunately. As far as I can tell, this answer is more or less correct though. I would cavil slightly by stating that "applicative order" refers to the evaluation order used by eager evaluation strategies (call by value/call by reference), and "normal order" refers to the evaluation order used by lazy evaluation strategies (call by name/call by need). That may just be my particular interpretation though. Conclusion: if you ever use the words in writing, please define them explicitly! :) - Noldorin

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.

Y también debes

Lazy evaluation combines normal-order evaluation and sharing:

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

• Never evaluate something more than once (sharing)



Respondido 08 Feb 12, 22:02

"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." I don't think that part is true. If the language only supports normal-order evaluation, then how do you explicitly memo anything? You'd need some sort of mechanism to introduce strictness, be it strict variable definitions or a Haskell-like seq operator which forces its left operand to be evaluated before the right one. - sepp2k

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

Evaluación perezosa

Aunque la 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.

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

Con la 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 evaluación perezosa, 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.

Respondido 19 Abr '20, 18:04

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.