https://wiki.haskell.org/index.php?title=Applications_and_libraries/Interfacing_other_languages/Erlang&feed=atom&action=historyApplications and libraries/Interfacing other languages/Erlang - Revision history2024-03-19T07:18:13ZRevision history for this page on the wikiMediaWiki 1.35.5https://wiki.haskell.org/index.php?title=Applications_and_libraries/Interfacing_other_languages/Erlang&diff=42950&oldid=prevBinq: removed invalid link2011-11-16T18:35:10Z<p>removed invalid link</p>
<table class="diff diff-contentalign-left diff-editfont-monospace" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 18:35, 16 November 2011</td>
</tr><tr>
<td colspan="2" class="diff-lineno">Line 1:</td>
<td colspan="2" class="diff-lineno">Line 1:</td>
</tr>
<tr>
<td class="diff-marker"> </td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>== Overview ==</div></td>
<td class="diff-marker"> </td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>== Overview ==</div></td>
</tr>
<tr>
<td class="diff-marker"> </td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td>
<td class="diff-marker"> </td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td>
</tr>
<tr>
<td class="diff-marker">−</td>
<td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>The [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/erlang Haskell/Erlang-FFI]<del class="diffchange diffchange-inline"> ([http://github.com/esessoms/haskell-interface see also])</del> 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.</div></td>
<td class="diff-marker">+</td>
<td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>The [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/erlang 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.</div></td>
</tr>
<tr>
<td class="diff-marker"> </td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td>
<td class="diff-marker"> </td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td>
</tr>
<tr>
<td class="diff-marker"> </td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>== Theory of Operation ==</div></td>
<td class="diff-marker"> </td>
<td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>== Theory of Operation ==</div></td>
</tr>
</table>Binqhttps://wiki.haskell.org/index.php?title=Applications_and_libraries/Interfacing_other_languages/Erlang&diff=25411&oldid=prevEricSessoms: simple tutorial on using the Erlang FFI2008-12-31T23:55:04Z<p>simple tutorial on using the Erlang FFI</p>
<p><b>New page</b></p><div>== Overview ==<br />
<br />
The [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/erlang Haskell/Erlang-FFI] ([http://github.com/esessoms/haskell-interface see also]) 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.<br />
<br />
== Theory of Operation ==<br />
<br />
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.<br />
<br />
Erlang types are represented in Haskell with the <hask>ErlType</hask> data type. See the Haddock docs for details. To use this package you will sometimes have to get down to the level of <hask>ErlType</hask>, but most of the time you can work with native Haskell types that are instances of the <hask>Erlang</hask> typeclass, and the conversion will be done for you. For example:<br />
<br />
<haskell><br />
ghci> toErlang [("a", 1), ("b", 2)]<br />
ErlList [ErlTuple [ErlString "a",ErlBigInt 1],ErlTuple [ErlString "b",ErlBigInt 2]]<br />
ghci> fromErlang $ ErlList [ErlTuple [ErlString "a",ErlBigInt 1],ErlTuple [ErlString "b",ErlBigInt 2]] :: [(String, Int)]<br />
[("a",1),("b",2)]<br />
</haskell><br />
<br />
== Getting Started ==<br />
<br />
Before you can do anything with the Erlang FFI, you minimally need to start up the Erlang Port Mapper Daemon (epmd). The simplest way to do that is to start an Erlang node on the local machine.<br />
<br />
Having started Erlang, we can now create a Haskell node. The <hask>Self</hask> data type represents a Haskell node. You need to instantiate one of these per Haskell process, passing it the network name of the node:<br />
<br />
<haskell><br />
self <- createSelf "haskell@localhost"<br />
</haskell><br />
<br />
The next step is to create an <hask>MBox</hask>. An <hask>MBox</hask> has a unique identifier and corresponds to Erlang's notion of a "process". You'll probably want one <hask>MBox</hask> per thread that needs to communicate with Erlang:<br />
<br />
<haskell><br />
mbox <- createMBox self<br />
</haskell><br />
<br />
You are now ready to talk to Erlang.<br />
<br />
== Low-Level Communication ==<br />
<br />
Erlang's fundamental abstraction is an asynchronous message send. In Haskell that's:<br />
<br />
<haskell><br />
mboxSend mbox node pid msg<br />
</haskell><br />
<br />
where <hask>mbox</hask> was created earlier, <hask>node</hask> is the name of the Erlang node (e.g., "erlang"), and <hask>msg</hask> is any data item that has an instance of <hask>Erlang</hask> so that it can be serialized.<br />
<br />
<hask>Pid</hask> 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 <hask>Either</hask>, so <hask>Left pid</hask> or <hask>Right name</hask> (<hask>mboxSelf</hask> returns the Pid for the given <hask>MBox</hask>):<br />
<br />
<haskell><br />
mboxSend mbox "erlang" (Right "echo") (mboxSelf mbox, "Hello, Erlang!")<br />
</haskell><br />
<br />
Receive messages addressed to your "process" with:<br />
<br />
<haskell><br />
msg <- mboxRecv mbox<br />
</haskell><br />
<br />
You will generally initiate communication to a registered name, at which time you may receive a Pid for later use.<br />
<br />
== High-Level Communication ==<br />
<br />
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.<br />
<br />
The most important of these protocols is <code>gen_server</code>. When talking to a process that implements the <code>gen_server</code> 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:<br />
<br />
<haskell><br />
reply <- genCall mbox node pid msg<br />
</haskell><br />
<br />
A cast is a one-way notification:<br />
<br />
<haskell><br />
genCast mbox node pid msg<br />
</haskell><br />
<br />
One instance of <code>gen_server</code> 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:<br />
<br />
<haskell><br />
reply <- rpcCall mbox node module function arguments<br />
</haskell><br />
<br />
or<br />
<br />
<haskell><br />
rpcCast mbox node module function arguments<br />
</haskell><br />
<br />
The library also provides a set of wrappers for making calls to Mnesia.<br />
<br />
== Not Implemented ==<br />
<br />
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).<br />
<br />
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.<br />
<br />
== Future Plans ==<br />
<br />
To complete the items listed in the previous section. :)</div>EricSessoms