急切评估/应用订单和懒惰评估/正常订单

时间:2011-01-08 15:22:00

标签: programming-languages evaluation sicp

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

那么,渴望评估应用订单,以及懒惰评估正常顺序这两个术语之间有什么区别?

感谢。

3 个答案:

答案 0 :(得分:8)

懒惰评估最多评估一次,而普通订单会评估它的频率。例如,如果您有f(x) = x+x并将其称为f(g(42)),那么g(42)会在延迟评估或应用订单下调用一次,但在正常顺序下调用两次。

渴望评估和应用顺序是同义词,至少在使用计算机程序的结构和解释中找到的应用顺序的定义时,这似乎与您的匹配。 (Wikipedia定义了不同的应用顺序,并将其作为急切评估的特例)。

答案 1 :(得分:5)

我也正在阅读SICP,我对作者给出的正常顺序的定义感到好奇。它似乎与我的懒惰评价相似,所以我去寻找关于两者的更多信息。

我知道很久以前就问了这个问题,但我查看了常见问题解答并没有提及回答旧问题,所以我想我会留下我在这里找到的内容,以便其他人可以在将来

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

  

我认为(和其他人一样)懒惰的评价和   NormalOrderEvaluation是两个不同的东西;不同的是   上面提到的。在懒惰的评估中,对论证的评价是   延迟到需要时,在此时评估参数   并保存其结果(备忘录)。进一步使用了论证   函数使用计算值。 C / C ++运算符||,&&和? :   都是懒惰评估的例子。 (除非是一些新手C / C ++   程序员愚蠢到足以超载&&或||,在这种情况下   重载版本按严格顺序评估;这就是为什么&&   和||运算符永远不应该在C ++中重载。)

     

换句话说,每个参数最多只评估一次,可能不是   一点都不。

     另一方面,

NormalOrderEvaluation重新计算表达式   每次使用它。想想C语言中的C语言,CallByName   支持它,以及循环控制结构的语义等。   正常订单评估可能比申请订单花费更长的时间   评估,并可能导致副作用不止一次发生。   (当然,这就是为什么一般应该有副作用的陈述   不能作为C / C ++中宏的参数提供)

     

如果参数是不变的并且没有副作用,那么唯一的   两者之间的差异是表现。的确,纯粹是一种   功能语言,懒惰的eval可以被视为一种优化   正常的评估。有副作用或表达   在重新评估时可以返回不同的值,两者都有   不同的行为;正常的顺序eval尤其是坏的   由于推理的困难,在程序语言中的声誉   关于没有ReferentialTransparency的此类程序

     

还应该注意严格的订单评估(以及懒惰   评估)可以用支持正常顺序的语言来实现   通过明确的备忘录进行评估。相反的情况并非如此;这个需要   传入可以调用/发送消息的thunk,函数或对象   为了推迟/重复评估。

  

懒惰评估结合了正常订单评估和共享:

     

•在您必须(正常订购)

之前,永远不要评价      

•永远不要评价某些内容(分享)

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

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

答案 2 :(得分:0)

来自Kevin SookocheffNormal, Applicative and Lazy Evaluation帖子(重点是我的风格变化):

懒惰评估

正常订单评估可能会导致 要求对函数参数进行多次评估, 应用顺序评估可能会导致程序无法执行 在其正常顺序的等效位置处终止。实际上,大多数 功能性编程语言使用 lazy解决了此问题 评估

通过惰性评估,我们以一种避免 相同功能的多个评估-因此将 正常订单应用订单评估的好处。

懒惰 评估,我们会在需要时以及之后评估一个值 评估用新的表达式更新该表达式的所有副本 值。实际上,传递给函数的参数存储在 内存中的单个位置,因此仅需要评估参数 一旦。也就是说,我们记得所有 参数将被使用,当我们评估一个函数时,我们替换 带有值的参数。

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

这个时间太长了,无法在问题下方发表评论,并且用它来更新现有答案似乎不合适,因此是这个答案。