是否有使用严格评估的Haskell编译器或预处理器?

时间:2009-06-15 13:17:04

标签: compiler-construction haskell lazy-evaluation

我正在寻找一个Haskell编译器,它默认使用严格的评估而不是延迟评估。我只会使用OCaml,但Haskell的语法比OCaml更好(并且Haskell是纯粹的,并且具有很酷的功能,例如类型类)。

我真的不会经常将!$!放在我的程序中。带有开关或预处理器的编译器可以输入严格的注释,这非常好。如果有一种方法在某些地方使用延迟评估也是有帮助的,以防万一我想要无限列表(我可能永远不会)。

请不要试图说服懒惰的评价更好,我真的需要表现。 IIRC,西蒙佩顿琼斯甚至说懒惰的评价并不是真的有必要,主要是为了防止他们使语言不纯洁。

11 个答案:

答案 0 :(得分:17)

  

我真的宁愿不经常把!s和$!s全部放在我的程序中

你做错了,如果你正在编程Haskell :)你根本不需要这样做。使用GHC,使用-O2,在适当的时候使用严格的数据类型,在适当的时候使用懒惰的数据类型。不要认为懒惰会成为一个问题 - 它可以解决很多问题。

答案 1 :(得分:16)

如果你有一个使用严格评估的Haskell编译器,它不会编译Haskell。 Laziness 非严格性是Haskell规范的一部分!

然而,还有其他选择。

  • DDC试图创建一个显式惰性的Haskell变体,它支持破坏性更新等内容,同时保留Haskell所有其余的优点。有一个问题:编译器目前只处于α阶段,虽然它似乎至少可用。

  • Create a preprocessor, as others have done.

  • 学会以“正确的方式”使用Haskell。如果您可以将测试用例简化为可公开显示的内容,则可以将其发布在Haskell-Café mailing list上,人们对这些关于非严格性影响的问题非常有帮助。

答案 2 :(得分:12)

过去有两次严格评估Haskell的尝试:

但两者都专注于坚持Haskell的非严格语义,但使用的是严格的评估策略,而不是真正改变语义,而且从未真正看到过光明。

编辑:Martijn对strict-plugin的建议看起来非常适合您的目的,因为它实际上做了您想要的并且作者仍然活跃在Haskell社区中,我已经忘记了它。

答案 3 :(得分:8)

答案 4 :(得分:7)

我感觉到你的痛苦。在我的日常编程中,我最大的PITA就是处理这些问题!@#$%^&(空间泄漏。

然而,如果它有所帮助,随着时间的推移你会学到(艰难的)如何处理这个问题,并且确实会变得更好。但是我还在等待Andy Gill带着他神奇的太空泄漏探测器来解决我的所有问题。 (我在最后一次ICFP上向我发表他的副评论,他认为这个很酷的想法是实现它的承诺。)

我不会试图说服你,懒惰的评价是世界上最好的,但有一些关于它的好处。我有一些流处理程序可以通过任何种类的组合器来搜索惰性列表,这些组合器在使用大约3.5 MB左右的内存(其中大于2MB是GHC运行时)时可以快速运行数十亿字节的数据。还有一个比我去年更聪明的人,你会真的很惊讶,作为一个典型的Haskell程序员,你有多依赖懒惰的评价。

但我们真正需要的是一本关于在现实世界中处理懒惰评估的非常好的书(这与学术界没那么不同,真的,除了他们根本没有发表论文,我们得到了客户我们用刀子来跟踪我们,这将适当地涵盖与此相关的大部分问题,更重要的是,让我们直观地了解将会爆炸我们的堆和什么不是。

我不认为这是新事物;我确信其他语言和架构也经历过这一点。毕竟,第一批程序员是如何处理硬件堆栈的呢?不太好,我打赌。

答案 5 :(得分:5)

我认为Jan-Willem Maessan的pH compiler是严格的。下一个最接近的是Robert Ennal对ghc 5的推测性评估分析.peclection_eval分支并不严格,而是乐观地评估。我不知道其中任何一个是否仍然是当前/可用的等等。

答案 6 :(得分:5)

在任何地方使用nfdata和rnf都不是解决方案,因为它意味着重复遍历已经评估过的大型结构。

Ben Lippmeier的博士论文(关于DDC)的介绍性章节是关于Haskell的最佳批评,我已经看过 - 它讨论了懒惰,破坏性更新,monad变换器等问题.DDC有懒惰但你必须明确地请求它,它被认为是一种效果,由DDC的类型和效果系统跟踪和管理。

答案 7 :(得分:5)

我最近在这方面看到了一些工作:

https://ghc.haskell.org/trac/ghc/wiki/StrictPragma

您可以在SPJ的GHC状态更新中听到一点关于它的信息:

http://youtu.be/Ex79K4lvJno?t=9m33s (链接从9:33的相关部分开始)

答案 8 :(得分:1)

  

我正在寻找一个默认情况下使用严格评估而不是延迟评估的Haskell编译器。

这样的编译器不是Haskell编译器。如果真的想要,您可以考虑将{-# LANGUAGE Strict #-} pragma放入您的文件中。这将适用于GHC 8.0.2,8.2.2和8.4.1,也就是编译器的最后三个版本。

  

如果有某种方法在某些地方使用延迟评估也是有帮助的,以防万一我想要无限列表

没有这样的方法。相反,按照预期使用GHC - 作为一种懒惰的语言。学会正确地思考你的代码,配置文件和使用功能数据结构比在任何地方盲目地应用严格编译指示要有用得多。 GHC已经有一个严格的分析仪。

  

(我可能永远不会)。

这确实是llvm-hs thought的作者在选择使用严格的状态monad而不是懒惰的时候。相反,它导致了一个意想不到的错误。懒惰和递归是相辅相成的。

  

请不要试图说服懒惰的评价更好,我真的需要表现。

我怀疑这实际上是你想要的,它不能可靠地提高Haskell代码的性能,同时破坏现有代码并使现有资源无用。如果您打算编写程序,请使用OCaml或Scala并单独留下Haskell社区。

  IIRC,Simon Peyton Jones甚至说懒惰的评价并非真的有必要,主要是为了防止他们使语言不纯。

事实并非如此。您可以阅读有关Haskell here

的实际历史的更多信息

答案 9 :(得分:0)

您显然已经决定了严格评估的价值,但我认为您忽略了使用Haskell的重点。 Haskell的惰性求值允许编译器/解释器采用更灵活的优化策略。强制自己的严格性会覆盖优化器。最后,使用过度严格的评估永远不会像自动化优化那样高效。尝试对GHCI中的一系列数字进行折叠求和,然后不进行惰性求值。您可以非常清楚地看到差异 - 在这种情况下,延迟评估总是更快。

答案 10 :(得分:0)

还有seqaid,其目标是懒惰严格的光谱中间。

  

Seqaid是一个GHC插件,提供Haskell项目的非侵入式自动检测,用于动态严格(和并行)控制。这将很快包括使用最小限度的自动化空间泄漏减轻的优化。