Tuesday, July 23, 2013

Using 3rd-party Erlang modules in Elixir

Calling into other people's Erlang from Elixir is pretty straightforward, but there are a couple things to be aware of. Let's start with some sample Erlang code that uses the epgsql module.


-define(EPG_PATH, "/Users/alh/src/epgsql/ebin").

main() ->
    {ok, PGConn} = pgsql:connect("localhost", "dba", [{database, "users"}]),
    {ok, Columns, Rows} = pgsql:squery(PGConn, "SELECT * FROM auth_user").

setup_paths() ->
Here's the same code written in Elixir:

defmodule PgDemo do
  @epg_path "/Users/alh/src/epgsql/ebin"

  def main do
    {:ok, pg_conn} = :pgsql.connect('localhost', 'dba', [{:database, 'users'}])
    {:ok, columns, rows} = :pgsql.squery(pg_conn, 'SELECT * FROM auth_user')

  defp setup_paths do
So what's different?
  • Because the module naming conventions are different between Elixir and Erlang, Elixir imports Erlang module names as atoms, e.g. :pgsql
  • Again because of naming conventions, Erlang atoms like database become :database and a local variable like PgConn in the Erlang version becomes pg_conn in Elixir.
  • Most (all?) Erlang functions that take a string as an argument are going to expect that string to be a char list, a list of 8-bit values ... but a typical double-quoted string in Elixir is UTF-8! We need to single-quote string literals when they are arguments to an Erlang function. If you have a UTF-8 string stored in an Elixir variable, you can convert it to a char list with the binary_to_list/1 function. For more about Elixir strings see the Getting Started Guide section 2.3.

Also, there doesn't seem to be an exact equivalent in Elixir to Erlang's -define() for defining a constant. You can use module attributes (Section 3.6) for defining string constants and they will be inlined at compile-time.

No comments: