Why I Love Elixir

...and Companies Are Crazy Not To Use It

Why I Love Elixir

...and Companies Are Crazy Not To Use It

Motorola funded a study which involved rewriting a telecommunication system used by the emergency services from C++ to Erlang, focusing on productivity gains. Depending on how you calculated, the code reduction in the Erlang system achieved a result of 4-20 times less code. The 20 times reduction assumed the OTP libraries to be part of the Erlang standard libraries, which they are. As C++ did not have a generic OTP, the original project had to implement a good part of it.

Francesco Cesarini, “Which Companies Are Using Erlang, and Why?”

Elixir & Erlang are unique among programming languages in offering safe concurrent/parallel programming out of the box. Erlang was created by telecom firm Ericsson in the 1980s to provide rock-solid stability and failure recovery. Joe Armstrong was one of Erlang’s main creators, and his “A History of Erlang” provides a fabulous history of the why and how of its creation. After scouring the world for the most suitable programming language, Ericsson engineers came up empty and felt forced to invent one. Telecom companies had greater need for fault-tolerant, parallel programming in the 1980s than anyone else. Here are some more histories.

The problems Ericsson solved with Erlang in the 1980s are the same exact problems anyone trying to build highly reliable large-scale software systems in 2023, especially since microprocessor speeds have plateaued in recent years. Because almost all performance gains have come through adding more cores to modern CPUs, not though faster clockspeeds, anyone wanting to leverage more than a fraction of their CPU’s power requires software that runs on more than a single CPU core. An Erlang or Elixir program will automatically use all your CPU cores. No code changes required. In fact, a single Erlang or Elixir program can even run across multiple computers!

Though niche languages, Elixir and its parent Erlang, are high-productivity languages used by smart companies to build feature-rich, scalable, reliable projects with small engineering staffs. Cisco ships two million devices a year with Erlang in them and says 90% of Internet traffic goes through Erlang-controlled servers. Erlang empowered a mere 34 WhatsApp engineers – only ten of whom worked on server-side code – to serve 450 million users and get bought by Facebook for $19 billion. A year after Facebook bought it, WhatsApp needed 50 engineers to server 900 million users.

Elixir and its web framework, Phoenix, were created by two Ruby developers frustrated by Ruby’s inability to do concurrent programming. I recommend this history of Elixir, Phoenix, and LiveView from Phoenix creator Chris McCord. Many companies now rely on Elixir, including: Adobe, Bleacher Report, Cars.com, Discord, Financial Times, PepsiCo, Pinterest, Ramp, Spotify, and Toyota Connected. Organizations relying on Erlang include AdRoll, Bet365, BT Mobile, Goldman Sachs, Grindr, Mastercard’s Vocalink, Nintendo, and the UK’s National Health Service (NHS).

Despite Erlang’s decades of success, most popular languages – including Python, JavaScript/Node, and Ruby – remain effectively single-threaded, able to execute only one task at a time. This is of little consequence for small, simple programs and programs that can crash without severe consequences. Programmers partially work around these languages’ limitations by handling IO-bound tasks off the main execution thread (e.g., web workers) or offloading discrete chunks of work to job queues (e.g., Ruby’s Sidekiq and Resque). But there’s always a danger the main thread could die, taking down the entire program.

Other languages also allow you to do parallel programming using complicated, dangerous tactics like semaphores and mutexes. Perhaps the closest analogue to Erlang/Elixir is Scala’s Akka model, which attempts to provide the benefits of Erlang’s actor model but is not inherently safe, as Erlang is, because it’s build on the JVM (Java Virtual Machine), which does not guarantee memory isolation, so problems can arise (see: https://doc.akka.io/docs/akka/current/general/jmm.html).

In Elixir/Erlang, there is no main thread. A single Erlang or Elixir program can spawn literally millions of independently executing processes, and these processes will automatically run safely across all your CPU cores and even across multiple computers. Because Erlang processes share no memory and communicate only by passing messages to one another, if any process dies, the blast radius is limited to just that one process. In a well-designed Erlang/Elixir program, a “supervisor” process can generally detect failures and restart dead processes in a healthy state. Erlang & Elixir are perfectly suited to parallel programming tasks, such as launching and continuously monitoring the execution of many OS processes.

Elixir has another ace up its sleeve. Erlang/Elixir’s ability to spin up millions of independently executing threads is perfectly suited to building stateful client-server sessions that maintain the state of each user’s browser session inside a server-side Erlang process. The Phoenix Framework leverages this power. If any user’s session blows up, no other user’s session is affected. And a single web server can have, literally, millions of simultaneous users.

In recent years, Phoenix LiveView – watch What Is Phoenix LiveView? for a four-minute video intro – has become the envy of developers everywhere, and now most every language & web framework is trying to copy it. One JavaScript framework – LiveViewJS – is even stealing its name!

Developing & testing front-end and back-end code with LiveView is far more efficient and bug-free than in any other client-server framework because you can do everything – on both client and server – with Elixir code and Elixir data structures. No need to write separate client-side Javascript/React and server-side Elixir and serialize to JSON to pass data back and forth. Here’s a video presentation on “Testing LiveViews”.

LiveView logic is centralized on the server (so no code duplication or – even worse – logic duplication in different client- and server-side languages), and performance is outstanding because only the most minimal pieces of data are passed from client to server (events that can change server-side state) and from server to client (tiny data diffs that Morphdom uses under the covers to patch the rendered DOM when session state changes in a way that generates a UI diff… The UI is rendered via two arrays, one with static values and one with dynamic values; changes surgically update specific dynamic value(s)).

LiveView does not eliminate client-side JavaScript. It hides away the boilerplate JavaScript required by the LiveView framework, allowing Elixir developers to focus on being productive by coding in Elixir. LiveView even wraps commonly used JavaScript functionality in an easy-to-use Elixir layer. LiveView users can still access the JavaScript, send messages to and receive messages from JavaScript code running in the browser, leverage browser APIs, trigger and detect events in the browser, and use and interact with JavaScript libraries. See LiveView’s “JavaScript interoperability” documentation. But you can accomplish a ton with LiveView without touching or thinking about JavaScript.

I haven’t even mentioned some incredibly powerful tools that have been built atop Elixir. This is long enough already, but let me point you to a few:

  • LiveBook – “Automate code & data workflows with interactive notebooks”
  • Nx – “Multi-dimensional arrays (tensors) and numerical definitions for Elixir”
  • Explorer – “Series (one-dimensional) and dataframes (two-dimensional) for fast data exploration in Elixir”
  • Axon – “Nx-powered Neural Networks for Elixir”
  • Scholar – “Traditional machine learning on top of Nx”
  • Bumblebee – “Pre-trained Neural Network models in Axon (+ 🤗 Models integration)”

Intrigued? Here are resources for learning more:

(With thanks to Olivier Collet for this photo on Unsplash)