Подтвердить что ты не робот

Смешивание Erlang и Haskell

Если вы купили парадигму функционального программирования, есть вероятность, что вам нравятся как Эрланг, так и Хаскелл. Оба имеют чисто функциональные ядра и другую доброту, такие как легкие потоки, которые делают их пригодными для многоядерного мира. Но есть и отличия.

Erlang - коммерчески доказанный отказоустойчивый язык со зрелой моделью распространения. Он обладает уникальной особенностью в своей способности обновлять свою версию во время выполнения с помощью загрузки горячего кода. (Спокойно!)

Haskell, с другой стороны, имеет самую сложную систему типов любого основного языка. (Где я определяю "мейнстрим" как любой язык, на котором есть опубликованная книга O'Reilly, поэтому Haskell рассчитывает.) Его прямолинейная однопоточная производительность выглядит выше Erlang, а ее легкие потоки выглядят еще легче.

Я пытаюсь собрать платформу разработки для остальной части моей жизни кодирования и задавался вопросом, можно ли смешивать Erlang и Haskell для достижения лучшей в своем классе платформы. Этот вопрос состоит из двух частей:

  • Я хотел бы использовать Erlang как своего рода отказоустойчивый MPI для склеивания экземпляров среды GHC. Был бы один процесс Erlang на время выполнения GHC. Если "произошло невозможное" и время выполнения GHC умерло, процесс Erlang определит это как-то и умрет. Функции загрузки и распределения горячего кода Erlang будут продолжать работать. Среда выполнения GHC может быть настроена для использования только одного ядра или всех ядер на локальной машине или любой комбинации между ними. После того, как была написана библиотека Erlang, остальная часть кода уровня Erlang должна быть чисто шаблоном и автоматически генерироваться для каждого приложения. (Возможно, например, с помощью Haskell DSL.) Как достичь хотя бы некоторых из этих вещей?
  • Я хотел бы, чтобы Эрланг и Хаскелл могли делиться одним и тем же сборщиком гаражей. (Это гораздо более глубокая идея, чем 1.) Языки, которые работают на JVM и CLR, достигают большей массы, делясь временем выполнения. Я понимаю, что существуют технические ограничения на запуск Erlang (загрузка горячего кода) и Haskell (более высокий тип полиморфизма) на JVM или CLR. Но как насчет развязки только сборщика мусора? (Сортировка начала выполнения для функциональных языков.) Распределение, очевидно, должно было бы быть действительно быстрым, поэтому, возможно, этот бит должен быть статически связан. И должно быть какое-то mechansim, чтобы отличить изменчивую кучу от неизменяемой кучи ( включая ленивую запись однажды памяти), поскольку GHC это нуждается. Было бы целесообразно модифицировать как HIPE, так и GHC, чтобы сборщики мусора могли делиться кучей?

Пожалуйста, ответьте на любые впечатления (положительные или отрицательные), идеи или предложения. На самом деле, любая обратная связь (без прямого обращения!) Приветствуется.

Обновление

Спасибо за все 4 ответа на сегодняшний день - каждый научил меня хотя бы одной полезной вещи, о которой я не знал.

Относительно остальной кодирующей вещи жизни я включил ее немного в щеку, чтобы вызвать споры, но на самом деле это правда. Существует проект, который я имею в виду, что я намерен работать до тех пор, пока не умру, и ему нужна стабильная платформа.

В платформе, которую я предложил выше, я бы только написал Haskell, так как автоматически будет создан шаблон Erlang. Итак, как долго будет длиться Haskell? Хорошо Lisp по-прежнему с нами и не похоже, что он уходит в ближайшее время. Haskell является открытым исходным кодом BSD3 и достиг критической массы. Если само программирование будет продолжаться через 50 лет, я бы ожидал, что Haskell или некоторая непрерывная эволюция Haskell все еще будут здесь.

Обновить 2 в ответ на сообщение rvirding

Согласовано - реализация полной универсальной виртуальной машины Erskell/Haslang не может быть абсолютно невозможной, но, безусловно, это будет очень сложно. Разделение только уровня сборщика мусора, как нечто вроде виртуальной машины, хотя все еще сложно, звучит на порядок меньше, чем мне труднее. В модели сбора мусора функциональные языки должны иметь много общего - неповторимость неизменяемых данных (включая thunks) и требование для очень быстрого распределения. Так что тот факт, что общность тесно связан с монолитными виртуальными машинами, кажется странным.

VM помогают достичь критической массы. Просто посмотрите, как "lite" функциональные языки, такие как F # и Scala, сняли. Scala может не иметь абсолютной отказоустойчивости Erlang, но он предлагает маршрут эвакуации для очень многих людей, привязанных к JVM.

При наличии одной кучи сообщение проходит очень быстро вводит ряд других проблем, в основном, что GC делает больше сложно, поскольку это должно быть интерактивным и глобально без прерывания, чтобы вы не могут использовать одни и те же простые алгоритмы как модель кучи процесса.

Абсолютно, это имеет для меня прекрасный смысл. Очень умные люди в команде разработчиков GHC, похоже, пытаются решить часть проблемы с помощью параллельного GC "stop the world".

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

(Очевидно, что "остановить мир" не будет летать для генерала Эрланга с учетом его основного варианта использования.) Но даже в тех случаях, когда "остановить мир" в порядке, их ускорения не кажутся универсальными. Поэтому я согласен с вами, маловероятно, что существует универсально лучший GC, поэтому я указал в первой части моего вопроса, что

Время выполнения GHC может быть настроено на используйте только одно ядро ​​или все ядра на локальная машина или любая комбинация в между ними.

Таким образом, для данного варианта использования я мог бы, после бенчмаркинга, выбрать путь Erlang и запустить одно время выполнения GHC (с однопоточным GC) плюс один процесс Erlang на ядро ​​и позволить Erlang копировать память между ядрами для хорошей локальности.

В качестве альтернативы, на двухпроцессорной машине с 4 ядрами на процессор с хорошей пропускной способностью памяти на процессоре, бенчмаркинг может предполагать, что я запускаю одну среду исполнения GHC (с параллельным GC) и один процесс Erlang на процессор.

В обоих случаях, если Erlang и GHC могут делиться кучей, совместное использование, вероятно, будет связано с одним потоком ОС, работающим на одном ядре. (Я выхожу из своей глубины здесь, поэтому я задал вопрос.)

У меня также есть другая повестка дня - сравнительные функциональные языки, независимо от GC. Часто я читаю результаты тестов OCaml v GHC v Erlang v... и задаюсь вопросом, насколько результаты смешаны с различными GC. Что делать, если выбор GC может быть ортогональным выбору функционального языка? Насколько дорогим является GC? Смотрите это сообщение блога адвокатов дьявола

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

мой друг Lisp Джон Фремлин, которого он, очаровательно, дал свой пост: "Автоматизированная сборка мусора - это мусор". Когда Джон утверждает, что GC медленный и на самом деле не так сильно ускорился, я хотел бы иметь возможность противостоять некоторым номерам.

4b9b3361

Ответ 1

Многие люди Haskell и Erlang заинтересованы в модели, в которой Erlang контролирует распространение, а Haskell параллельно использует узлы разделяемой памяти, делая все число хруст/логику.

Начнем с того, что это библиотека haskell-erlang: http://hackage.haskell.org/package/erlang

И у нас есть аналогичные усилия на земле Руби, через Hubris: http://github.com/mwotton/Hubris/tree/master

Теперь вопрос заключается в том, чтобы найти кого-то, кто действительно проталкивает интервал Erlang/Haskell, чтобы выяснить сложные проблемы.

Ответ 2

Хотя это довольно старый поток, если читатели по-прежнему заинтересованы, стоит взглянуть на Cloud Haskell, который привносит стиль Erlang concurrency и распределения в стабильную GHC.

В предстоящей библиотеке distributed-process-platform добавлена ​​поддержка конструкций OTP-esque, таких как gen_servers, деревья наблюдения и различные другие абстракции "haskell flavored", заимствованные из и вдохновлен Erlang/OTP.

Ответ 3

  • Вы можете использовать процесс OTP gen_supervisor для контроля экземпляров Haskell, которые вы создаете с помощью open_port(). В зависимости от того, как выйдет "порт", вы сможете перезапустить его или решить, что он остановлен специально, и пусть соответствующий процесс Erlang тоже умрет.

  • Fugheddaboudit. Даже эти независимые от языка виртуальные машины, о которых вы говорите, имеют проблемы с данными, передаваемыми между языками. Вы должны просто сериализовать данные между двумя способами: database, XML-RPC, что-то вроде этого.

Кстати, идея одной платформы на всю оставшуюся жизнь, вероятно, тоже непрактична. Вычислительные технологии и мода слишком часто меняются, чтобы ожидать, что вы сможете продолжать использовать только один язык навсегда. На ваш вопрос ставится вопрос: ни один язык не делает все, что мы могли бы пожелать, даже сегодня.

Ответ 4

У вас будет интересное время, связанное с GC между Haskell и Erlang. Эрланг использует кучу процессов и копирует данные между процессами - поскольку у Haskell даже нет концепции процессов, я не уверен, как вы могли бы сопоставить этот "универсальный" GC между ними. Кроме того, для достижения наилучшей производительности Эрланг использует множество распределителей, каждый из которых имеет слегка измененное поведение, которое, я уверен, повлияет на подсистему GC.

Как и во всех вещах в программном обеспечении, абстракция стоит дорого. В этом случае я скорее подозреваю, что вам придется вводить так много слоев, чтобы получить оба языка по их несоответствию импеданса, что вы закончите с не очень эффективной (или полезной) общей виртуальной машиной.

Нижняя линия - обнимите разницу! Существуют огромные преимущества для НЕ запускать все в одном и том же процессе, особенно с точки зрения надежности. Кроме того, я думаю, что немного наивно ожидать, что один язык/виртуальная машина оставит вас на всю оставшуюся жизнь (если вы не планируете.) Прожить короткое время или b.) Стать своего рода кодовым монахом, который ТОЛЬКО работает на единый проект). Разработка программного обеспечения связана с умственной гибкостью и желанием использовать лучшие доступные инструменты для создания быстрого и надежного кода.

Ответ 5

Как упоминается в своем комментарии dizzyd не все данные в сообщениях копируются, большие двоичные файлы существуют вне кучи процесса и не копируются.

Использование другой структуры памяти, чтобы избежать раздельной кучи для каждого процесса, безусловно, возможно и было сделано в ряде ранних реализаций. Хотя наличие одной кучи делает сообщение быстрее очень, оно вводит ряд других проблем, в основном это делает GC более сложным, так как он должен быть интерактивным и глобальным без прерывания, поэтому вы не можете использовать такие же простые алгоритмы, как и для модели кучи процессов.

Пока мы используем неизменяемые структуры данных, нет проблем с надежностью и безопасностью. Решение о том, какую память и модели GC использовать - это большой компромисс, и, к сожалению, это универсально лучшая модель.

В то время как Haskell и Erlang являются функциональными языками, они во многих отношениях очень разные языки и имеют очень разные реализации. Трудно было бы придумать машину Erskell (или Haslang), которая могла бы эффективно работать с обоими языками. Я лично считаю, что гораздо лучше держать их в отдельности и убедиться, что у вас действительно хороший интерфейс между ними.

Ответ 6

CLR поддерживает оптимизацию хвостового вызова с явным кодом операции tail (как используется F #), который JVM еще не имеет эквивалента, что ограничивает реализацию такого стиля языка. Использование отдельного AppDomain позволяет CLR для кода "горячей" замены (см., Например, это сообщение в блоге, показывающее, как это можно сделать).

С Саймоном Пейтоном Джонсом, работающим по коридору от Дона Сима и команды F # в Microsoft Research, было бы большим разочарованием, если бы мы не увидели IronHaskell с каким-то официальным статусом. IronErlang был бы интересным проектом - большая часть работы, вероятно, будет переносить планировщик с зелеными потоками, не получая такого тяжелого веса, как движок Windows Workflow, или должен запустить виртуальную машину BEAM поверх CLR.