Woo, quite a long title, but I think that effectively explains what this is going to be about. There are already lots of good posts on Elixir from proper Erlang programmers. This isn't meant to be another one of them. It's just a collection of things I've noticed.

It is pretty much the same

Superficially there is no real difference (or benefit to be gained) between Erlang and Elixir code. Here's some Erlang code:

pad_to(Length, Binary_string) when length(Binary_string) < Length ->
    Padded_binary_string = "0"++Binary_string,
    pad_to(Length, Padded_binary_string);
pad_to(Length, Binary_string) when length(Binary_string) == Length ->

And the equivalent in Elixir:

def pad_to(length, binary_string) when length(binary_string) < length do
  padded_binary_string = '0'++binary_string
  pad_to(length, padded_binary_string)
def pad_to(length, binary_string) when length(binary_string) == length do

Apart from the wrapping of the code in def and end it looks pretty much the same.

You have to still use Erlang

Quite a bit. I was surprised how quick I came across the need to do this, but not all Erlang things have Elixir equivalents so you have to use Erlang code; However, at least this is seamless and painless.

Original Erlang:

Binary_string = hd(io_lib:format("~.2B", [Binary_number])),

Elixir port:

binary_string = hd(:io_lib.format("~.2B", [binary_number]))

defp is really neat

In Erlang you export only the functions you want:


six_bit_chunks(Encoded_polyline) ->
    six_bit_chunks_(Encoded_polyline, []).
six_bit_chunks_([Head | Rest], Chunks_list) ->
    Six_bit_chunk = six_bit_chunk(Head),
    %Add to Reversed_chunks
    six_bit_chunks_(Rest, [Six_bit_chunk]++Chunks_list);
six_bit_chunks_([], Chunks_list) ->

In Elixir everything that uses def is exported automatically. If you don't want something exported you use defp. This is really neat.

def six_bit_chunks(encoded_polyline) do
  six_bit_chunks_(encoded_polyline, [])
defp six_bit_chunks_([head | rest], chunks_list) do
  six_bit_chunk = six_bit_chunk(head)
  #Add to Reversed_chunks
  six_bit_chunks_(rest, [six_bit_chunk]++chunks_list)
defp six_bit_chunks_([], chunks_list) do

Indices are different

I don't know why, but indices are different. I don't think there is a clever reason. It just is.

In Erlang lists:sublist("words", 2, 3) returns "ord". And in Elixir Enum.slice('words', 2, 3) returns 'rds'; That is something else to be aware off the differences in single and double quotes; single quotes are charlists as per Erlang, whereas double quotes are for Elixir strings (something different).

Flipping order of args... and pipes.

In Elixir some functions have the order of the arguments flipped from how they are in Erlang. This threw me to start with and I thought it was to make Ruby programmers happy, but actually it's because of pipes.

In Erlang:

Eight_bit_chunks = lists:map(
    fun(Group_of_chunks) ->

In Elixir the list, etc is always first:

eight_bit_chunks = Enum.map(
  fn(group_of_chunks) ->

This means you can then do things like this:

|>  Enum.map(
      fn(group_of_chunks) ->

I.e. pull out and pipe five_bit_chunks into the Enum.map. Which doesn't look that impressive on its own but it means you can chain things together. Pipes are neat. My only quibble is that it is a step towards Haskell's esoteric symbols (I liked Erlang over Haskell just because it was a little easier to understand).


I am mid-way through porting my Erlang command line application to Elixir. My plan is to then use Phoenix to turn this into a web application so other people (ha!) can use it. I also have plans to improve it. Slow, long term plans. I mention this only to say that you can write Ruby without going near Rails and the same is true of Elixir and Phoenix; and both are something you should do.