混合Erlang和Haskell

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

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

另一方面,Haskell拥有任何主stream语言中最复杂的types系统。 (我把'主stream'定义为任何具有已发表的O'Reilly书籍的语言,所以哈斯克尔就是这样评价的)。它的直线单线程性能看起来比Erlang更好,轻量级线程看起来更轻。

我正试图为我剩下的编码生活组build一个开发平台,并想知道是否可以将Erlang和Haskell混合起来,以实现最佳的平台。 这个问题有两个部分:

  1. 我想使用Erlang作为一种容错MPI来将GHC运行时实例粘合在一起。 每个GHC运行时将会有一个Erlang进程。 如果“不可能发生”和GHC运行时间死了,那么Erlang进程会以某种方式检测到并死掉。 Erlang的热门代码加载和分发function将继续工作。 可以将GHC运行时configuration为仅使用一个核心,或者本地机器上的所有核心,或两者之间的任何组合。 一旦编写了Erlang库,其余的Erlang级别代码应该是纯粹的样板,并在每个应用程序的基础上自动生成。 (也许通过一个Haskell DSL例如。)如何实现至less一些这些东西?
  2. 我希望Erlang和Haskell能够共享相同的garabage收集器。 (这是比1更进一步的想法。)运行在JVM和CLR上的语言通过共享运行时间实现更大的质量。 我明白,在JVM或CLR上运行Erlang(热代码加载)和Haskell(更高版本的多态)有技术限制。 但是,解开垃圾收集器呢? (对函数式语言的运行时间的开始进行sorting)分配显然还是要非常快,所以也许这一点需要静态链接。而且应该有一些机制来区分可变堆和不可变堆(包含懒惰的一次写入内存),因为GHC需要这个。 修改HIPE和GHC是否可行,以便垃圾收集者可以共享堆?

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

更新

感谢所有4个回复date – 每个教我至less有一个有用的东西,我不知道。

关于编码生活的其余部分 – 我把它包含在脸颊中引起争论,但实际上是这样。 我有一个项目,我打算继续努力,直到我死,它需要一个稳定的平台。

在上面提出的平台中,我只会编写Haskell,因为Erlang将自动生成。 那么Haskell会持续多久呢? Lisp依然和我们在一起,看起来好像很快就会消失。 Haskell是BSD3开放源代码,已经达到临界质量。 如果编程本身仍然是50年左右的时间,那么我认为Haskell或者Haskell的一些持续发展仍然会在这里。

更新2 回应rvirding的post

同意 – 实现一个完整的“Erskell / Haslang”通用虚拟机可能不是绝对不可能的,但是确实会非常困难。 虽然垃圾收集器级别只是像虚拟机一样共享,虽然仍然困难 ,但对我来说听起来要难一些。 在垃圾收集模型中,函数式语言必须有很多共同之处 – 不可变数据(包括thunk)的非普遍性和对非常快的分配的要求。 因此,通用性与单一虚拟机紧密捆绑的事实似乎有些奇怪。

VM有助于实现临界质量。 只要看看F#和Scala等“精简”function语言是如何起飞的。 Scala可能不具有Erlang的绝对容错能力,但是它为与JVM绑定的很多人提供了一条逃生路线。

虽然有一个堆使消息传递非常快,但它引入了一些其他问题,主要是因为GC必须是交互式的和全局的非中断性的,所以不能使用与每个堆一样简单的algorithm,过程堆模型。

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

en-us/um/people/simonpj/papers/parallel-gc/par-gc-ismm08.pdf

(显然,“停止世界”对于一般的Erlang来说不会因为它的主要用例而飞)。但是即使在“停止世界”的情况下,它们的加速似乎并不普遍。 所以我同意你的观点,这是不太可能的,因为在我的问题的第一部分中,

可以将GHC运行时configuration为仅使用一个核心,或者本地机器上的所有核心,或两者之间的任何组合。

这样,对于一个给定的用例,我可以在基准testing之后selectErlang方式,并且运行一个GHC运行时(使用单线程GC),每个内核运行一个Erlang进程,让Erlang在内核之间复制内存以获得良好的本地化。

或者,在双处理器机器上,每个处理器有4个内核,处理器上的内存带宽很好,基准testing可能表明我运行了一个GHC运行时(使用并行GC),另外每个处理器运行一个Erlang进程。

在这两种情况下,如果Erlang和GHC可以共享一个堆,那么共享可能会绑定到某个单核上运行的单个操作系统线程。 (我正在这里深究,这就是为什么我问这个问题。)

我还有另一个议程 – 独立于GC的基准function语言。 我经常读到OCaml v GHC v Erlang v的基准testing结果,并想知道不同的GC有多less结果。 如果GC的select与function语言的select是正交的呢? GC究竟有多昂贵? 看到这个魔鬼主张博客文章

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

由我的Lisp朋友约翰·弗里姆林(John Fremlin),他迷人地给了他的职位题目“自动垃圾收集是垃圾”。 当约翰宣称GC很慢,并没有真正加快这一点时,我希望能够反击一些数字。

很多Haskell和Erlang人都对Erlang监督分配的模型感兴趣,而Haskell并行地运行共享内存节点来完成所有的数字运算/逻辑。

一开始是haskell-erlang库: http : //hackage.haskell.org/package/erlang

我们在ruby土地上也有类似的努力,通过胡里斯: http : //github.com/mwotton/Hubris/tree/master

现在的问题是要find真正推动Erlang / Haskell互操作的人来找出棘手的问题。

虽然这是一个非常古老的线程,但是如果读者仍然感兴趣,那么值得一看Cloud Haskell ,它将Erlang风格的并发和分布带到GHC稳定。

即将推出的分布式过程平台库增加了对OTPtypes构造的支持,比如gen_servers,监督树和Erlang / OTP借鉴和启发的各种其他“haskell味”抽象。

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

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

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

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

和软件中的所有东西一样,抽象也是有代价的。 在这种情况下,我相当怀疑你将不得不引入这么多的图层来获得这两种语言的阻抗不匹配,你会得到一个不是很高性能(或有用)的普通虚拟机。

底线 – 拥抱差异! 不要在同一个过程中运行所有的东西,特别是从可靠性的angular度来看,有很多好处。 另外,我认为期望一种语言/虚拟机能够在你的余生中继续生活(除非你打算做一个计划),或者过一会儿,或者变成某种代码修士,这个代码修士只能在单个项目)。 软件开发都是关于智能敏捷性,并愿意使用最好的工具来构build快速,可靠的代码。

正如dizzyd在他的评论中提到的,并不是消息中的所有数据都被复制,大的二进制文件存在于进程堆外,并且不会被复制。

使用不同的内存结构来避免单独的每进程堆是肯定可能的,并且已经在许多早期的实现中完成。 虽然有一个堆使消息传递非常快,但它引入了一些其他问题,主要是因为GC必须是交互式的和全局的非中断性的,所以不能使用与每个堆一样简单的algorithm,过程堆模型。

只要我们使用具有不可变的数据结构,就不存在鲁棒性和安全性问题。 决定使用哪种内存和GC模型是一个很大的折衷,不幸的是,普遍存在最好的模型。

虽然Haskell和Erlang都是函数式语言,但它们在很多方面都是非常不同的语言,并且具有非常不同的实现。 很难想出一个能够有效处理这两种语言的“Erskell”(或Haslang)机器。 我个人认为把它们分开并确保你们之间有一个非常好的界面会好得多。

CLR支持使用明确的tail操作码(F#所使用的tail操作码)进行尾部呼叫优化,而JVM不具有相同的function,这限制了这种语言风格的实现。 使用单独的AppDomain s允许CLR热交换代码(参见例如这篇博客文章展示了如何完成)。

西蒙·佩顿·琼斯(Simon Peyton Jones)从唐·西姆(Don Syme)和微软研究院(Microsoft Research)的F#团队的走廊上下class,如果我们最终没有看到具有某种官方地位的铁哈斯克尔(IronHaskell),那将是一个非常失望的事情。 IronErlang将是一个有趣的项目 – 最大的工作可能是移植绿色线程调度程序,而不像Windows工作stream引擎那样重量级,或者不得不在CLR上运行BEAM VM。