In the first part of this article, we have discussed the need for concurrency in today's software and how the Erlang VM not only provides the proper tooling and abstractions for writing concurrent software but also for building distributed, fault-tolerant applications.
In this second part, we will explore what Elixir brings to the table and its main goals.
The better way to answer this question is to look at Elixir's three main goals: productivity, extensibility and compatibility.
Productivity is, in general, a hard goal to measure. A language productive for creating desktop applications may not be productive for mathematical computing. Productivity depends directly on the field in which you intend to use the language, the available tools in the ecosystem and how easy it is to create and extend those tools.
For example, Elixir attempts to eliminate many steps in between starting with the language and writing production ready code. That's why Elixir ships with a unit test framework named ExUnit and build called Mix. With simple three commands, you can create a complete Elixir application, including a supervisor chain, compile and test it:
Our second goal, extensibility is directly tied to productivity. To quote Guy Steele:
Now we need to go meta. We should now think of a language design as being a pattern for language designs. A tool for making more tools of the same kind. [...] A language design can no longer be a thing. It must be a pattern, a pattern for growth. A pattern for growing a pattern, for defining the patterns that programmers can use for their real work and main goals.
- Guy Steele, keynote at the 1998 ACM OOPSLA conference on "Growing a Language"
For this reason, we have opted for a small language core. For example, while some languages have if, case, try and so on as language keywords, each with its own rules in the parser, in Elixir they are just macros. This allows us to implement most of Elixir in Elixir and also allows developers to extend the language using the same tools we used to build the language itself, often extending the language to the specific domains they are working on.
Here is an example of how someone would implement unless, which is a keyword in many languages, in Elixir:
Since a macro receives the code representation as arguments, we can simply convert an
unless into an
ifat compile time.
Macros are also the base construct for meta-programming in Elixir: the ability to write code that generates code. Meta-programming allows developers to easily get rid of boilerplate and create powerful tools. ExUnit, that test framework that ships with Elixir, uses macros for expressiveness. Let's see an example:
The first thing to notice is the
async: true option. When your tests do not have any side-effects, you can run them concurrently by passing the
async: true option.
Next we define a test case and we do an assertion with the
assert macro. Writing tests by simply using
assert would be a bad practice in many languages as it would provide a poor error report. In such languages, functions/methods like
assert_equal would be the recommended way of performing such assertion.
In Elixir, however,
assert is a macro and as such it can look into the code being asserted and infer that a comparison is being made. This code is then transformed to provide a detailed error report when the test runs:
This simple example illustrates how a developer can leverage macros to provide a concise but powerful API. Macros have access to the whole compilation environment, being able to check the imported functions, macros, defined variables and more. And those examples are just scratching the surface of what can be achieved with macros in Elixir.
Finally, the last goal is compatibility. Compatibility is about being compatible with the Erlang VM and the whole existing ecossystem, which allows developers to benefit from all the features we have described in the previous section. Elixir can call Erlang code, and vice-versa, with no conversion cost at all.
Elixir and the Erlang VM are here to change the way you write software and prepare you for the next years in computing. By using Elixir, you can join open source projects like CouchDB, Riak, RabbitMQ, Chef11 and companies like Ericsson, Heroku, Facebook, Basho, Klarna and Wooga which already enjoying the benefits provided by the Erlang VM, some of them for quite a long time.