Dynamic, Scalable, Maintainable. These are the keywords that many programming languages in the market use for advertising. Elixir, too, promotes itself with these attributes and yet it stands out as exceptional. The programming language has been around since 2011 and has a steadily growing fanbase. This community actively contributes to the development of the language and its ecosystem, integrating it into an increasing number of productive projects.
We asked our colleague Raphael Esterle to explain what Elixir is and what makes it so special.
Hello Raphael, thank you for taking the time for us. Let’s dive right in: Where does Elixir come from? Who invented it? Why?
Those are three questions at once. I’ll start with “Why.” Elixir aims to simplify the development of distributed, highly available, and fault-tolerant backend systems. These are systems that are crucial in the age of networking, exhibiting high complexity. Now, to answer the first two questions together:
In 2011, José Valim released the first version of Elixir. The language is heavily influenced by Ruby in many aspects. However, it fundamentally differs from Ruby at the runtime level. Elixir’s runtime, BEAM, is optimized for concurrency, parallelism, and high throughput. BEAM is a virtual machine developed with and for the Erlang language.
So, is BEAM and Erlang for Elixir what JVM and Java are for Kotlin or Scala?
Yes, that’s a very good comparison because, like Scala being compatible with Java, Elixir is compatible with Erlang and its ecosystem. However, Erlang and its ecosystem have been around for a few more years than Java.
What sets Elixir apart from others?
For me, three points are crucial: runtime, syntax, and ecosystem. All three together make Elixir an extremely interesting language. Let’s start with the runtime. One thing to note before that: everything I’m going to say about Erlang applies to Elixir as well.
Erlang and BEAM were developed by/at Ericsson for use in the telephone switches manufactured by Ericsson. Since these applications have the same requirements for software as today’s networked applications – distributed, highly available, and fault-tolerant – we can leverage over 30 years of matured solutions for these problems with BEAM and Erlang.
This all sounds very abstract. Can you give a concrete example of how BEAM and Erlang make applications distributed, highly available, and fault-tolerant?
Certainly. BEAM and Erlang implement the Actor Model. Processes communicate exclusively through messages. Each process can send messages to other processes and has an “inbox” for messages received from other processes.
As a Java developer, Akka comes to mind, which also implements the Actor Model.
Exactly. The difference is that the Actor Model in Erlang is implemented at the language and runtime level. It is thus embedded in the language and native to the runtime, being the only means of inter-process communication. Perhaps I should briefly explain the term “process” in this context.
In the Erlang world, a process refers to a virtual thread, i.e., a thread managed by BEAM and not the operating system. Therefore, processes in Erlang are very lightweight, and it is common to run thousands of them simultaneously. Moreover, processes can be transparently distributed across different nodes in a cluster. A process on another node in the cluster behaves the same way as a process running on the same node.
So, we’ve clarified how Erlang enables the development of distributed systems. What about the other two properties, fault tolerance and error tolerance?
These two properties go hand in hand. In short, processes can monitor and control other processes. The “let it crash” philosophy is implemented, meaning a process that encounters an error simply “dies” without worrying much about error handling. The monitoring process takes care of error handling, usually by restarting the corresponding process.
Now we’ve learned a lot about Erlang and BEAM. Where and how does Elixir come into play?
It might seem a bit strange that I’m focusing so much on Erlang, but it’s essential to understand that by using BEAM, everything I’ve mentioned about Erlang also applies to Elixir. Now, let’s get to the differences. Erlang and Elixir mainly differ in syntax and ecosystem.
As mentioned, Erlang’s syntax is over 30 years old, not quite fresh. On the other hand, Elixir has a modern and, in my opinion, easily understandable syntax heavily inspired by Ruby. This is partly because there are relatively few language elements and also due to the extensive use of pattern matching.
Often, there’s precisely one way to efficiently solve a problem. Following the functional paradigm, it’s straightforward to “compose” complex functionality from simple (partial) functionality. And if a language element is missing, you can implement your own language elements through metaprogramming, i.e., writing Elixir code with Elixir code. Metaprogramming makes the language powerful and extensible. For example, domain-specific languages can be created this way.
This is coupled with a robust ecosystem with excellent documentation and a welcoming community. At the center of the ecosystem is Mix, Elixir’s build tool. It allows scaffolding, testing, building projects, dependency management, and much more.
When is Elixir not a good idea?
It’s challenging to make a blanket statement because, in my perception, Elixir has evolved into a versatile language lately. For example, Embedded Elixir can be used to program microcontrollers, and Numerical Elixir can perform calculations on multidimensional arrays. However, as mentioned, the focus is on distributed systems. Elixir is often used with Phoenix, a web framework, to create web applications.
With few exceptions, it can be said that Elixir is not suitable for large numerical calculations and low-level applications. Elixir excels when used on the server side.
What is Phoenix?
Phoenix is a framework, or library, for creating web applications. Phoenix drew inspiration from Rails, a similar framework for the Ruby programming language. Like Rails, Phoenix is primarily designed for server-side rendering following the Model-View-Controller pattern. LiveView, introduced some time ago, blurs the boundaries between server-side and client-side rendering, providing an alternative for single-page applications.
What sets Phoenix apart from others?
The most significant difference from other well-known server-side MVC frameworks is undoubtedly that Elixir is a functional language, and Phoenix is also implemented with functional patterns. This may require some adjustment if coming from an object-oriented context, but on the other hand, many find that things feel more natural.
For example?
In Phoenix, the entire request-response cycle is essentially nothing more than a transformation of the request data structure into a response data structure using functions. It feels very natural to me.
Another difference is that, like Rails, Phoenix follows the convention over configuration approach. Therefore, projects can quickly gain momentum as a lot of boilerplate code is eliminated.
What excites you about Elixir?
The entire approach of Elixir is fresh and unique. One can see the runtime as a counterproposal to the microservices design pattern, for example. With Elixir, it’s effortless to modularize large applications and scale these modules over a cluster, deploying them independently. However, it’s not limited to very large applications; small applications that grow and scale over time can also be built. The language is popular among developers because of its relatively small language scope and excellent documentation, leading to high efficiency.
Bonus – Do you have a quick start for me? What would be good introductory literature?
Depending on someone’s prior experience with functional programming, the entry point may vary. Overall, I can recommend the books from “Pragmatic Bookshelf,” especially “Programming Elixir.” The official website also provides a good introduction.
Raphael, thank you very much for your time and for answering the questions.
Über den Autor
Raphi works as a software engineer and consultant at Inspired. He's specialized in IT security. When concepting and implementing software he's always trying to take the point of view of potential aggressors.
He's engaing in functional programming in general for over 6 years and Elixir programming in particular for about 3 years using it on a daily basis.