Contents

1 Overview

The Haskell/Erlang-FFI enables full bi-directional communication between programs written in Haskell and Erlang. Message sends from Haskell to Erlang just look like function calls (of course), and messages from Erlang to Haskell are delivered to MVars.

2 Theory of Operation

Because everything interesting that happens in Erlang happens as a result of sending a message, all that is required to fully interoperate with Erlang is to be able to send and receive messages using its native wire protocol. There are similar packages that allow Erlang to interoperate with programs written in C, Java, Clojure, Scheme, Emacs Lisp, Python, and Ruby. This Haskell library is distantly derived from the Emacs Lisp package Distel.

Erlang types are represented in Haskell with the

ErlType

data type. See the Haddock docs for details. To use this package you will sometimes have to get down to the level of

ErlType

, but most of the time you can work with native Haskell types that are instances of the

is slightly more complicated. In Erlang you can address messages either to "process ids" (pids) that are opaque and not knowable a-priori, or to registered process names. On the Haskell side, we represent this with

Either

, so

Left pid

or

Right name

(

mboxSelf

returns the Pid for the given

MBox

):

mboxSend mbox "erlang"(Right "echo")(mboxSelf mbox,"Hello, Erlang!")

Receive messages addressed to your "process" with:

msg <- mboxRecv mbox

You will generally initiate communication to a registered name, at which time you may receive a Pid for later use.

5 High-Level Communication

In a real Erlang program, low-level message sends are not used for the bulk of the work. Most of the interesting things in Erlang are part of the OTP (Open Telecom Platform) libraries, and these implement higher-level protocols on top of message sends.

The most important of these protocols is gen_server. When talking to a process that implements the gen_server protocol, you can either "call" or "cast" to it (in addition to still being able to do low-level message sends). A call is a two-way faux-synchronous request/response:

reply <- genCall mbox node pid msg

A cast is a one-way notification:

genCast mbox node pid msg

One instance of gen_server in particular is very useful: the RPC server "rex". Send rex a message containing a module name, function name, and a list of arguments, and it will (synchronously or asynchronously) call the named function in the named module, passing it the arguments supplied, and optionally returning the results to you. The RPC server gives you access to nearly all of Erlang:

reply <- rpcCall mbox node module function arguments

or

rpcCast mbox node module function arguments

The library also provides a set of wrappers for making calls to Mnesia.

6 Not Implemented

The Erlang FFI is a work in progress, and it has some shortcomings. As of this writing, it does not yet register itself with epmd. This means that, even though Erlang can call into Haskell, Haskell must initiate first contact with the Erlang node. (Otherwise Erlang simply doesn't know where the Haskell node is on the network).

A larger issue is that the FFI does not yet implement process linking. Two processes are "linked" in Erlang if one is notified when the other terminates, and linking is the primary mechanism for handling and/or propagating errors in an Erlang system. This is in-progress and should be completed soon. Until it is done, this library is best suited for situations where Haskell is consuming Erlang services. Erlang can't yet reliably consume Haskell services because there is no error notification.