Mieszanie Erlanga i Haskella

Jeśli kupiłeś paradygmat programowania funkcyjnego, są szanse, że spodoba ci się zarówno Erlang, jak i Haskell. Oba mają czysto funkcjonalne rdzenie i inne zalety, takie jak lekkie nici, które sprawiają, że dobrze pasują do wielordzeniowego świata. Ale są też pewne różnice.

Erlang jest komercyjnie sprawdzonym językiem tolerancyjnym na błędy z dojrzałym modelem dystrybucji. Ma pozornie unikalną cechę w zdolności do uaktualniania swojej wersji w czasie wykonywania poprzez ładowanie gorącego kodu. (Way cool!)

Haskell, z drugiej strony, ma najbardziej wyrafinowany system typów ze wszystkich głównych języków. (Gdzie definiuję "mainstream" jako każdy język, który ma opublikowaną książkę O 'Reilly' ego, więc liczy się Haskell.) Jego prosta wydajność pojedynczego gwintu wygląda lepiej niż Erlang, a jego lekkie nici wyglądają jeszcze lżejsze.

Próbuję stworzyć platformę programistyczną dlado końca mojego życia programistycznego i zastanawiałem się, czy można mieszać Erlang i Haskell, aby osiągnąć najlepszy w Rasie platformy. To pytanie składa się z dwóch części:

  1. chciałbym użyć Erlanga jako pewnego rodzaju odpornego na błędy MPI do sklejania instancji GHC. Dla każdego środowiska GHC będzie istniał jeden proces Erlang. Gdyby" niemożliwe stało się " i środowisko GHC umarło, to proces Erlanga wykryłby to w jakiś sposób i też by umarł. Funkcje Erlanga wczytywania i dystrybucji gorącego kodu będą nadal działać. Środowisko wykonawcze GHC można skonfigurować tak, aby używało tylko jeden rdzeń lub wszystkie rdzenie na maszynie lokalnej lub dowolna kombinacja pomiędzy nimi. Po napisaniu biblioteki Erlang, reszta kodu poziomu Erlang powinna być czysto boilerplate i automatycznie generowana dla każdej aplikacji. (Być może przez Haskell DSL na przykład.) Jak osiągnąć przynajmniej niektóre z tych rzeczy?
  2. Chciałbym, żeby Erlang i Haskell mogli dzielić się tym samym garabage collector. (Jest to znacznie dalej idący pomysł niż 1.) Języki, które działają na JVM i CLR osiągnąć większą masę, dzieląc runtime. Rozumiem, że istnieją ograniczenia techniczne do uruchamiania Erlang (hot code loading) i Haskell (higher kinded polymorphism) na JVM lub CLR. Ale co z rozdzieleniem tylko śmieciarza? (Rodzaj początku runtime dla języków funkcyjnych.) Alokacja musiałaby oczywiście być bardzo szybka, więc może ten bit musi być statycznie połączony. I powinien być jakiś mechanizm odróżniający mutable sterta z niezmiennej sterty (incuding leniwy zapis raz pamięci) jak GHC tego potrzebuje. Czy byłoby możliwe zmodyfikowanie zarówno HIPE, jak i GHC, aby śmieciarze mogli dzielić stertę?

Proszę odpowiadać wszelkimi doświadczeniami (pozytywnymi lub negatywnymi), pomysłami lub sugestiami. W rzeczywistości, wszelkie opinie (bez prostego nadużycia!) jest mile widziany.

Update

Dzięki za wszystkie 4 odpowiedzi do tej pory-każda nauczyła mnie przynajmniej jednej przydatnej rzeczy, której nie wiedzieć.

Odnośnie reszty życia - dodałem to nieco do dyskusji, ale to prawda. Mam na myśli projekt, nad którym mam zamiar pracować aż do śmierci i który potrzebuje stabilnej platformy.

Na platformie, którą zaproponowałem powyżej, napiszę tylko Haskell, ponieważ kocioł Erlang byłby generowany automatycznie. Jak długo wytrzyma Haskell? Cóż, Lisp jest nadal z nami i nie wygląda na to, że odejdzie w najbliższym czasie. Haskell jest bsd3 open source i osiągnął masę krytyczną. Jeśli samo programowanie jest nadal około 50 lat czasu, spodziewałbym się Haskell, lub jakaś ciągła ewolucja Haskell, nadal będzie tutaj.

Aktualizacja 2 w odpowiedzi na post rvirdinga

Zgoda-wdrożenie kompletnej uniwersalnej maszyny wirtualnej "Erskell/Haslang" może nie być absolutnie niemożliwe, ale z pewnością byłoby bardzo trudne. Dzielenie się tylko śmieciami poziom kolekcjonera jako coś w rodzaju maszyny wirtualnej, choć wciąż trudny , wydaje mi się o rząd wielkości mniej trudny. W modelu garbage collection języki funkcyjne muszą mieć wiele wspólnego - niekwalifikowalność niezmiennych danych (w tym thunksów) i wymóg bardzo szybkiej alokacji. Więc fakt, że wspólność jest ściśle powiązana z monolitycznymi maszynami wirtualnymi, wydaje się trochę dziwny.

Maszyny wirtualne pomagają osiągnąć masę krytyczną. Wystarczy spojrzeć na to, jak "lite" języki funkcyjne lubią F # i Scala wystartowały. Scala może nie ma absolutnej tolerancji błędu Erlanga, ale oferuje drogę ucieczki dla bardzo wielu ludzi, którzy są związani z JVM.

Mając jedną stertę sprawia, że wiadomość przekazywana bardzo szybko wprowadza szereg innych problemów, głównie, że robienie GC staje się bardziej trudne, ponieważ musi być interaktywne i globalnie nie przerywający, więc ty nie można używać tych samych prostszych algorytmów jako sterta per-process model.

Absolutnie, to ma dla mnie sens. Bardzo inteligentni ludzie w zespole rozwoju GHC wydają się próbować rozwiązać część problemu za pomocą równoległego GC "stop the world".

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

(oczywiście "stop the world" nie poleciłby generałowi Erlangowi, biorąc pod uwagę jego główny przypadek użycia.) Ale nawet w przypadkach, w których "stop the world" jest OK, ich speedupy robią nie wydaje się być uniwersalny. Więc zgadzam się z tobą, jest mało prawdopodobne, że istnieje uniwersalnie najlepszy GC, co jest powodem wyszczególniłem w części 1. z mojego pytania, że

Środowisko uruchomieniowe GHC może być skonfigurowane do używać tylko jednego rdzenia lub wszystkich rdzeni na maszyna lokalna, lub dowolna kombinacja w pomiędzy.

W ten sposób, dla danego przypadku użycia, mogłem, po benchmarkingu, wybrać sposób Erlang i uruchomić jeden GHC runtime (z singlethreaded GC) plus jeden Erlang proces na rdzeń i niech Erlang skopiuje pamięć między rdzeniami dla dobrej lokalizacji.

Alternatywnie, na maszynie z dwoma procesorami z 4 rdzeniami na procesor z dobrą przepustowością pamięci na procesor, analiza porównawcza może sugerować, że uruchamiam jeden GHC runtime (z równoległym GC) plus jeden proces Erlanga na procesor.

W obu przypadkach, gdyby Erlang i GHC mogli współdzielić stertę, współdzielenie prawdopodobnie byłoby powiązane z pojedynczym wątkiem OS działającym na jednym rdzeniu. (I ' m getting out of my głębia tutaj, dlatego zadałem pytanie.)

Mam też inny program-benchmarking języków funkcyjnych niezależnie od GC. Często czytam wyniki benchmarków OCaml v GHC v Erlang v ... i zastanawiam się, jak bardzo wyniki są mylone przez różne GCs. Co jeśli wybór GC może być ortogonalny do wyboru języka funkcjonalnego? Ile kosztuje GC? Zobacz ten wpis na blogu devil advocates

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

By My Lisp friend John Fremlin, which has, charming, he has given his post title "Automated garbage collection is śmieci". Kiedy John twierdzi, że GC jest powolny i nie przyspieszył tak bardzo, chciałbym być w stanie przeciwstawić się niektórym liczbom.

Author: Paul Delhanty, 2009-09-09

6 answers

Wiele osób Haskell i Erlang jest zainteresowanych modelem, w którym Erlang nadzoruje dystrybucję, podczas gdy Haskell uruchamia węzły pamięci współdzielonej równolegle wykonując wszystkie łamanie/logikę liczb.

PoczÄ…tkiem tego jest biblioteka haskell-erlang: http://hackage.haskell.org/package/erlang

I mamy podobne wysiłki w Ruby land, poprzez pychę: http://github.com/mwotton/Hubris/tree/master

Teraz jest pytanie, aby znaleźć kogoś, kto faktycznie przepchnij się przez interop Erlang / Haskell, aby dowiedzieć się trudnych problemów.

 30
Author: Don Stewart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-09 10:45:45

Będziesz miał ciekawy czas mieszając GC między Haskell i Erlang. Erlang używa sterty procesów i kopiuje dane między procesami - jako że Haskell nawet nie ma pojęcia o procesach, nie jestem pewien, jak odwzorowałbyś ten "uniwersalny" GC między nimi. Ponadto, aby uzyskać najlepszą wydajność, Erlang używa różnych alokatorów, każdy z lekko podrasowanymi zachowaniami, które na pewno wpłyną na podsystem GC.

Jak w przypadku wszystkich rzeczy w oprogramowaniu, abstrakcja przychodzi na koszt. W tym przypadku raczej podejrzewam, że będziesz musiał wprowadzić tak wiele warstw, aby oba języki miały niedopasowanie impedancji, że skończysz z niezbyt wydajną (lub użyteczną) wspólną maszyną wirtualną.

Reasumując -- przyjmij różnicę! Istnieją ogromne zalety, aby nie uruchamiać wszystkiego w tym samym procesie, szczególnie z punktu widzenia niezawodności. Ponadto, myślę, że to trochę naiwne oczekiwać, że jeden język / VM będzie trwać do końca życia (chyba, że planujesz.) krótki czas lub b.) staje się jakimś mnichem kodu, który działa tylko na jednym projekcie). Tworzenie oprogramowania polega na sprawności umysłowej i chęci korzystania z najlepszych dostępnych narzędzi do budowania szybkiego, niezawodnego kodu.

 5
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-09 12:39:53

Chociaż jest to dość stary wątek, jeśli czytelnicy są nadal zainteresowani, warto przyjrzeć się Cloud Haskell , która wprowadza współbieżność i dystrybucję w stylu Erlanga do stajni GHC.

Nadchodząca biblioteka distributed-process-platform dodaje wsparcie dla konstrukcji typu OTP, takich jak gen_servery, drzewa nadzoru i różne inne abstrakcje o Smaku Haskella zapożyczone i inspirowane przez Erlang/OTP.

 5
Author: hyperthunk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-02 11:18:29
  1. Możesz użyć procesu gen_supervisor OTP do monitorowania wystąpień Haskella, które pojawiają się za pomocą open_port (). W zależności od tego, w jaki sposób "port" wyszedł, będziesz mógł go ponownie uruchomić lub zdecydować, że celowo się zatrzymał i pozwolić, aby odpowiedni proces Erlanga również umarł.

  2. Fugheddaboudit. Nawet te niezależne od języka maszyny wirtualne, o których mówisz, czasami mają problemy z danymi przekazywanymi między językami. Powinieneś tylko serializować dane między tymi dwoma w jakiś sposób: baza danych, XML-RPC, coś w tym stylu.

Przy okazji, pomysł na jedną platformę do końca życia jest prawdopodobnie niepraktyczny. Technologia obliczeniowa i moda zmieniają się zbyt często, aby oczekiwać, że możesz używać tylko jednego języka na zawsze. Twoje pytanie wskazuje na to: żaden język nie robi wszystkiego, czego byśmy chcieli, nawet dzisiaj.
 4
Author: Warren Young,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-09 05:20:13

Jak wspomniał dizzyd w komentarzu nie wszystkie dane w wiadomościach są kopiowane, Duże binaria istnieją poza stosami procesów i nie są kopiowane.

Użycie innej struktury pamięci, aby uniknąć oddzielnego stosu dla poszczególnych procesów, jest z pewnością możliwe i zostało wykonane w wielu wcześniejszych implementacjach. Chociaż posiadanie jednej sterty sprawia, że przekazywanie wiadomości jest bardzo szybkie, wprowadza szereg innych problemów, głównie to, że wykonywanie GC staje się trudniejsze, ponieważ musi być interaktywny i globalnie nie przerywający, więc nie można używać tych samych prostszych algorytmów, co model sterty per-process.

Dopóki używamy niezmiennych struktur danych, nie ma problemu z solidnością i bezpieczeństwem. Decydowanie o tym, które modele pamięci i GC zastosować, to duży kompromis, a niestety jest najlepszy model.

Podczas gdy Haskell i Erlang są językami funkcyjnymi, są pod wieloma względami bardzo różnymi językami i mają bardzo różne implementacje. Trudno byłoby wymyślić maszynę" Erskell" (lub Haslang), która mogłaby efektywnie obsługiwać oba języki. Osobiście uważam, że o wiele lepiej jest trzymać je osobno i upewnić się, że masz naprawdę dobry interfejs między nimi.

 4
Author: rvirding,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-09 15:34:55

CLR obsługuje optymalizację wywołań ogonowych za pomocą jawnego kodu opcode tail (używanego przez F#), którego JVM nie ma (jeszcze) odpowiednika, co ogranicza implementację takiego stylu języka. Użycie oddzielnych AppDomains pozwala CLR na wymianę kodu (patrz np. ten post na blogu pokazujący, jak można to zrobić).

Z Simonem Peytonem Jonesem pracującym tuż obok Dona Syme ' a i zespołu F # w Microsoft Research, byłoby wielkim rozczarowaniem, gdybyśmy nie w końcu zobaczyć IronHaskell z jakimś oficjalnym statusem. IronErlang byłby ciekawym projektem . największym dziełem prawdopodobnie byłoby przeportowanie Green-threading scheduler bez uzyskania tak ciężkiego jak silnik Workflow Windows, lub konieczność uruchomienia Beam VM na CLR.
 2
Author: Steve Gilham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-09 07:11:07