混合Erlang和Haskell


Answers

你将有一个有趣的时间在Haskell和Erlang之间混合GC。 Erlang使用每进程堆并在进程之间复制数据 - 因为Haskell甚至没有进程的概念,我不确定如何在两者之间映射这个“通用”GC。 此外,为了获得最佳性能,Erlang使用各种分配器,每个分配器都有轻微的调整行为,我肯定会影响GC子系统。

与软件中的所有内容一样,抽象是有代价的。 在这种情况下,我宁愿怀疑你必须引入这么多层来使两种语言超过它们的阻抗不匹配,以至于你最终会遇到性能不高(或有用)的常见虚拟机。

底线 - 拥抱差异! 不在同一过程中运行所有内容具有巨大的优势,特别是从可靠性的角度来看。 另外,我认为期待一个语言/ VM在你的余生中持续使用(除非你计划在。),生活很短的时间或者b。)成为​​某种代码僧侣只会在你的生活中工作,这有点天真单个项目)。 软件开发完全是关于心理敏捷性,并愿意使用最好的工具来构建快速,可靠的代码。

Question

如果您已经购买了函数式编程范例,那么您很可能同时喜欢Erlang和Haskell。 两者都具有纯粹的功能核心和其他优点,如轻量级线程,使其非常适合多核世界。 但也存在一些差异。

Erlang是一种经过商业验证的容错语言,具有成熟的分发模型。 它具有看似独特的功能,能够通过热代码加载在运行时升级其版本。 (太酷了!)

另一方面,Haskell拥有任何主流语言中最复杂的类型系统。 (我将'主流'定义为任何已发布的O'Reilly书籍的语言,因此Haskell很重要。)它的直线单线程性能看起来优于Erlang,其轻量级线程看起来更轻。

我正在尝试为我的编码生命的其余部分组建一个开发平台,并且想知道是否有可能将Erlang和Haskell混合以实现最佳的平台。 这个问题有两个部分:

  1. 我想使用Erlang作为一种容错MPI来将GHC运行时实例粘合在一起。 每个GHC运行时会有一个Erlang进程。 如果“不可能发生”并且GHC运行时死亡,那么Erlang进程会以某种方式检测到并且也会死亡。 Erlang的热代码加载和分发功能将继续工作。 GHC运行时可以配置为仅使用一个核心,或本地计算机上的所有核心,或其间的任何组合。 一旦编写了Erlang库,Erlang级别代码的其余部分应该是纯粹的样板,并在每个应用程序的基础上自动生成。 (例如,可能以Haskell DSL为例。)如何实现至少其中一些内容?
  2. 我希望Erlang和Haskell能够共享同一个收集器。 (这是一个比1更远的想法。)在JVM和CLR上运行的语言通过共享运行时实现更大的质量。 我知道在JVM或CLR上运行Erlang(热代码加载)和Haskell(更高的kinded多态)存在技术限制。 但是如果只拆分垃圾收集器呢? (函数式语言的运行时的开始排序。)分配显然仍然必须非常快,所以也许这个位需要静态链接。并且应该有一些机制来区分可变堆和不可变堆(因为GHC需要这个,所以包括懒惰写一次内存)。 是否可以修改HIPE和GHC以便垃圾收集器可以共享堆?

请回答任何经验(积极或消极),想法或建议。 事实上,任何反馈(没有直接滥用!)都是受欢迎的。

更新

感谢迄今为止的所有4个回复 - 每个回复教我至少一个我不知道的有用的东西。

关于其余的编码生活事物 - 我在脸颊上稍微用舌头包括引发辩论,但实际上是真的。 有一个我想到的项目,我打算继续工作直到我死,它需要一个稳定的平台。

在我上面提到的平台中,我只会编写Haskell,因为将自动生成样板Erlang。 那么Haskell会持续多久? 好吧,Lisp仍然和我们在一起,看起来不会很快消失。 Haskell是BSD3的开源软件,已达到临界质量。 如果编程本身在50年左右仍然存在,我会期望Haskell,或者Haskell的一些不断演变,仍然会在这里。

更新2 以回应rvirding的帖子

同意 - 实现一个完整的“Erskell / Haslang”通用虚拟机可能并非绝对不可能,但确实非常困难。 尽管如此,将垃圾收集器级别作为VM之类的东西共享虽然仍然很难 ,但听起来要小一些。 在垃圾收集模型中,函数式语言必须有许多共同点 - 不可变数据(包括thunk)的无处不在和非常快速分配的要求。 因此,将通用性与单片VM紧密捆绑在一起这一事实似乎有些奇怪。

虚拟机确实有助于实现临界质量。 看看像F#和Scala这样的“精简”功能语言是如何起飞的。 Scala可能没有Erlang的绝对容错能力,但它为许多与JVM绑定的人提供了一条逃生路线。

虽然拥有单个堆会使消息传递速度非常快,但它会引入许多其他问题,主要是因为它必须是交互式的且全局不中断的,所以做GC会变得更加困难,所以你不能使用相同的简单算法。进程堆模型。

当然,这对我来说非常有意义。 GHC开发团队中非常聪明的人似乎试图通过平行的“停止世界”GC来解决部分问题。

http://research.microsoft.com/en-us/um/people/simonpj/papers/parallel-gc/par-gc-ismm08.pdf

(显然,“停止世界”不会因为它的主要用例而对一般的Erlang飞行。)但即使在“停止世界”的用例中也是如此,它们的加速似乎并不普遍。 所以我同意你的观点,不太可能有一个普遍最好的GC,这就是我在我的问题第1部分中指出的原因。

GHC运行时可以配置为仅使用一个核心,或本地计算机上的所有核心,或其间的任何组合。

通过这种方式,对于给定的用例,我可以在基准测试后选择使用Erlang方式,并运行一个GHC运行时(使用单线程GC)和每个核心一个Erlang进程,让Erlang在内核之间复制内存以获得良好的局部性。

或者,在处理器上具有4个核心/处理器并具有良好内存带宽的双处理器计算机上,基准测试可能表明我运行一个GHC运行时(使用并行GC)和每个处理器一个Erlang进程。

在这两种情况下,如果Erlang和GHC可以共享一个堆,那么共享可能会绑定到以某种方式在单个核上运行的单个OS线程。 (我在这里深入了解,这就是我问这个问题的原因。)

我还有另一个议程 - 独立于GC的功能语言基准测试。 我经常阅读OCaml v GHC v Erlang v ...的基准测试结果,并想知道不同的GC会对结果造成多大的影响。 如果选择GC可以与函数式语言的选择正交怎么办? GC究竟有多昂贵? 看到这个恶魔倡导者博客文章

http://john.freml.in/garbage-collection-harmful

由我的Lisp朋友约翰弗雷姆林,他迷人地,给他的帖子标题“自动垃圾收集是垃圾”。 当约翰声称GC很慢并且没有真正加速那么多时,我希望能够用一些数字来对抗。




CLR支持使用显式tail操作码(由F#使用)进行尾调用优化,JVM没有(尚未)具有等效,这限制了这种语言风格的实现。 使用单独的AppDomain确实允许CLR热插拔代码(参见此博客文章,展示如何完成)。

Simon Peyton Jones在Don Syme和微软研究院的F#团队的走廊上工作,如果我们最终没有看到具有某种官方地位的IronHaskell,那将是一个非常令人失望的事。 IronErlang将是一个有趣的项目 - 最大的工作可能是移植绿色线程调度程序,而不是像Windows Workflow引擎那样重量级,或者必须在CLR上运行BEAM VM。




  1. 您可以使用OTP gen_supervisor进程来监视使用open_port()生成的Haskell实例。 根据“端口”退出的方式,您可以重新启动它或者确定它是故意停止的,并让相应的Erlang进程也死掉。

  2. Fugheddaboudit。 即使是这些与语言无关的虚拟机,有时也会遇到语言之间传递的数据问题。 你应该以某种方式在两者之间序列化数据:数据库,XML-RPC,类似的东西。

顺便说一下,在你的余生中使用单一平台的想法也可能是不切实际的。 计算技术和时尚变化太频繁,以至于你可以永远只使用一种语言。 你的问题指出了这一点:即使在今天,也没有任何一种语言可以做我们想要的一切。




Related