Elixir / Erlang Learning resources



This is my attempt to collect Erlang / Elixir resources that I have read or watched. I have only listed content that I have personally completed and enjoyed. I will try to keep this up to date, at least periodically.

NOTE: This is a work-in-progress and requires a lot of structure / love. But if I wait to publish these resources until I’ve finished all of that, it’ll be months.

Why Did I Pursue Erlang / Elixir?

After 25 years in the industry, I decided to take a step back and determine the problems that I want to be solving. I decided that my primary interest is in designing scalable server software. I work at a fintech company, building payment processing systems, and I wanted to expand my capabilities related to those problems.

I spent about 4-5 months exploring a bunch of new languages that had popped up over the past years. Ultimately, I chose Elixir running on the Erlang VM for the following reasons:

  • the ability to run a tremendous amount of light-weight servers with complete memory isolation
  • native clustering built into the runtime for horizontal scalability
  • a native model for failure management and isolation
  • actor-model based processes, with native sync and async execution capabilities
  • highly effective garbage collection model (complete memory isolation enables gc to run per process, instead of halting the world)
  • support for hot code swapping, benefiting both dev and production environments
  • low latency, near-realtime capabilities well suited for server software
  • well-written and mature tooling including OTP (the Erlang standard library for concurrent server development)

I chose Elixir because:

  • it can do everything that Erlang can, it’s built on Erlang
  • its Erlang interop capabilities mean you can use any Erlang or Elixir libraries, best of both worlds
  • thriving ecosystem developed by unusually talented engineers.. tools like Phoenix framework, Oban, and more provide relatively unparalleled capabilities in their spaces
  • powerful metaprogramming capabilities enable judicious use of domain-specific languages
  • one-of-a-kind evolving type system catches errors in dynamically typed code
  • mature tooling for composable workflows (GenStage, flow, broadway)

I discovered over my years of exploration, that this toolset pushes away a lot of the accidental coMplexity related to concurrency in languages like Java, Ruby, Python, and PHP and brings the incidental complexity to the foreground, forcing engineers to acknowledge and account for them. These are properties that I value in my tools.

Introduction into Erlang / Elixir

The first thing that you need to know is that Elixir is nothing without Erlang. The Erlang virtual machine (also referred to as the BEAM) is a power runtime environment for applications. The entire concept behind the BEAM is that it’s a runtime environment for tiny little servers. Servers are implemented with the actor model or in systems such as the Java VM.

These BEAM servers are called Processes. Do not confuse these processes for ‘threads’ at either the system-level or in systems such as the Java VM. The BEAM’s scheduler ensures that each little (very cheap, very lightweight) server is run concurrently with as much parallelism as your processors can support. The BEAM scheduler will distribute your process execution across as many cores as you’ve configured.

The BEAM runtime environment supports scaling through native clustering. Multiple BEAM nodes can be connected as a cluster and processes can communicate transparently across nodes as easily as within a single node. This is the mechanism through which the BEAM offers horizontal scaling.

Getting a Feel / Motivation for Erlang / Elixir

Maybe the most fun introduction to Erlang is Erlang: The Movie, which I rewatch periodically out of love.

Which Should I Learn: Erlang or Elixir?

Once I understood what the Erlang VM had to offer, I decided to learn Erlang and build some small project with it before I move to Elixir. I’m glad that I did, I have become very fond of the Erlang syntax (something that many people find to be an acquired taste) and I love many aspects of its design that I miss in Elixir.

However, you’re very free to directly pick up Elixir. In learning Elixir you’ll learn all of the core ideas behind Erlang, as Elixir is built upon Erlang. You’ll get a more familiar syntax (easier for people to adjust to), Elixir’s fantastic metaprogramming, and it’s fantastic ecosystem.

If you’re in it to learn history and expand your understanding of what programming could be, maybe you want to start with Erlang. If you feel you learn best and keep your motivation best when immediately developing web software or something like that, then maybe jump straight to Elixir.

Elixir is better for web because it has Phoenix. You can do anything with Elixir that you can do with Erlang. Elixir supports both Erlang and Elixir libraries. Probably you want Elixir.

REMEMBER: Aesthetics around syntax are based on FAMILIARITY. I recommend perfectly targeting capability first and then adjusting to the syntax as time goes on. It’s impossible for me to imagine that you’ll not come to love these languages.

Installation

If you’re installing Erlang / Elixir, then I highly recommend ASDF Package Manager. I recommend strongly against installing Erlang or Elixir with your OS package manager.

Once ASDF is installed, it’s something like this:

asdf plugin add erlang
asdf plugin add elixir
asdf listall erlang
asdf list all elixir

You’ll see Erlang versions like this:

26.2.3
26.2.4
26.2.5
26.2.5.1
26.2.5.2
26.2.5.3
26.2.5.4
26.2.5.5
26.2.5.6
26.2.5.7
26.2.5.8
26.2.5.9
27.0-rc1
27.0-rc2
27.0-rc3
27.0
27.0.1
27.1
27.1.1
27.1.2
27.1.3
27.2
27.2.1
27.2.2
27.2.3
27.2.4
27.3
28.0-rc1

Just choose the newest non-release candidate version. In this example, that’s 27.3.

For Elixir you’ll see something like this:

1.18.0-otp-26
1.18.0-otp-27
1.18.0-rc.0
1.18.0-rc.0-otp-25
1.18.0-rc.0-otp-26
1.18.0-rc.0-otp-27
1.18.1
1.18.1-otp-25
1.18.1-otp-26
1.18.1-otp-27
1.18.2
1.18.2-otp-25
1.18.2-otp-26
1.18.2-otp-27
1.18.3
1.18.3-otp-25
1.18.3-otp-26
1.18.3-otp-27
main
main-otp-22
main-otp-23
main-otp-24
main-otp-25
main-otp-26
main-otp-27
master
master-otp-21
master-otp-22
master-otp-23
master-otp-24

Since you chose version 27 of Erlang, you’ll choose an equivalent version of Elixir. In this case, 1.18.3-otp-27. You must choose an OTP version that matches your Erlang version.

Now that you know you’re installing versions:

  • Erlang 27.3
  • Elixir 1.18.3-otp-27
asdf install erlang 27.3
asdf install elixir 1.18.3-otp-27

Now you can see what versions of software you have installed:

$ asdf current
Name            Version         Source                     Installed
elixir          1.18.2-otp-27   ASDF_ELIXIR_VERSION        true
erlang          27.2.4          ASDF_ERLANG_VERSION        true
neovim          stable          /home/shawn/.tool-versions true

Remember that you need your ENV set up correctly. The following is what I did. I can’t speak to whether there’s better ways. Look into asdf’s .tool-versions capabilities for individual projects.

NOTE: I’m still working on adding more thoughts, more resources, and structuring it better. I just didn’t want to wait to publish the resources for the 2 months it’ll take me to make progress on that.

# in my ~/.zshrc
export ASDF_ELIXIR_VERSION=1.18.3-otp-27
export ASDF_ERLANG_VERSION=27.3
export PATH="${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH"
fpath=(${ASDF_DATA_DIR:-$HOME/.asdf}/completions $fpath)
autoload -Uz compinit && compinit

IDE / Development Environment

I use nvim with a modified LazyVim setup. Unless you’re specifically interested in going down the long and winding neovim path, then you probably would prefer vscode.

Getting Started with Erlang

My primary resources for getting started with Erlang were:

These alone are enough to get started. I especially liked slowly bouncing off of “Learn You Some Erlang" over the course of a couple of months, building familiarity with a lot of the ideas, before being ready to dive in and actually do some real coding. “Programming Erlang" was a great way to dive in further, with a lot more detail and focus on building software.

Advanced Erlang Materials

These materials are on more advanced topics and can be dived into later, once you’ve gotten up to speed with the rest.

Getting Started with Elixir

Directly starting with Elixir is a perfectly fine (and for some, more fun) approach. Previously mentioned resources like “Erlang: The Movie" and “Learn You Some Erlang for Great Good" are still very applicable (and fun).

For primary materials, I highly recommend:

Advanced Elixir Materials

For diving into more depth on specific topics, the following resources were a pleasure:

Pipelines / Flows (for data ingestion, for example)

OTP

Async Processing

Ports

Ports are an Erlang feature that empowers you to interact with non-Erlang systems by using traditional message passing to Erlang processes.

Phoenix Web Framework

The Phoenix framework is a significant part of the Elixir ecosystem. It ships with tools like Phoenix PubSub, Channels, and the popular LiveView web rendering system that has popularly been somewhat poorly imitated but never duplicated.

Ecto

Ecto is a popular relational database abstraction. It’s a much better tool than “ORMs", so if you’re tired of Hibernate and ActiveRecord, then don’t worry and read on.

Other Libraries of Note

Oban is an ecosystem stable for durable job processing. It ships with dashboards and while it’s useful out of the box it’s possible to pay for more advanced features. It’s a mature tool that can save a ton of work.

Elixir Notebook: Livebook

Notebooks integrate code and documentation into a single interface with other rich media that can be used for a variety of purposes including documentation, experimentation, and education. Elixir’s Livebook is an exceptionally powerful notebook which leverages the strengths of Erlang and Elixir to provide a best-in-class offering.

Community