Elixir is a programming language developed by José Valim in 2011, designed with the primary goals of enabling higher extensibility and productivity in the Erlang VM while maintaining compatibility with the Erlang’s ecosystem.
Elixir is built on top of Erlang and BEAM VM and is primarily used for web development, but there are many other cases in which it is being used such as IoT.
With high reliability, scalability and ease of testing at its core massive companies like Apple, Netflix, Discord, Pinterest and Whatsapp have adopted Elixir in their services.
Elixir is a functional, concurrent and general programming language. Since it is built on top of Erlang, it shares similar abstractions for building distributed, fault tolerant applications and has support for meta-programming with macros and polymorphism via protocols.
It is a robust and production-ready language built on a 30 year old, battle-tested technology: Erlang.
A core tenet of Elixir and functional programming is that all values are immutable.
But why is this important?
Imperative languages share and mutate values which means that different parts of an application can reference the same value and make changes to it.
“Objects bind functions and data structures together in indivisible units.” - Joe Armstrong
This presents issues for concurrency and can lead to “hard to detect” bugs.
For example, imagine multiple parts of a system running in parallel which have access to the same value at the same time. If the value is changed by any process, it can lead to some unpredictable outcomes.
There are thread and lock mechanisms in many imperative languages that help keep things synchronized but this requires detailed planning and adds overhead beyond the original problem you’re trying to solve.
Immutability is also being added to more languages as these problems become more prevalent, but again imperative languages have mutable values by default.
In Elixir and functional languages, all values are immutable by default. This simplifies the development of applications that utilize parallelism and concurrency.
Every operation generates new values so the value of dogs remains unchanged.
Simply put, parallel processes have stable values which they can safely change without affecting the results of any other process.
Elixir is built for concurrency.
Imperative vs Declarative
We’ve mentioned imperative and declarative languages so let’s try to nail down what these mean.
Imperative programming focuses on how to execute, defines control flow as statements that change a program state. In other words, it focuses on “how” individual statements, instructions or function calls are executed or evaluated in order to generate a result.
Declarative programming focuses on what to execute, defines program logic, but not detailed control flow. Declarative programming attempts to minimize side effects by describing what the program must accomplish, rather than how to accomplish it as a sequence of actions or statements.
This is a deeper subject than outlined here so feel free to dig more into it if you like.
Let’s use a code example to illustrate the differences:
This is a contrived example, but the former describes “how” to generate the result using control flow, and the latter leaves those details up to the computer.
Elixir has built-in support for concurrency out of the box because it runs on the Erlang VM (BEAM).
Elixir code runs inside lightweight OS threads of execution called processes that are isolated and exchange information via messages.
From the docs:
Due to their lightweight nature, it is not uncommon to have hundreds of thousands of processes running concurrently in the same machine. Isolation allows processes to be garbage collected independently, reducing system-wide pauses, and using all machine resources as efficiently as possible (vertical scaling).
We’re just hitting some high-points of Elixir in this overview so feel free to read more about how Erlang/OTP, BEAM handle concurrency if you’re interested.
Elixir is a well-designed language that comes with features that allow developers to write code that’s easy to reason about and to build systems that are highly-available and fault-tolerant.
In the next part we’ll cover Elixir Data Types and then progress through more Elixir Concepts such as Syntax and Patterns.
Hope you found this overview helpful!