Erlang/OTP

индекс
136,44

Ускоряем работу Erlang системы без замедления разработки

Недавно появилась возможность использовать С для написания модулей Erlang систем (это по-моему удобнее любого из предложенных здесь методов). Возможно вы не знали о возможности использовать Haskell в связке с Erlang. Haskell очевидно не панацея и действительно критические участки кода вероятно всё равно придётся переписывать на С, но Haskell предлагает строгую типизацию и сокращение обьёма кода по сравнению с С. Я думаю что проще переписывать код с Erlang на Haskell чем на С, потому что оба языка функциоанльные. Haskell быстрее Erlang благодаря статической типизации и умной системе выведения типов. Предлагаю вашему вниманию вольный перевод статьи о Haskell/Erlang-FFI.


Типы эрланг представлены в хаскеле типом ErlType.
Конвертация типов осуществляется для типов порождённых от стандартных с помощью функции toErlang.
ghci> toErlang [("a", 1), ("b", 2)]
ErlList [ErlTuple [ErlString "a",ErlBigInt 1],ErlTuple [ErlString "b",ErlBigInt 2]]
ghci> fromErlang $ ErlList [ErlTuple [ErlString "a",ErlBigInt 1],ErlTuple [ErlString "b",ErlBigInt 2]] :: [(String, Int)]
[("a",1),("b",2)]


Для создания узла (ноды) с хаскел кодом используется функция createSelf принимающая имя ноды.
self <- createSelf "haskell@localhost"

Для создания erlang-style процесса (SIP) используется функция createMBox принимающая в качестве параметра узел на котором следует запустить новый процесс.

mbox <- createMBox self

Для того что бы отослать сообщение используется функция mboxSend принимающая 4 параметра: хаслел процесс который посылает сообщение, «имя» эрланг ноды, pid и само сообщение. Сообщение любой тип эрланг. Структура Pid несколько сложнее: либо Left pid, где pid — это идентификатор эрланг процесса, либо Right name, где name — строка с именем процесса.

mboxSend mbox node pid msg

С получением сообщений всё проще:
msg <- mboxRecv mbox

Так же существует возможность более высокоуровневого взаимодействия:

reply <- genCall mbox node pid msg

genCast mbox node pid msg


Не сложно догадатся что genCall осуществляет синхронный вызов процесса с gen_server на эрланг ноде, а genCast — асинхронный.

Так же можно синхронно и асинхронно вызывать функции из эрланговских модулей

reply <- rpcCall mbox node module function arguments
rpcCast mbox node module function arguments


Не реализованы в данном релизе возможности связывания (linking) процессов, передачи ошибок, регистрации хаскел процессов в Erlang Port Mapper Daemon.

Скачать можно тут hackage.haskell.org/package/erlang.

PS простите что не оформил как перевод.
+17
4 декабря 2009, 00:29
8

комментарии (7)

0
wolf13h #
ссылка битая 404 Not Found
The requested resource was not found: malformed package identifier
0
OdobenusRosmarus #
там точка в конце url мешает
0
proxor #
Что значит недавно? Давным-давно можно писать внешние модули (т.н. порты) и даже целые ноды для Erlang на C и Java. Недавно появилось NIF, пока что в качестве экспериментальной возможности. Штука безусловно нужная и удобная, так как пишется не отдельный модуль, и не нода, а просто функция, которую виртуальная машина принимает так же, как функцию Erlang.

Опять же на каких задачах Haskell быстрее? На бенчмарке математика, а в документации прямо говорится: Erlang плохо умеет считать, хотя и поддерживает длинную арифметику. Regexp немного настораживает, но с этим можно жить, благо задача не так часто попадается и не столь существенно влияет на общую производительность.

Я думаю что проще переписывать код с Erlang на Haskell чем на С, потому что оба языка функциоанльные.

Это не совсем верно, цель написания внешних модулей на С — добиться максимальной производительности на кусках кода, которые Erlang делает плохо. Те же математические рассчёты. Использовать для этих целей Haskell равнозначно расхожей фразе «шило на мыло». Кроме того, Erlang, хоть и функциональный, но разительно отличается как от С, так и от Haskell. Переписывать же не обязательно, проще написать внешний модуль сразу. А теперь, благодаря NIF, это стало совсем просто и удобно.
0
notacodemonkey #
Именно NIF-ы я и имел ввиду, порты и ноды можно было писать — но в статье написано «Недавно появилась возможность использовать С для написания модулей Erlang систем». Хаскел быстрее, парадигма остаётся та же — значит перенос кода происходит быстрее.
По поводу их различий: www.infoq.com/interviews/armstrong-peyton-jones-erlang-haskell.
Хотя естественно критические элементы нужно переносить на С.
0
proxor #
Хаскел быстрее, парадигма остаётся та же — значит перенос кода происходит быстрее.

Можете привести пример? Я не согласен. Erlang слишком ориентирован на параллельность во всём. Для переноса подходят только последовательные участки кода, а тут уже не имеет вес использованная парадигма. Линейный код — он на любом языке практически идентичен.

И опять же я хочу заострить внимание не на переносе, а на изначальном написании критических кусков кода на С.
0
notacodemonkey #
Для хаскел есть несколько библиотек-расширений для erlang style concurrency.
«И опять же я хочу заострить внимание не на переносе, а на изначальном написании критических кусков кода на С.» — а как же идеология «сначала сделай правильно — и только потом, если нужно быстро»?
И вы сами себе противоречите — неужели в С больше средств для параллелизма чем в хаскел?
0
proxor #
Я же написал, что переносятся последовательные линейные участки кода, никакого противоречия, просто вы невнимательно читали :) Под Erlang прежде всего нужно понимать OTP — платформу, обеспечивающую всю ту вкусную параллельность и стабильность, а не язык. Переносить параллельность в Наskell или C глупо, теряется весь смысл. Посему Erlang-style это именно что style, что-то вроде китайской подделки под швейцарские часы.
По поводу идеологии… Ну вот у меня есть тяжелая математическая функция, думаете есть смысл писать её сначала на Erlang, если и так ясно, что она будет бутылочным горлышком? Преждевременная оптимизация это плохо, но здравый смысл нужно тоже иметь.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.