What is Elixir? For my Ruby friends.

Many Ruby friends think of Elixir as just a functional Ruby. So they see it, maybe try it, and walk away.

Of course, they can be excused for doing so when you look at the syntactic similarities between the languages or if you’ve worked with equivalent elements in Rails and Phoenix (controllers, templates, etc.)

# ruby
class User
  def first_name
    # code here
  end
end
# elixir
defmodule User do
  def first_name do
    # code here
  end
end

But that’s just the surface.

Whereas Ruby is only a programming language, Elixir is a programming language that comes with a runtime system – something like an operating system – that we can design and control.

Here is one way to think of it.

Grab a Ruby program — a script that performs a task. Imagine we can run it inside a lightweight process:

Ruby script. Ruby script inside a process

Now imagine we can add code in that program to start other processes like it. The other processes can perform the same or different tasks. Some tasks do their job and finish, so they exit normally. Other tasks can loop indefinitely, living forever.

And those processes are very lightweight (so creating them is cheap), and they share no memory (so we don’t have to worry about accidentally mutating data). So, we can safely create many of them at little cost, each running a portion of our application.

Three scripts running in three processes

How can those programs affect one another since they don’t share memory?

They can send messages to each other through built-in language primitives.

Three scripts running in three processes and sending messages to each other

Since the processes are isolated but can communicate via messages, we can write a portion of our application (a program) to monitor the other processes. That program can supervise the others…

Three processes with scripts. One supervisor. One process dies (boom!)

…and restart them if they fail.

Three processes with scripts. One supervisor. The supervisor starts another one

That is what we call fault-tolerance, and it’s at the heart of Elixir.

What’s more, that group of processes can be but a tiny portion of our system. We can arbitrarily nest groups like it to form supervision trees:

Supervision tree with one top supervisor, two children (a and b), (a) supervises many workers, (b) supervises two other supervisors, which in turn supervise other supervisors and workers

Thus, with Elixir, we can design our application as a set of sub-systems that should live, die, and restart together.

So, Elixir isn’t just a functional Ruby. It’s more like a functional Ruby running on a custom-built operating system that we can design and control from the very language itself to create self-healing applications.