Extracted from:

Programming Elixir ≥ 1.6
Functional |> Concurrent |> Pragmatic |> Fun

This PDF file contains pages extracted from Programming Elixir ≥ 1.6, publishedby the Pragmatic Bookshelf. For more information or to purchase a paperback or
PDF copy, please visit http://www.pragprog.com.
Note: This extract contains some colored text (particularly in code listing). Thisis available only in online versions of the books. The printed versions are black
and white. Pagination might vary between the online and printed versions; thecontent is otherwise identical.
Copyright © 2018 The Pragmatic Programmers, LLC.
All rights reserved.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted,
in any form, or by any means, electronic, mechanical, photocopying, recording, or otherwise,
without the prior consent of the publisher.

The Pragmatic Bookshelf
Raleigh, North Carolina

Programming Elixir ≥ 1.6
Functional |> Concurrent |> Pragmatic |> Fun

Dave Thomas

The Pragmatic Bookshelf
Raleigh, North Carolina

Many of the designations used by manufacturers and sellers to distinguish their products
are claimed as trademarks. Where those designations appear in this book, and The Pragmatic
Programmers, LLC was aware of a trademark claim, the designations have been printed ininitial capital letters or in all capitals. The Pragmatic Starter Kit, The Pragmatic Programmer,
Pragmatic Programming, Pragmatic Bookshelf, PragProg and the linking g device are trademarks of The Pragmatic Programmers, LLC.
Every precaution was taken in the preparation of this book. However, the publisher assumes
no responsibility for errors or omissions, or for damages that may result from the use of
information (including program listings) contained herein.
Our Pragmatic books, screencasts, and audio books can help you and your team create
better software and have more fun. Visit us at https://pragprog.com.
The team that produced this book includes:
Publisher: Andy Hunt
VP of Operations: Janet Furlow
Managing Editor: Brian MacDonald
Supervising Editor: Jacquelyn Carter
Copy Editor: Candace Cunningham
Indexing: Potomac Indexing, LLC
Layout: Gilson Graphics
For sales, volume licensing, and support, please contact support@pragprog.com.
For international rights, please contact rights@pragprog.com.

Copyright © 2018 The Pragmatic Programmers, LLC.
All rights reserved.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted,
in any form, or by any means, electronic, mechanical, photocopying, recording, or otherwise,
without the prior consent of the publisher.
Printed in the United States of America.
ISBN-13: 978-1-68050-299-2
Encoded using the finest acid-free high-entropy binary digits.
Book version: P1.0—May 2018

A Vain Attempt at a Justification, Take Two
I’m a language nut. I love trying languages out, and I love thinking about
their design and implementation. (I know; it’s sad.)I came across Ruby in 1998 because I was an avid reader of comp.lang.misc(ask your parents). I downloaded it, compiled it, and fell in love. As with any
time you fall in love, it’s difficult to explain why. It just worked the way I work,
and it had enough depth to keep me interested.
Fast-forward 15 years. All that time I’d been looking for something new thatgave me the same feeling.
I came across Elixir a while back, but for some reason never got sucked in.
But a few months before starting on the first edition of this book, I waschatting with Corey Haines. I was bemoaning the fact that I wanted a way toshow people functional programming concepts without the academic trappings
those books seem to attract. He told me to look again at Elixir. I did, and I
felt the same way I felt when I first saw Ruby.
So now I’m dangerous. I want other people to see just how great this is. I wantto evangelize. So I write a book. But I don’t want to write another 900-page
Pickaxe book. I want this book to be short and exciting. So I’m not going into
all the detail, listing all the syntax, all the library functions, all the OTP
options, or….
Instead, I want to give you an idea of the power and beauty of this programming model. I want to inspire you to get involved, and then point to the online
resources that will fill in the gaps.
But mostly, I want you to have fun.
Fast-forward three years. Elixir has moved on. Phoenix, its connectivity framework, introduced a whole new set of developers to the joys of a functional
approach. The Nerves project makes it easy to write embedded Elixir code on
Linux-based microcontrollers. The Elixir base has grown—there are international, national, and regional conferences. Job ads ask for Elixir developers.

• Click HERE to purchase this book now. discuss

A Vain Attempt at a Justification, Take Two • iv

I’ve been moving on, too. But I’m still using Elixir daily. I just completed mysecond year as an adjunct professor at Southern Methodist University, corrupting the programmers of tomorrow with the temptations of Elixir. I’ve
written an online Elixir course.1
And now I’m revving this book. To be honest, I don’t really have to: Elixir 1.6
is not so different from 1.3 that the older book would not be useful. But myown thinking about Elixir has matured. I now do some things differently. And
I’d like to share these things with you.

Acknowledgments
It seems to be a common thread—the languages I fall in love with are createdby people who are both clever and extremely nice. José Valim, the creator of
Elixir, takes both of these adjectives to a new level. I owe him a massive thankyou for giving me so much fun over the last 18 months. Along with him, thewhole Elixir core team has done an amazing job of cranking out an entire
ecosystem that feels way more mature than its years. Thank you, all.
A conversation with Corey Haines reignited my interest in Elixir—thank you,
Corey, for good evenings, some interesting times in Bangalore, and theinspiration.
Bruce Tate is always an interesting sounding board, and his comments onearly drafts of the book made a big difference. And I’ve been blessed with anincredible number of active and insightful beta readers who have made literally hundreds of suggestions for improvements. Thank you, all.
A big tip of the hat to Jessica Kerr, Anthony Eden, and Chad Fowler for letting
me steal their tweets.
Kim Shrier seems to have been involved with my writing since before I started
writing. Thanks, Kim, for another set of perceptive and detailed critiques.
Candace Cunningham again amazed me with her detailed copy editing: it’srare to find someone who can correct both your grammar and your code. The
crew at Potomac did their customary stellar job of indexing.
Dave Thomas
dave@pragdave.me

Dallas, TX, April 20181.

https://codestool.coding-gnome.com• Click HERE to purchase this book now. discussCHAPTER 1Take the Red Pill
The Elixir programming language wraps functional programming with immutable state and an actor-based approach to concurrency in a tidy, modern
syntax. And it runs on the industrial-strength, high-performance, distributed
Erlang VM. But what does all that mean?
It means you can stop worrying about many of the difficult things that currently consume your time. You no longer have to think too hard about protecting your data consistency in a multithreaded environment. You worry lessabout scaling your applications. And, most importantly, you can think aboutprogramming in a different way.

Programming Should Be About Transforming Data
If you come from an object-oriented world, then you are used to thinking interms of classes and their instances. A class defines behavior, and objects
hold state. Developers spend time coming up with intricate hierarchies ofclasses that try to model their problem, much as Victorian scientists createdtaxonomies of butterflies.
When we code with objects, we’re thinking about state. Much of our time isspent calling methods in objects and passing them other objects. Based on thesecalls, objects update their own state, and possibly the state of other objects. In
this world, the class is king—it defines what each instance can do, and it implicitly controls the state of the data its instances hold. Our goal is data-hiding.
But that’s not the real world. In the real world, we don’t want to model abstract
hierarchies (because in reality there aren’t that many true hierarchies). We
want to get things done, not maintain state.
Right now, for instance, I’m taking empty computer files and transforming
them into files containing text. Soon I’ll transform those files into a format• Click HERE to purchase this book now. discussChapter 1. Take the Red Pill • 2

you can read. A web server somewhere will transform your request to download
the book into an HTTP response containing the content.
I don’t want to hide data. I want to transform it.

Combine Transformations with Pipelines
Unix users are accustomed to the philosophy of small, focused command-line
tools that can be combined in arbitrary ways. Each tool takes an input, transforms it, and writes the result in a format the next tool (or a human) can use.
This philosophy is incredibly flexible and leads to fantastic reuse. The Unix
utilities can be combined in ways undreamed of by their authors. And each
one multiplies the potential of the others.
It’s also highly reliable—each small program does one thing well, which makes
it easier to test.
There’s another benefit. A command pipeline can operate in parallel. If I write$ grep Elixir *.pml | wc -l

the word-count program, wc, runs at the same time as the grep command.
Because wc consumes grep’s output as it is produced, the answer is ready with
virtually no delay once grep finishes.
Just to give you a taste of this, here’s an Elixir function called pmap. It takes
a collection and a function, and returns the list that results from applyingthat function to each element of the collection. But…it runs a separate process
to do the conversion of each element. Don’t worry about the details for now.
spawn/pmap1.exs
defmodule Parallel dodef pmap(collection, func) docollection|> Enum.map(&(Task.async(fn -> func.(&1) end)))|> Enum.map(&Task.await/1)
end
end

We could run this function to get the squares of the numbers from 1 to 1,000.
result = Parallel.pmap 1..1000, &(&1 * &1)

And, yes, I just kicked off 1,000 background processes, and I used all thecores and processors on my machine.
The code may not make much sense, but by about halfway through the book,
you’ll be writing this kind of thing for yourself.

• Click HERE to purchase this book now. discussInstalling Elixir • 3

Functions Are Data Transformers
Elixir lets us solve the problem in the same way the Unix shell does. Rather
than have command-line utilities, we have functions. And we can string them
together as we please. The smaller—more focused—those functions, the more
flexibility we have when combining them.
If we want, we can make these functions run in parallel—Elixir has a simple
but powerful mechanism for passing messages between them. And these are
not your father’s boring old processes or threads—we’re talking about thepotential to run millions of them on a single machine and have hundreds ofthese machines interoperating. Bruce Tate commented on this paragraphwith this thought: “Most programmers treat threads and processes as a necessary evil; Elixir developers feel they are an important simplification.” As we
get deeper into the book, you’ll start to see what he means.
This idea of transformation lies at the heart of functional programming: afunction transforms its inputs into its output. The trigonometric function sin
is an example—give it π⁄4, and you’ll get back 0.7071. An HTML templating
system is a function; it takes a template containing placeholders and a listof named values, and produces a completed HTML document.
But this power comes at a price. You’re going to have to unlearn a whole lotof what you know about programming. Many of your instincts will be wrong.
And this will be frustrating, because you’re going to feel like a total n00b.
Personally, I feel that’s part of the fun. You didn’t learn, say, object-oriented
programming overnight. You are unlikely to become a functional programming
expert by breakfast, either.
But at some point things will click. You’ll start thinking about problems in adifferent way, and you’ll find yourself writing code that does amazing things
with very little effort on your part. You’ll find yourself writing small chunksof code that can be used over and over, often in unexpected ways (just as wc
and grep can be).
Your view of the world may even change a little as you stop thinking in termsof responsibilities and start thinking in terms of getting things done. And justabout everyone can agree that will be fun.

Installing Elixir
This book assumes you’re using at least Elixir 1.6. The most up-to-date
instructions for installing Elixir are available at http://elixir-lang.org/install.html. Go
install it now.

• Click HERE to purchase this book now. discussChapter 1. Take the Red Pill • 4

Running Elixir
In this book, I show a terminal session like this:$ echo Hello, World
Hello, World

The terminal prompt is the dollar sign, and the stuff you type follows. (Onyour system, the prompt will likely be different.) Output from the system isshown without highlighting.

iex—Interactive Elixir
To test that your Elixir installation was successful, let’s start an interactive
Elixir session. At your regular shell prompt, type iex.
$ iex
Erlang/OTP 20 [erts-9.1] [source] [64-bit] [smp:4:4] [ds:4:4:10][async-threads:10] [hipe] [kernel-poll:false]hInteractive Elixir (x.y.z) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>(The various version numbers you see will likely be different—I won’t botherto show them on subsequent examples.)Once you have an IEx prompt, you can enter Elixir code and you’ll see theresult. If you enter an expression that continues over more than one line, IEx
will prompt for the additional lines with an ellipsis (…).
iex(1)> 3 + 4
7iex(2)> String.reverse "madamimadam""madamimadam"iex(3)> 5 *...(3)> 630
iex(4)>The number in the prompt increments for each complete expression executed.
I’ll omit the number in most of the examples that follow.
There are several ways of exiting from IEx—none are tidy. The easiest two aretyping Ctrl - C twice or typing Ctrl - G followed by q and Return . On some systems,
you can also use a single Ctrl - \ .

• Click HERE to purchase this book now. discuss

Running Elixir • 5

IEx Helpers
IEx has a number of helper functions. Type h (followed by Return ) to get a list:iex> hIEx.Helpers
Welcome to Interactive Elixir. You are currently seeing the documentation
for the module IEx.Helpers which provides many helpers to make Elixir's
shell more joyful to work with.
This message was triggered by invoking the helper h(), usually referred toas h/0 (since it expects 0 arguments).
You can use the h/1 function to invoke the documentation for any Elixir
module or function:iex> h(Enum)iex> h(Enum.map)
iex> h(Enum.reverse/1)
You can also use the i/1 function to introspect any value you have in theshell:
iex> i("hello")
There are many other helpers available, here are some examples:
• b/1
• c/1
• c/2
• cd/1• clear/0• exports/1• flush/0
• h/0
• h/1
• i/0
• i/1
• ls/0• ls/1• open/1- prints callbacks info and docs for a given module- compiles a file into the current directory- compiles a file to the given path- changes the current directory- clears the screen- shows all exports (functions + macros) in a module- flushes all messages sent to the shell- prints this help message- prints help for the given module, function or macro- prints information about the last value- prints information about the given term
- lists the contents of the current directory- lists the contents of the specified directory- opens the source for the given module or function
in your editor• pid/1- creates a PID from a string• pid/3- creates a PID with the 3 integer arguments passed• ref/1- creates a Reference from a string• ref/4- creates a Reference with the 4 integer arguments
passed• pwd/0- prints the current working directory• r/1- recompiles the given module's source file• recompile/0- recompiles the current project• runtime_info/0 - prints runtime info (versions, memory usage, stats)• v/0- retrieves the last value from the history• v/1- retrieves the nth value from the history• Click HERE to purchase this book now. discussChapter 1. Take the Red Pill • 6
Help for all of those functions can be consulted directly from the commandline using the h/1 helper itself. Try:iex> h(v/0)
To list all IEx helpers available, which is effectively all exports(functions and macros) in the IEx.Helpers module:iex> exports(IEx.Helpers)
This module also includes helpers for debugging purposes, see IEx.break!/4
for more information.
To learn more about IEx as a whole, type h(IEx).

In the list of helper functions, the number following the slash is the numberof arguments the helper expects.
Probably the most useful is h itself. With an argument, it gives you help on
Elixir modules or individual functions in a module. This works for any modules
loaded into IEx (so when we talk about projects later on, you’ll see your own
documentation here, too). For example, the IO module performs common
input/output functions. For help on the module, type h(IO) or h IO:
iex> h IO
iex> h(IO)# or...

Functions handling IO.
Many functions in this module expect an IO device as argument. An IO device
must be a PID or an atom representing a process. For convenience, Elixir
provides :stdio and :stderr as shortcuts to Erlang's :standard_io and:standard_error....

This book frequently uses the puts function in the IO module, which in its
simplest form writes a string to the console. Let’s get the documentation:iex> h IO.puts
def puts(device \\ :stdio, item)
Writes item to the given device, similar to write/2, but adds a
newline at the end.
By default, the device is the standard output. It returns :ok if it
succeeds.
## Examples
IO.puts "Hello, World!"#=> Hello, World!
IO.puts :stderr, "error"#=> error• Click HERE to purchase this book now. discuss

Running Elixir • 7

Another informative helper is i, which displays information about a value:iex> i 123
Term
123
Data type
Integer
Reference modules
Integer
Implemented protocols
IEx.Info, Inspect, List.Chars, String.Charsiex> i "cat"
Term
"cat"
Data type
BitString
Byte size
3
Description
This is a string: a UTF-8 encoded binary. It's printed surrounded by"double quotes" because all UTF-8 encoded codepoints in it are printable.
Raw representation<<99, 97, 116>>
Reference modules
String, :binary
Implemented protocols
IEx.Info, Collectable, Inspect, List.Chars, String.Charsiex> i %{ name: "Dave", likes: "Elixir" }Term%{likes: "Elixir", name: "Dave"}
Data type
Map
Reference modules
Map
Implemented protocols
IEx.Info, Collectable, Enumerable, Inspectiex> i Map
TermMap
Data type
Atom
Module bytecodebin/../lib/elixir/ebin/Elixir.Map.beam
Sourcelib/elixir/lib/map.ex
Version[234303838320399652689109978883853316190]
Compile options[]• Click HERE to purchase this book now. discussChapter 1. Take the Red Pill • 8
Description
Use h(Map) to access its documentation.
Call Map.module_info() to access metadata.
Raw representation:"Elixir.Map"
Reference modules
Module, Atom
Implemented protocols
IEx.Info, Inspect, List.Chars, String.Chars

IEx is a surprisingly powerful tool. Use it to compile and execute entire
projects, log in to remote machines, and access running Elixir applications.
And, if you happen to include the occasional bug in your code (deliberately,of course), IEx has a simple debugger. We’ll talk about it when we look at
tooling on page ?.

Customizing iex
You can customize IEx by setting options. For example, I like showing theresults of evaluations in bright cyan. To find out how to do that, I used this:iex> h IEx.configure
def configure(options)
Configures IEx.
The supported options are: :colors, :inspect, :default_prompt,:alive_prompt and :history_size.
Colors
A keyword list that encapsulates all color settings used by the shell. See
documentation for the IO.ANSI module for the list of supported colors andattributes.
The value is a keyword list. List of supported keys:• :enabled- boolean value that allows for switching the coloringon and off• :eval_result - color for an expression's resulting value• :eval_info- … various informational messages• :eval_error- … error messages• :stack_app- … the app in stack traces• :stack_info- … the remaining info in stack traces• :ls_directory - … for directory entries (ls helper)• :ls_device- … device entries (ls helper). . .

I then created a file called .iex.exs in my home directory, containing
IEx.configure colors: [ eval_result: [ :cyan, :bright ] ]• Click HERE to purchase this book now. discuss

Running Elixir • 9

If your IEx session looks messed up (and things such as [33m appear in the
output), it’s likely your console does not support ANSI escape sequences. In
that case, disable colorization using
IEx.configure colors: [enabled: false]

You can put any Elixir code into .iex.exs.

Compile and Run
Once you tire of writing one-line programs in IEx, you’ll want to start puttingcode into source files. These files will typically have the extension .ex or .exs.
This is a convention—files ending in .ex are intended to be compiled into
bytecodes and then run, whereas those ending in .exs are more like programsin scripting languages—they are effectively interpreted at the source level.
When we come to write tests for our Elixir programs, you’ll see that theapplication files have .ex extensions, whereas the tests have .exs because we
don’t need to keep compiled versions of the tests lying around.
Let’s write the classic first program. Go to a working directory and create afile called hello.exs.
intro/hello.exs
IO.puts "Hello, World!"

That example shows how most of the code listings in this book are presented.
The bar before the code itself shows the path and file name that contains thecode. If you’re reading an ebook, you’ll be able to click on this to download
the source file. You can also download all the code by visiting the book’s pageon our site and clicking on the Source Code link.1

Source file names are written in lowercase with underscores. They will havethe extension .ex for programs that you intend to compile into binary form,
and .exs for scripts that you want to run without compiling. Our “Hello, World”
example is essentially throw-away code, so we used the .exs extension for it.

1.

http://pragprog.com/titles/elixir16• Click HERE to purchase this book now. discussChapter 1. Take the Red Pill • 10

Having created our source file, let’s run it. In the same directory where you
created the file, run the elixir command:$ elixir hello.exs
Hello, World!

We can also compile and run it inside IEx using the c helper:$ iexiex> c "hello.exs"
Hello, World!
[]iex>

The c helper compiled and executed the source file. The [] that follows theoutput is the return value of the c function—if the source file had contained
any modules, their names would have been listed here.
The c helper compiled the source file as freestanding code. You can also loada file as if you’d typed each line into IEx using import_file. In this case, local
variables set in the file are available in the IEx session.
As some folks fret over such things, the Elixir convention is to use two-column
indentation and spaces (not tabs).

Suggestions for Reading the Book
This book is not a top-to-bottom reference guide to Elixir. Instead, it isintended to give you enough information to know what questions to ask andwhen to ask them. So approach what follows with a spirit of adventure. Try
the code as you read, and don’t stop there. Ask yourself questions and thentry to answer them, either by coding or by searching the web.
Participate in the book’s discussion forums and consider joining the Elixir
mailing list.2
You’re joining the Elixir community while it is still young. Things are exciting
and dynamic, and there are plenty of opportunities to contribute.

Exercises
You’ll find exercises sprinkled throughout this book. To become familiar witha language, you need to go beyond reading a book and following along withthe examples; you need to write some code yourself. These exercises are2.

https://elixirforum.com• Click HERE to purchase this book now. discussThink Different(ly) • 11

starting points so you can do some exploring of the language. Try them out,
and don’t be afraid to make mistakes.

Think Different(ly)This is a book about thinking differently—about accepting that some of thethings folks say about programming may not be the full story:• Object orientation is not the only way to design code.
• Functional programming need not be complex or mathematical.
• The bases of programming are not assignments, if statements, and loops.
• Concurrency does not need locks, semaphores, monitors, and the like.
• Processes are not necessarily expensive resources.
• Metaprogramming is not just something tacked onto a language.
• Even if it is work, programming should be fun.
Of course, I’m not saying Elixir is a magic potion (well, technically it is, but
you know what I mean). It isn’t the one true way to write code. But it’s different
enough from the mainstream that learning it will give you more perspective
and will open your mind to new ways of thinking about programming.
So let’s start.
And remember to make it fun.

• Click HERE to purchase this book now. discuss