home  .   articles  .   til  .   about  .   contact

Elixir Atoms

I’ve officially begun my Elixir journey. Coming from some experience with F# and Ruby I’ve noticed many syntax and feature similarities. One of the first things I noticed was the presence of :atoms. Atoms in Elixir are similar to Ruby’s symbol type. But Ruby and Elixir aren’t the only languages that support this basic type. The list is long: Clojure, Smalltalk, Scheme, Scala, and Objective-C just to name a few. The idea seems to come from C’s enum.

In the simplest terms an atom is just a named constant. I often found myself using enums in C to pass an option to a function. This happens to be a common pattern in Elixir as well.

Atoms come in handy when pattern matching return values. Playing around with Phoenix I have noticed that a lot of functions return a tuple with the first element being :ok or :error. This makes it really simple to handle behavior based on success and failure because :ok and :error will always have the same value that you can match against.

case foo do
  {:ok, _} -> IO.puts "SUCCESS!!@!@$*()"
  {:error, _} -> IO.puts "sadface"

That brings me to a very important point. Atoms are completely unique. The named text is stored along with its numerical value, one word in size, in a lookup table. Atoms are NOT garbage collected, and any two atoms with the same name will always be equivalent. True and false are actually atoms in Elixir, there is no Boolean type.

There are some pros and cons here. Atoms provide for great performance because their lookup times are very fast. The important caveat here is that memory consumption can become a real issue. Each atom is one word in size. The default limitation by the VM is 1,048,577 but it’s unlikely that you would want anywhere close to that number. It has been suggested by many to never dynamically generate atoms, and for good reason.