Table Of ContentProgramming 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 in
initial capital letters or in all capitals. The Pragmatic Starter Kit, The Pragmatic Programmer,
Pragmatic Programming, Pragmatic Bookshelf, PragProg and the linking g device are trade-
marks 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
Contents
Foreword . . . . . . . . . . . . . . ix
A Vain Attempt at a Justification, Take Two . . . . . xi
1. Take the Red Pill . . . . . . . . . . . . 1
Programming Should Be About Transforming Data 1
Installing Elixir 3
Running Elixir 4
Suggestions for Reading the Book 10
Exercises 10
Think Different(ly) 11
Part I — Conventional Programming
2. Pattern Matching . . . . . . . . . . . 15
Assignment: I Do Not Think It Means What You Think
It Means. 15
More Complex Matches 16
Ignoring a Value with _ (Underscore) 18
Variables Bind Once (per Match) 18
Another Way of Looking at the Equals Sign 20
3. Immutability . . . . . . . . . . . . 21
You Already Have (Some) Immutable Data 21
Immutable Data Is Known Data 22
Performance Implications of Immutability 23
Coding with Immutable Data 24
4. Elixir Basics . . . . . . . . . . . . . 25
Built-in Types 25
Value Types 26
Contents • iv
System Types 28
Collection Types 28
Maps 31
Binaries 32
Dates and Times 33
Names, Source Files, Conventions, Operators, and So On 34
Variable Scope 36
End of the Basics 40
5. Anonymous Functions . . . . . . . . . . 41
Functions and Pattern Matching 42
One Function, Multiple Bodies 43
Functions Can Return Functions 45
Passing Functions as Arguments 47
Functions Are the Core 51
6. Modules and Named Functions . . . . . . . . 53
Compiling a Module 53
The Function’s Body Is a Block 54
Function Calls and Pattern Matching 55
Guard Clauses 58
Default Parameters 60
Private Functions 63
The Amazing Pipe Operator: |> 63
Modules 65
Module Attributes 67
Module Names: Elixir, Erlang, and Atoms 68
Calling a Function in an Erlang Library 69
Finding Libraries 69
7. Lists and Recursion . . . . . . . . . . . 71
Heads and Tails 71
Using Head and Tail to Process a List 72
Using Head and Tail to Build a List 74
Creating a Map Function 75
Reducing a List to a Single Value 76
More Complex List Patterns 78
The List Module in Action 81
Get Friendly with Lists 82
Contents • v
8. Maps, Keyword Lists, Sets, and Structs . . . . . . 83
How to Choose Between Maps, Structs, and Keyword Lists 83
Keyword Lists 84
Maps 84
Pattern Matching and Updating Maps 85
Updating a Map 87
Structs 88
Nested Dictionary Structures 89
Sets 95
With Great Power Comes Great Temptation 95
9. An Aside—What Are Types? . . . . . . . . . 97
10. Processing Collections—Enum and Stream . . . . . 99
Enum—Processing Collections 99
Streams—Lazy Enumerables 103
The Collectable Protocol 110
Comprehensions 111
Moving Past Divinity 114
11. Strings and Binaries . . . . . . . . . . 117
String Literals 117
The Name “strings” 120
Single-Quoted Strings—Lists of Character Codes 121
Binaries 123
Double-Quoted Strings Are Binaries 124
Binaries and Pattern Matching 130
Familiar Yet Strange 132
12. Control Flow . . . . . . . . . . . . 133
if and unless 133
cond 134
case 137
Raising Exceptions 138
Designing with Exceptions 138
Doing More with Less 139
13. Organizing a Project . . . . . . . . . . 141
The Project: Fetch Issues from GitHub 141
Step 1: Use Mix to Create Our New Project 142
Transformation: Parse the Command Line 145
Write Some Basic Tests 146
Contents • vi
Refactor: Big Function Alert 149
Transformation: Fetch from GitHub 149
Step 2: Use Libraries 151
Transformation: Convert Response 156
Transformation: Sort Data 158
Transformation: Take First n Items 159
Transformation: Format the Table 160
Step 3: Make a Command-Line Executable 163
Step 4: Add Some Logging 164
Step 5: Create Project Documentation 166
Coding by Transforming Data 167
14. Tooling . . . . . . . . . . . . . 169
Debugging with IEx 169
Testing 173
Code Dependencies 186
Server Monitoring 187
Source-Code Formatting 190
Inevitably, There’s More 193
Part II — Concurrent Programming
15. Working with Multiple Processes . . . . . . . 197
A Simple Process 198
Process Overhead 203
When Processes Die 206
Parallel Map—The “Hello, World” of Erlang 210
A Fibonacci Server 211
Agents—A Teaser 215
Thinking in Processes 216
16. Nodes—The Key to Distributing Services . . . . . 219
Naming Nodes 219
Naming Your Processes 223
Input, Output, PIDs, and Nodes 226
Nodes Are the Basis of Distribution 228
17. OTP: Servers . . . . . . . . . . . . 229
Some OTP Definitions 229
An OTP Server 230
GenServer Callbacks 238
Contents • vii
Naming a Process 240
Tidying Up the Interface 240
Making Our Server into a Component 242
18. OTP: Supervisors . . . . . . . . . . . 247
Supervisors and Workers 247
Worker Restart Options 254
Supervisors Are the Heart of Reliability 255
19. A More Complex Example . . . . . . . . . 257
Introduction to Duper 257
The Duper Application 262
But Does It Work? 272
Planning Your Elixir Application 274
Next Up 275
20. OTP: Applications . . . . . . . . . . . 277
This Is Not Your Father’s Application 277
The Application Specification File 278
Turning Our Sequence Program into an OTP Application 278
Supervision Is the Basis of Reliability 281
Releasing Your Code 282
Distillery—The Elixir Release Manager 282
OTP Is Big—Unbelievably Big 292
21. Tasks and Agents . . . . . . . . . . . 293
Tasks 293
Agents 295
A Bigger Example 297
Agents and Tasks, or GenServer? 300
Part III — More Advanced Elixir
22. Macros and Code Evaluation . . . . . . . . 303
Implementing an if Statement 303
Macros Inject Code 304
Using the Representation as Code 307
Using Bindings to Inject Values 312
Macros Are Hygienic 313
Other Ways to Run Code Fragments 314
Macros and Operators 315
Contents • viii
Digging Deeper 316
Digging Ridiculously Deep 316
23. Linking Modules: Behavio(u)rs and use . . . . . . 319
Behaviours 319
use and __using__ 322
Putting It Together—Tracing Method Calls 322
Use use 326
24. Protocols—Polymorphic Functions . . . . . . . 329
Defining a Protocol 329
Implementing a Protocol 330
The Available Types 331
Protocols and Structs 332
Built-in Protocols 333
Protocols Are Polymorphism 345
25. More Cool Stuff . . . . . . . . . . . 347
Writing Your Own Sigils 347
Multi-app Umbrella Projects 351
But Wait! There’s More! 354
A1. Exceptions: raise and try, catch and throw . . . . . 355
Raising an Exception 355
catch, exit, and throw 357
Defining Your Own Exceptions 358
Now Ignore This Appendix 359
A2. Type Specifications and Type Checking . . . . . . 361
When Specifications Are Used 361
Specifying a Type 362
Defining New Types 364
Specs for Functions and Callbacks 365
Using Dialyzer 366
Bibliography . . . . . . . . . . . . 373
Index . . . . . . . . . . . . . . 375
Description:This book is the introduction to Elixir for experienced programmers, completely updated for Elixir 1.6 and beyond. Explore functional programming without the academic overtones (tell me about monads just one more time). Create concurrent applications, butget them right without all the locking and co