簡體   English   中英

混合Erlang和Haskell

[英]Mixing Erlang and Haskell

如果你已經購買了函數式編程范例,那么你很可能同時喜歡Erlang和Haskell。 兩者都具有純粹的功能核心和其他優點,如輕量級線程,使其非常適合多核世界。 但也存在一些差異。

Erlang是一種經過商業驗證的容錯語言,具有成熟的分發模型。 它具有看似獨特的功能,能夠通過熱代碼加載在運行時升級其版本。 (太酷了!)

另一方面,Haskell擁有任何主流語言中最復雜的類型系統。 (我將'主流'定義為任何已發布的O'Reilly書籍的語言,因此Haskell很重要。)它的直線單線程性能看起來優於Erlang,其輕量級線程看起來更輕。

and was wondering whether it was possible to mix Erlang and Haskell to achieve a best of breed platform. 我正在嘗試為組建一個開發平台,並且想知道是否可以將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朋友約翰弗雷姆林,他迷人地,給他的帖子標題“自動垃圾收集是垃圾”。 當John聲稱GC很慢並且沒有真正加速那么多時,我希望能夠用一些數字來對抗。

許多Haskell和Erlang人對Erlang監督分發的模型感興趣,而Haskell並行運行共享內存節點執行所有數字運算/邏輯。

這方面的開始是haskell-erlang庫: http//hackage.haskell.org/package/erlang

我們在Ruby的土地上也有類似的努力,通過Hubris: http//github.com/mwotton/Hubris/tree/master

現在的問題是找到一個人實際通過Erlang / Haskell互操作來找出棘手的問題。

你將有一個有趣的時間在Haskell和Erlang之間混合GC。 Erlang使用每進程堆並在進程之間復制數據 - 因為Haskell甚至沒有進程的概念,我不確定如何在兩者之間映射這個“通用”GC。 此外,為了獲得最佳性能,Erlang使用各種分配器,每個分配器都有輕微的調整行為,我肯定會影響GC子系統。

與軟件中的所有內容一樣,抽象是有代價的。 在這種情況下,我寧願懷疑你必須引入這么多層才能讓兩種語言超過它們的阻抗不匹配,以至於你會遇到性能不高(或有用)的常見虛擬機。

底線 - 擁抱差異! 不在同一過程中運行所有內容具有巨大的優勢,特別是從可靠性的角度來看。 此外,我認為期待一個語言/ VM在你的余生中持續使用(除非你計划在。),生活很短的時間或b。)成為​​某種代碼僧侶只能在單個項目)。 軟件開發完全是關於心理敏捷性,並願意使用最好的工具來構建快速,可靠的代碼。

雖然這是一個非常古老的線程,但如果讀者仍然感興趣,那么值得一看的是Cloud Haskell ,它將Erlang風格的並發性和分布帶入了GHC穩定版。

即將推出的分布式流程平台庫增加了對OTP-esque構造的支持,例如gen_servers,監督樹以及從Erlang / OTP借鑒和啟發的各種其他“haskell風格”抽象。

  1. 您可以使用OTP gen_supervisor進程來監視使用open_port()生成的Haskell實例。 根據“端口”的退出方式,您可以重新啟動它,或者確定它是故意停止的,並讓相應的Erlang進程也死掉。

  2. Fugheddaboudit。 即使是這些與語言無關的虛擬機,有時也會遇到語言之間傳遞的數據問題。 你應該以某種方式在兩者之間序列化數據:數據庫,XML-RPC,類似的東西。

順便說一句,在你的余生中使用單一平台的想法也可能是不切實際的。 計算技術和時尚變化太頻繁,以至於你可以永遠只使用一種語言。 你的問題指出了這一點:即使在今天,也沒有一種語言可以滿足我們所希望的一切。

正如dizzyd在他的評論中提到的那樣,並不是所有的消息數據都被復制,大型二進制文件存在於進程堆之外並且不會被復制。

使用不同的存儲器結構以避免具有單獨的每個進程堆當然是可能的並且已經在許多早期實現中完成。 雖然擁有單個堆會使消息傳遞速度非常快,但它會引入許多其他問題,主要是因為它必須是交互式且全局不中斷的,因此GC變得更加困難,因此您無法使用相同的簡單算法。進程堆模型。

只要我們使用具有不可變數據結構,就沒有魯棒性和安全性的問題。 決定使用哪種內存和GC模型是一個很大的權衡,不幸的是,這是一個普遍最好的模型。

雖然Haskell和Erlang都是函數式語言,但它們在許多方面都是非常不同的語言,並且具有非常不同的實現。 很難想出能夠有效處理這兩種語言的“Erskell”(或Haslang)機器。 我個人認為將它們分開並確保它們之間有一個非常好的接口要好得多。

CLR支持使用顯式tail操作碼(由F#使用)進行尾調用優化,JVM沒有(尚未)具有等效,這限制了這種語言風格的實現。 使用單獨的AppDomain確實允許CLR熱插拔代碼(參見此博客文章,展示如何完成)。

Simon Peyton Jones在Don Syme和微軟研究院的F#團隊的走廊下工作,如果我們最終沒有看到具有某種官方身份的IronHaskell,那將是一個非常令人失望的事情。 IronErlang將是一個有趣的項目 - 最大的工作可能是移植綠色線程調度程序,而不是像Windows Workflow引擎那樣重量級,或者必須在CLR上運行BEAM VM。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM