Successful programming languages are invented to solve problems existing languages and tools do not address well. When I asked José Valim what problem he was trying to solve when creating Elixir, he responded that he wanted to bring the power of Erlang and the BEAM to other communities of programmers. He started with the web through the Phoenix framework, followed by successful inroads into the embedded and machine learning spaces. “What problem were you trying to solve?” is a question I have asked dozens of language inventors, with varied answers. José was the first, who, in his reply, said his focus was on the adoption of ideas, semantics, and runtime of another extremely powerful language, Erlang. He did it by approaching the problem with a different syntax, tools, and development approach.
What problems were Erlang co-inventors, Joe Armstrong, Robert Virding, and Mike Williams, trying to solve? They set out on a quest to understand how to better and more efficiently build and maintain scalable, fault-tolerant systems. These systems in the early ’90s were typically associated with telecom switches, but soon, they became applicable to any piece of software connected to the internet. Their solution happened to be a programming language, even if they had not set out to invent one. Erlang ended up being used in major infrastructure projects at Cisco, Ericsson, Klarna, Goldman Sachs, T-Mobile, WhatsApp, and Amazon, alongside many other top companies. As more programming languages were added to the BEAM, Erlang and its runtime became an Ecosystem of languages today referred to as the Erlang ecosystem. Elixir is, without a doubt, the most popular of these languages.
So how does all of this relate to the book you are about to read? It is simple. To truly understand and embrace the power of Elixir, you need to understand both Erlang and OTP. I am not suggesting you go off and learn these languages but, instead, learn Elixir from someone who has used Erlang professionally for many years before making the transition. Saša Jurić, by explaining what makes Erlang special, shows you how to efficiently use Elixir. Explaining why Erlang works the way it does shows you the what and the how of Elixir. This is what differentiates Elixir in Action from all of the other books on the topic. I hope you enjoy it as much as I did, learning not only about a programming language but about the philosophy of the ecosystem as a whole.
—Francesco Cesarini
Founder of Erlang Solutions;
Member of the team who worked on the R1 release of OTP;
Coauthor of Erlang Programming and Designing for Scalability with Erlang/OTP;
Founding member of the Erlang Ecosystem Foundation;
Senior lecturer at the University of Oxford
In 2010, I was given the task of implementing a system to transmit frequent updates to a few thousand connected users in near-real time. My company at the time was mostly using Ruby on Rails, but I needed something more suitable for such a highly concurrent challenge. Following the suggestion of my CTO, I looked into Erlang, read some material, made a prototype, and performed a load test. I was impressed with the initial results and moved on to implement the whole thing in Erlang. A few months later, the system was shipped, and it’s been doing its job ever since.
As time passed, I began to increasingly appreciate Erlang and the way it helped me manage such a complex system. Gradually, I came to prefer Erlang over the technologies I had used previously. I began to evangelize the language, first in my company and then at local events. Finally, at the end of 2012, I started the blog The Erlangelist (http://theerlangelist.com), where I aim to showcase the advantages of Erlang to programmers from OO backgrounds.
Because Erlang is an unusual language, I began experimenting with Elixir, hoping it would help me explain the beauty of Erlang in a way that would resonate with OO programmers. Despite the fact that it was at an early stage of development (at the time, it was at version 0.8), I was immediately impressed with Elixir’s maturity and the way it integrated with Erlang. Soon, I started using Elixir to develop new features for my Erlang-based system.
A few months later, I was contacted by Michael Stephens of Manning Publications, who asked me if I was interested in writing a book about Elixir. At the time, two Elixir books were already in the making. After some consideration, I decided there was space for another book that would approach the topic from a different angle, focusing on Elixir concurrency and the OTP way of thinking. Writing the book took a lot of work, but it was a rewarding experience.
This is the third edition of the book, and it isn’t radically different from the first or second ones. Rather, it focuses on bringing the book up to date with the latest developments in Elixir and Erlang, such as the new ways of working with application configuration and OTP releases.
At this point, Elixir in Action is again fully up to date and teaches you the most recent techniques for building software systems with Elixir. I hope you enjoy reading the book, learn a lot from it, and have a chance to apply your new knowledge in your work!
Writing this book required a significant time investment, so, above all, I want to thank my wife, Renata, for her endless support and patience during those long hours and busy weekends.
I’d like to thank Manning for making this book happen. In particular, thanks go to Michael Stephens, for making the initial contact; Marjan Bace, for giving me a chance to write this book; Bert Bates, for pointing me in the right direction; Karen Miller and Rebecca Johnson, for keeping me on track; Aleksandar Dragosavljević and Dunja Nikitović, for managing the review process; Kevin Sullivan and Vincent Nordhaus for overseeing production; Tiffany Taylor, Andy Carroll, and Christian Berk, for transforming my “English” into proper English; and Candace Gillhoolley, Ana Romac, Christopher Kaufmann, and Radmila Ercegovac, for promoting the book.
The material in this book has been significantly improved thanks to great feedback from reviewers and early readers. Above all, I wish to thank Andrew Gibson for useful feedback and great insights as well as for rescuing me when I got stuck at the last hurdle. I’d also like to thank Oleksii Sholik, Peter Minten, and Marius Butuc, who provided excellent immediate technical feedback during the writing process.
A big thank you goes to all the technical reviewers: Al Rahimi, Alan Lenton, Alessandro Campeis, Alexander Zenger, Alexey Galiullin, Andrew Courter, Ariel Otilibili, Arun Kumar, Ashad Dean, Christoffer Fink, Christopher Bailey, Christopher Haupt, Clive Harber, Daniel Couper, Eoghan O’Donnell, Frederick Schiller, Gábor László Hajba, George Thomas, Heather Campbell, Ioannis Polyzos, Jeroen Benckhuijsen, Jim Amrhein, Johan Mattisson, Jorge Deflon, José Valim, Kosmas Chatzimichalis, Laszlo Hegedus, Mafinar Khan, Mark Ryall, Mathias Polligkeit, Michael Piscatello, Mohsen Mostafa Jokar, Rahul Sinha, Riza Fahmi, Simon Hewitt, Simone Sguazza, Tijl Vercaemer, Tom Geudens, Tomer Elmalem, Ved Antani, and Yurii Bodarev.
I also wish to thank all the readers who bought and read the Manning Early Access Program (MEAP) version and provided useful comments. Thank you for taking the time to read my ramblings and for providing insightful feedback.
The people who gave us Elixir and Erlang, including the original inventors, core team members, and contributors, deserve a special mention. Thank you for creating such great products that make my job easier and more fun. Thank you, Francesco Cesarini, for the lovely foreword. Finally, special thanks go to all the members of the Elixir community; this is the nicest and friendliest developer community I’ve ever known!
Elixir is a modern functional programming language for building large-scale, distributed, fault-tolerant, scalable systems for the Erlang virtual machine (VM). Although the language is compelling in its own right, arguably, its biggest advantage is that it targets the Erlang platform.
Erlang was made to help developers deal with the challenge of high availability. Originally, the product was intended for developing telecommunication systems, but today, it’s used in all kinds of domains, such as collaboration tools, online payment systems, real-time bidding systems, database servers, and multiplayer online games, to name only a few examples. If you’re developing a system that must provide service to a multitude of users around the world, you’ll want that system to function continuously without noticeable downtime, regardless of any software or hardware problems that occur at run time. Otherwise, significant and frequent outages will leave end users unhappy, and ultimately, they may seek alternative solutions. A system with frequent downtime is unreliable and unusable and, thus, fails to fulfill its intended purpose. Therefore, high availability becomes an increasingly important property—and Erlang can help you achieve that.
Elixir aims to modernize and improve the experience of developing Erlang-powered systems. The language is a compilation of features from various other languages, such as Erlang, Clojure, and Ruby. Furthermore, Elixir ships with a toolset that simplifies project management, testing, packaging, and documentation building. Arguably, Elixir lowers the entry barrier into the Erlang world and improves developer productivity. Having the Erlang runtime as the target platform means Elixir-based systems are able to use all the libraries from the Erlang ecosystem, including the battle-tested OTP framework that ships with Erlang.
This book is a tutorial that will teach you how to build production-ready Elixir-based systems. It’s not a complete reference on Elixir and Erlang—it doesn’t cover every nuance of the language or every possible aspect of the underlying Erlang VM. It glosses over or skips many topics, such as floating-point precision, Unicode specifics, file I/O, unit testing, and more. Although they’re relevant, such topics aren’t this book’s primary focus, and you can research them yourself when the need arises. Omitting or dealing quickly with these conventional topics gives us space to treat more interesting and unusual areas in greater detail. Concurrent programming and the way it helps bring scalability, fault tolerance, distribution, and availability to systems are the core topics of this book.
Some of the techniques covered in this book aren’t discussed in full detail. I’ve omitted some fine-print nuances for the sake of brevity and focus. My goal is not to provide complete coverage but, rather, to teach you about the underlying principles and how each piece fits into the bigger picture. After finishing this book, you should find it simple to research and understand the remaining details on your own. To give you a push in the right direction, mentions of and links to further interesting topics appear throughout the book.
Because this book deals with upper-intermediate topics, there are some prerequisites you should meet before reading it. I’ve assumed you’re a professional software developer with a couple of years of experience. The exact technology you’re proficient in isn’t relevant: it can be Java, C#, Ruby, C++, or another general-purpose programming language. Any experience in development of backend (server-side) systems is helpful.
You don’t need to know anything about Erlang, Elixir, or other concurrent platforms. In particular, you don’t need to know anything about functional programming. Elixir is a functional language, which, if you come from an OO background, may scare you a bit. As a long-time OO programmer, I can sincerely tell you not to worry. The underlying functional concepts in Elixir are relatively simple and should be easy to grasp. Of course, functional programming is significantly different from whatever you’ve seen in a typical OO language, and it takes some getting used to. But it’s not rocket science, and if you’re an experienced developer, you should have no problem understanding these concepts.
The book is divided into three parts. Part 1 introduces the Elixir language, presents and describes its basic building blocks, and then treats common functional programming idioms in more detail:
Chapter 1 provides a high-level overview of Erlang and Elixir and explains why those technologies are useful and what distinguishes them from other languages and platforms.
Chapter 2 presents the main building blocks of Elixir, such as modules, functions, and the type system.
Chapter 3 gives a detailed explanation of pattern matching and how it’s used to deal with flow control.
Chapter 4 explains how to build higher-level abstractions on top of immutable data structures.
Part 2 builds on these foundations and focuses on the Erlang concurrency model and its many benefits, such as scalability and fault-tolerance:
Chapter 5 explains the Erlang concurrency model and presents basic concurrency primitives.
Chapter 6 discusses generic server processes—building blocks of highly concurrent Elixir and Erlang systems.
Chapter 7 demonstrates how to build a more involved concurrent system.
Chapter 8 presents the idioms of error handling, with a special focus on errors and faults in concurrent systems.
Chapter 9 provides an in-depth discussion of how to isolate all kinds of errors and minimize their impact in production.
Chapter 10 discusses a couple of alternatives to generic server processes that are sometimes more appropriate for implementing parts of your system.
Part 3 deals with systems in production:
Chapter 11 explains OTP applications, which are used to package reusable components.
Chapter 12 discusses distributed systems, which can help you improve fault tolerance and scalability.
Chapter 13 presents various ways of preparing an Elixir-based system for production, particularly focusing on OTP releases.
This book contains many examples of source code both in numbered listings and in line with normal text. In both cases, source code is formatted in a fixed-width font like this
to separate it from ordinary text.
In some cases, the original source code has been reformatted; we’ve added line breaks and reworked indentation to accommodate the available page space in the book. Additionally, comments in the source code have been removed from the listings when the code is described in the text. Code annotations accompany many of the listings, highlighting important concepts.
You can get executable snippets of code from the liveBook (online) version of this book at https://livebook.manning.com/book/elixir-in-action-third-edition. The complete code for the examples in the book is available for download from the Manning website at https://www.manning.com/books/elixir-in-action-third-edition, and from GitHub at https://github.com/sasa1977/elixir-in-action/tree/3rd-edition.
Purchase of Elixir in Action, Third Edition, includes free access to liveBook, Manning’s online reading platform. Using liveBook’s exclusive discussion features, you can attach comments to the book globally or to specific sections or paragraphs. It’s a snap to make notes for yourself, ask and answer technical questions, and receive help from the author and other users. To access the forum, go to https://livebook.manning.com/book/elixir-in-action-third-edition/discussion. You can also learn more about Manning’s forums and the rules of conduct at https://livebook.manning.com/discussion.
Manning’s commitment to our readers is to provide a venue where a meaningful dialogue between individual readers and between readers and the author can take place. It is not a commitment to any specific amount of participation on the part of the author, whose contribution to the forum remains voluntary (and unpaid). We suggest you try asking the author some challenging questions lest their interest stray! The forum and the archives of previous discussions will be accessible from the publisher’s website as long as the book is in print.
Saša Jurić is a developer with extensive experience implementing high-volume, concurrent, server-side systems—desktop and kiosk applications—using various programming languages, such as C#, Ruby, and JavaScript. For the past 14 years, his main professional focus has been on the BEAM languages, primarily Elixir. In recent years, he’s been working as an Elixir mentor, helping teams adopt Elixir and use it in production. He occasionally blogs about Elixir and Erlang at https://www.theerlangelist.com/.
The figure on the cover of Elixir in Action, Third Edition, “A Russian Girl,” is taken from a book by Thomas Jefferys, published between 1757 and 1772.
In those days, it was easy to identify where people lived and what their trade or station in life was just by their dress. Manning celebrates the inventiveness and initiative of the computer business with book covers based on the rich diversity of regional culture centuries ago, brought back to life by pictures from collections such as this one.