聪明地使用严格的评估在哪里?

时间:2009-03-16 17:22:42

标签: haskell lazy-evaluation

在懒惰评估的语言中,似乎有很多聪明的事情都是在严格评估的环境中完成的。例如Haskell中的无限列表或replacing every element in a tree with the tree's minimum value in one pass

是否有任何巧妙的事情以严格评估的语言进行,并且不能用懒惰评估的语言轻松完成?

9 个答案:

答案 0 :(得分:8)

你可以用急切的(严格的)语言而不是懒惰的语言轻松完成主要的事情:

  • 从源代码预测程序的时间和空间成本

  • 允许副作用,包括可变数组的恒定时间更新,这使得更快地实现某些算法更容易

在我看来,热切语言的主要好处是让代码以您想要的方式执行变得容易得多,并且很少有性能陷阱,其中代码中的微小变化会导致巨大的变化在表现。

话虽如此,总的来说我更喜欢在Haskell中编写复杂的东西。

答案 1 :(得分:5)

没有;有一些你可以做的事情*懒惰评估(AKA正常顺序减少,或左外侧减少),你不能用严格的评估,但不是相反。

这样做的原因是,懒惰评估在某种程度上是评估的“最一般”方式,这被称为:

  

计算充分性定理:   如果某些评估顺序终止并产生特定结果,那么延迟评估也将终止并产生相同的结果。

*(请注意我们在这里谈论图灵等价)

答案 2 :(得分:4)

嗯,不,或多或少的定义。在懒惰评估语言中,您应该按照定义获得与您精力充沛相同的结果(人们真的使用“严格”现在?)评估,除了延迟评估直到需要,存储影响等等。所以如果你能得到一些不同的行为除了,那就是一个bug。

答案 3 :(得分:2)

在日常语言中最明显的懒惰用法是“if”语句,其中只执行条件的一个分支。

与纯粹非严格(懒惰)语言相反的是纯粹严格的语言。

至少有一种情况,即“纯粹严格”是有益的,即branch predication

链接文章的粗略释义:

很久以前,在CPU的世界中,在测试分支条件时加载了执行指令。在某些时候,添加了指令流水线以减少加载时间。缺点是CPU不知道它需要加载哪个分支,所以它默认加载一个。如果分支以另一种方式运行,则管道将在加载另一个分支的代码时停止。

解决方案是加载两个分支,执行两个分支,然后条件的结果告诉您要保留哪个分支结果,以及丢弃哪个分支结果。然后你就不会出现管道停滞。

这是我最喜欢的(仅限于?)纯粹严格语言的好处的例子。

答案 4 :(得分:1)

'Hello,World'程序浮现在脑海中,或者所有与副作用基本相关的事情。

在严格评估中,评估表达式很容易产生副作用,因为您对评估顺序有清晰的概述,因此副作用的顺序通常在副作用中很重要。这是严格评估的基本优势,也是大多数语言拥有它的原因。为什么像C这样的面向性能的语言经常使用按值传递模型。

两者都可以做同样的事情,只要有不同程度的人类困难,你就可以用严格的语言很好地模拟无限列表,你可以用非严格语言模拟副作用的所有效果。

答案 5 :(得分:0)

在严格的评估语言(如C#)中,可以通过将thunk返回值(Func)而不是值本身来实现延迟评估。作为在c#中构造Y-Combinator的一个例子,可以这样做:

public Func<int, int> Y(Func<Func<int, int>, Func<int, int>> f)
{
    return x => f(Y(f))(x);
}

这个声明在懒惰的环境中会更简洁:

Y f = f (Y f)

答案 6 :(得分:0)

作为Charlie Martin wrote,严格和懒惰程序的结果应该是等效的。差异在于时间和空间限制和/或语言表达。除了懒惰对不需要的值的性能影响之外,懒惰语言可以容易地引入新的语言构造而没有额外的语言概念(例如LISP中的宏)。无论如何,懒惰可以咬你 How does Haskell tail recursion work?同样的想法可能比严格的语言更复杂。 (haskell编译器不应该认识到计算+1比make thunk ( x + 1 )便宜吗?)

答案 7 :(得分:0)

我在Erlang中编程了一下,发现我在大学里学到的懒惰评价很少令人沮丧。

我一直在简要介绍Euler的一些项目问题,尤其是那些与素数有关的问题。

使用延迟评估,您可以使用一个返回所有素数列表的函数,但它实际上只返回您实际需要的素数。因此,很容易说“给我第一个 n 素数”。

如果没有懒惰的评估,你最终会得到更多限制“给我一个1和 n 之间所有素数的列表。”

答案 8 :(得分:-5)

不幸的是,被评为最佳答案的答案因逻辑错误而受到影响。 根据定理,Porges引用并不意味着人们可以用懒惰语言做更多事情。

相反的证据是,所有懒惰语言的程序都被编译成严格语言的等效语言(进一步编译为汇编程序)或由严格语言编写的解释程序执行(是的,解释器最终的汇编程序。)