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, but get them right without all the locking and consistency headaches. Meet Elixir, a modern, functional, concurrent language built on the rock-solid Erlang VM. Elixir’s pragmatic syntax and built-in support for metaprogramming will make you productive and keep you interested for the long haul. Maybe the time is right for the Next Big Thing. Maybe it’s Elixir.
Programming Elixir 1.6: Functional |> Concurrent |> Pragmatic |> Fun
by Dave Thomas
Programming Elixir 1.6
Functional |> Concurrent |> Pragmatic |> Fun
by Dave Thomas
Free ebook of Programming Elixir ≥ 1.6 for Educational Domains
If you have a pragprog.com account with a valid email address ending in .edu, you can use coupon code elixir2sFMhJN to get a free ebook of Programming Elixir ≥ 1.6.
Help us get the word out. Tell all of your friends in the .edu world about Elixir. Forward them this newsletter, text them, even call them if you’re feeling retro.
International domains: In addition to .edu in the US, the offer is valid for additional educational domains in other countries. Check the promotions page for the full list.
About this Title
Release: P1.0 (2018-05-17)
Functional programming techniques help you manage the complexities of today’s real-world, concurrent systems; maximize uptime; and manage security. Enter Elixir, with its modern, Ruby-like, extendable syntax, compile and runtime evaluation, hygienic macro system, and more. But, just as importantly, Elixir brings a sense of enjoyment to parallel, functional programming. Your applications become fun to work with, and the language encourages you to experiment.
Part 1 covers the basics of writing sequential Elixir programs. We’ll look at the language, the tools, and the conventions. Part 2 uses these skills to start writing concurrent code—applications that use all the cores on your machine, or all the machines on your network! And we do it both with and without OTP. Part 3 looks at the more advanced features of the language, from DSLs and code generation to extending the syntax.
This edition is fully updated with all the new features of Elixir 1.6, with a new chapter on structuring OTP applications, and new sections on the debugger, code formatter, Distillery, and protocols.
Interview with Dave Thomas:
It’s been a while since the last revision of this book. Why a new edition now?
I guess it’s been almost 3 years. I’ve resisted doing another edition because not much has actually changed in the core language. There’ve been a few deprecations, and a bunch of new functions, but almost all the code in the 1.3 version of the book runs just fine on Elixir 1.6.
But… it has been 3 years. And during that time the Elixir community has gained a lot of experience. Although the language is pretty stable, the way we use it has become more sophisticated. That’s what triggered me to update the book: I wanted to show some of those new ideas.
Can you give an example?
Let’s look at one of the core components of the Elixir runtime, the GenServer module. This comes from Erlang, and in the past we designed Elixir GenServers just about the same way the Erlang folks did (although the implementations were a lot simpler). But we’ve moved on from that. Elixir has new ways of specifying the supervisors for servers, and new convenience servers such as Agents and Tasks. The result is that idiomatic Elixir has moved on quite a lot. I ended up writing a new chapter, and substantially changing two others, to reflect these new (and better) styles.
In the past, you said that developers should learn Elixir because it teaches them a new way of thinking about code. Do you still feel the same way?
Yes and no. I think that reason is still valid. Apple just shipped an 18 core iMac. Servers with 64 and 128 cores are in the works. You need to find reliable and manageable ways to write code for these beasts. I still firmly believe that functional programming is the key technology to make this happen. On top of that, the actor model seems to be the best way to communicate between processes. And Elixir is both a functional language and it has a runtime library based on the actor model that has been battle tested for decades.
But now I give a second reason why developers should learn Elixir: there’s a well-paying and expanding job market for Elixir developers. It’s a skill that’s in short supply, and this is a great time to join in.
What do you see in the future of Elixir?
I’m more and more convinced that the browser will not be the dominant way we interact with the internet in the (near term) future. You can already see the growth of alternatives: mobile apps, smart devices, and even things like Alexa and Google Home. As computer power becomes ambient, we’ll need technologies that let us deal with this dynamic, long-running, and fault-resistant world. I think Elixir has a big part to play in this.
Already we have the Nerves project, which lets you burn your Elixir applications into free standing images which will boot on devices such as the Raspberry Pi Zero. That’s a $10 processor with WiFi, lots of I/O, and a full Elixir and Erlang runtime. I made a touch sensitive xylophone that uses pubsub to communicate over the ’net with synthesizers running on desktops, both client and server in Elixir.
And that brings me to the second revolution. Elixir has a framework called Phoenix. Unfortunately, people see it as some kind of Rails replacement. But Phoenix is way more than that. Phoenix is a connectivity framework. If it connects to the ‘net, Phoenix can talk to it, switch traffic to and from it, and manage it. It’s a natural for driving millions of IoT devices from a single server.
So I see the future of Elixir as being the future of software. And it sounds like fun.
By the end of this book, you’ll understand Elixir, and know how to
apply it to solve your complex, modern problems.
What You Need
You’ll need a computer, a little experience with another high-level
language, and a sense of adventure. No functional programming
experience is needed.
Contents & Extracts
- Conventional Programming
- Pattern Matching
- Assignment: I Do Not Think It Means What You Think It Means.
- More Complex Matches
- Ignoring a Value with _ (Underscore)
- Variables Bind Once (per Match)
- Another Way of Looking at the Equals Sign
- You Already Have (Some) Immutable Data
- Immutable Data Is Known Data
- Performance Implications of Immutability
- Coding with Immutable Data
- Elixir Basics
- Built-in Types
- Value Types
- System Types
- Collection Types
- Dates and Times
- Names, Source Files, Conventions, Operators, and So On
- Variable Scope
- End of the Basics
- Anonymous Functions
- Functions and Pattern Matching
- One Function, Multiple Bodies
- Functions Can Return Functions
- Passing Functions as Arguments
- Functions Are the Core
- Modules and Named Functions
- Compiling a Module
- The Function’s Body Is a Block
- Function Calls and Pattern Matching
- Guard Clauses
- Default Parameters
- Private Functions
- The Amazing Pipe Operator: |>
- Module Attributes
- Module Names: Elixir, Erlang, and Atoms
- Calling a Function in an Erlang Library
- Finding Libraries
- Lists and Recursion excerpt
- Heads and Tails
- Using Head and Tail to Process a List
- Using Head and Tail to Build a List
- Creating a Map Function
- Reducing a List to a Single Value
- More Complex List Patterns
- The List Module in Action
- Get Friendly with Lists
- Maps, Keyword Lists, Sets, and Structs
- How to Choose Between Maps, Structs, and Keyword Lists
- Keyword Lists
- Pattern Matching and Updating Maps
- Updating a Map
- Nested Dictionary Structures
- With Great Power Comes Great Temptation
- An Aside—What Are Types?
- Processing Collections—Enum and Stream
- Enum—Processing Collections
- Streams—Lazy Enumerables
- The Collectable Protocol
- Moving Past Divinity
- Strings and Binaries
- String Literals
- The Name “strings”
- Single-Quoted Strings—Lists of Character Codes
- Double-Quoted Strings Are Binaries
- Binaries and Pattern Matching
- Familiar Yet Strange
- Control Flow
- if and unless
- Raising Exceptions
- Designing with Exceptions
- Doing More with Less
- Organizing a Project
- The Project: Fetch Issues from GitHub
- Step 1: Use Mix to Create Our New Project
- Transformation: Parse the Command Line
- Write Some Basic Tests
- Refactor: Big Function Alert
- Transformation: Fetch from GitHub
- Step 2: Use Libraries
- Transformation: Convert Response
- Transformation: Sort Data
- Transformation: Take First n Items
- Transformation: Format the Table
- Step 3: Make a Command-Line Executable
- Step 4: Add Some Logging
- Step 5: Create Project Documentation
- Coding by Transforming Data
- Tooling excerpt
- Debugging with IEx
- Code Dependencies
- Server Monitoring
- Source-Code Formatting
- Inevitably, There’s More
- Pattern Matching
- Concurrent Programming
- Working with Multiple Processes
- A Simple Process
- Process Overhead
- When Processes Die
- Parallel Map—The “Hello, World” of Erlang
- A Fibonacci Server
- Agents—A Teaser
- Thinking in Processes
- Nodes—The Key to Distributing Services
- Naming Nodes
- Naming Your Processes
- Input, Output, PIDs, and Nodes
- Nodes Are the Basis of Distribution
- OTP: Servers
- Some OTP Definitions
- An OTP Server
- GenServer Callbacks
- Naming a Process
- Tidying Up the Interface
- Making Our Server into a Component
- OTP: Supervisors
- Supervisors and Workers
- Worker Restart Options
- Supervisors Are the Heart of Reliability
- A More Complex Example
- Introduction to Duper
- The Duper Application
- But Does It Work?
- Planning Your Elixir Application
- Next Up
- OTP: Applications
- This Is Not Your Father’s Application
- The Application Specification File
- Turning Our Sequence Program into an OTP Application
- Supervision Is the Basis of Reliability
- Releasing Your Code
- Distillery—The Elixir Release Manager
- OTP Is Big—Unbelievably Big
- Tasks and Agents
- A Bigger Example
- Agents and Tasks, or GenServer?
- Working with Multiple Processes
- More Advanced Elixir
- Macros and Code Evaluation
- Implementing an if Statement
- Macros Inject Code
- Using the Representation as Code
- Using Bindings to Inject Values
- Macros Are Hygienic
- Other Ways to Run Code Fragments
- Macros and Operators
- Digging Deeper
- Digging Ridiculously Deep
- Linking Modules: Behavio(u)rs and use
- use and using
- Putting It Together—Tracing Method Calls
- Use use
- Protocols—Polymorphic Functions
- Defining a Protocol
- Implementing a Protocol
- The Available Types
- Protocols and Structs
- Built-in Protocols
- Protocols Are Polymorphism
- More Cool Stuff
- Writing Your Own Sigils
- Multi-app Umbrella Projects
- But Wait! There’s More!
- Macros and Code Evaluation
Dave Thomas is a programmer who likes to evangelize cool stuff. He cowrote The Pragmatic Programmer, and was one of the creators of the Manifesto for Agile Software Development. His book Programming Ruby introduced the Ruby language to the world, and Agile Web Development with Rails helped kickstart the Rails revolution.