Intro to Elixir

by @tednaleid

Intro to Elixir

by @tednaleid

Quick Background

Why should you spend time with Elixir?

Linguistic Relativity

(AKA Sapir-Whorf Hypothesis)
"The structure of a language affects the way in which its respective speakers conceptualize their world." - wikipedia

Covers: Ruby, Io, Prolog, Scala, Erlang, Clojure, Haskell

The Free Lunch is Over

Used 5 criteria to determine the language to use

Natural Syntax

Fast and Repeatable Dev Cycle

Concurrent and Fast


Failure Management

Short List Choice #1: Ruby + $$$

Natural Syntax, Fast and Repeatable Dev Cycle, Metaprogramming

Concurrent and Fast, Failure Management

Short List Choice #2: Erlang

Failure Management, Concurrent and Fast

Natural Syntax, Fast and Repeatable Dev Cycle, Metaprogramming

Short List Choice #3: Clojure

Concurrent and Fast, Metaprogramming, Fast & Repeatable Dev Cycle

Failure Management

Natural Syntax

Met José, Found Elixir

"Twisted Love Child of all 3 options"

What is Elixir?

Mostly immutable, functional language with ruby-like syntax running on the battle-tested Erlang BEAM VM

What is Erlang/BEAM?

Language + VM, Created by Ericsson in 1986 to support distributed, fault-tolerant, always-up systems

How does Elixir satisfy 5 criteria?

1. Natural Syntax

Comfortable for most programmers, heavy weighting on quick parsing & readability

Feels Rubyish

Basic Types

iex> my_utf8_string = "hello Iñtërnâtiônàlizætiøn"
"hello Iñtërnâtiônàlizætiøn"
iex> my_atom = :hello
iex> 1000 == 1_000
iex> 0.314159e1 == 314159.0e-5
iex> my_range = 1..5

Tuples, Lists, Maps

iex> my_tuple = {:ok, "return value", 715}
{:ok, "return value", 715}
iex> my_list = [1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
iex> my_map = %{:first => "Ted", :last => "Naleid"}
%{first: "Ted", last: "Naleid"}


iex> sum = fn a, b -> a + b end
#Function<12.90072148/2 in :erl_eval.expr/5>
iex> sum.(1, 2)
# shortened closure syntax:
iex> short_sum = &(&1 + &2)
iex> short_sum.(1, 2)


iex> defmodule Person do
...>   defstruct first: "Ted", last: "Naleid"
...> end
{:module, Person, …}
iex> %Person{}
%Person{first: "Ted", last: "Naleid"}
iex> %Person{first: "Hazel"}
%Person{first: "Hazel", last: "Naleid"}
iex> %Person{nope: "Bad Field"}
** (CompileError) iex:4: unknown key :nope for struct


iex> defprotocol Stringable do
...>   def to_string(value)
...> end
iex> defimpl Stringable, for: Person do
...>   def to_string(value) do
...>     "#{value.first} #{value.last}"
...>   end
...> end
iex> Stringable.to_string(%Person{})
"Ted Naleid"

Some similarities to an OOP Interface

Pattern Matching

iex> a = {:ok, 1}
{:ok, 1}  
iex> {:ok, b} = {:ok, 1}
{:ok, 1}
iex> b

Pattern Matching Lists

iex> [a, b, c] = [1, 2, 3]
[1, 2, 3]
iex> a
iex> [head | tail] = [1, 2, 3]
[1, 2, 3]
iex> head
iex> tail
[2, 3]

Pattern Matching Structs

case HTTP.get(url) do
  {:ok, %HTTP.Resp{ status: 200, body: body }} ->
    IO.puts body
  {:ok, %HTTP.Resp{ status: 404 }} ->
    IO.puts "Not found :("
  {:ok, %HTTP.Resp{ status: status }} ->
    IO.puts "HTTP Status: #{status}"
  {:error, %HTTP.Error{ reason: reason }} ->
    IO.inspect reason
  _ ->
    IO.puts "¯\_(ツ)_/¯"

Even More Pattern Matching

def execute({:ok, good_value}) do
  IO.puts "Known good value: #{good_value}"
def execute({:error, error_reason}) do
  IO.puts "Error! #{error_reason}"
iex> execute({:ok, "Yay!"})
Known good value: Yay!
iex> execute({:error, "Boo!"})
Error! Boo!

Pipe Operator |>

defmodule Shop do
  defp apply_tax(prices) do, fn v -> v * 1.1 end)
  def cart_total(items) do
      apply_tax(, fn item -> item.price end)))
Shop.cart_total([%{:price=>5.00}, %{:price=>2.00}])
# => 7.7

Nested cart_total is hard to read, have to read inside out

Pipe Operator |>

  def cart_total(items) do
    prices =, fn itm -> itm.price end)
    prices_with_tax = apply_tax(prices)

Intermediate variables cleans up a bit

Pipe Operator |>

def cart_total(items) do
  |> item -> item.price end)
  |> add_tax
  |> Enum.sum

|> operator passes result from last method as first param in next

Similar to unix pipe: ps ax | grep iex | awk '{ print $1 }'

Simple Interop with Erlang

iex> :crypto.md5("sekr1t")
<<192, 151, 240, 131, 252, 86, 1, 90, 71, 171, 2, …

Can easily leverage 20+ years of Erlang libraries

2. Fast & Repeatable Dev Cycle


Very Testable, Easy to Parallelize, No Side Effects

Hot Reloading Without Restarting

Mix Build Tool

$ mix new myapp
* creating
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/myapp.ex
* creating test
* creating test/test_helper.exs
* creating test/myapp_test.exs
Your mix project was created successfully.
You can use mix to compile it, test it, and more:
    cd myapp
    mix test
Run `mix help` for more commands.

Hex Package Manager

defmodule MyProject.Mixfile do
  use Mix.Project
  def project do
    [app: :myapp,
     version: "0.0.1",
     elixir: "~> 1.0",
     deps: deps]
  def application do
    [applications: [:logger]]
  defp deps do
    [{:ecto, "~> 0.11.3"},
     {:postgrex, "~> 0.8.1"},
     {:cowboy, github: "extend/cowboy"}]

iex is a Great REPL

iex> h<tab>
map/2           map_join/3      map_reduce/3
iex> h
                            def map(collection, fun)
Returns a new collection, where each item is the result of invoking fun 
on each corresponding item of collection.
For dicts, the function expects a key-value tuple.
┃ iex>[1, 2, 3], fn(x) -> x * 2 end)
┃ [2, 4, 6]

┃ iex>[a: 1, b: 2], fn({k, v}) -> {k, -v} end)
┃ [a: -1, b: -2]

Debugging via pry

require IEx
def index(conn, _params) do
  conn |> render "index"

Similar to the JavaScript debugger; command

Erlang Activity Monitor

iex> :observer.start

Quick Demo

3. Metaprogramming

How expressive can you make your code

Hygenic Macros

defmacro unless(expr, opts) do
  quote do
    if(!unquote(expr), unquote(opts))
unless true do
  IO.puts "this will never be seen"

Most of the standard library is written using macros

Easy Access to AST

iex> ast = quote, do 2 * 2 / 7
{:/,[context: Elixir, import: Kernel],
 [{:*,[context: Elixir, import: Kernel], [2, 2]}, 7]}

Underlying AST looks a bit like a lisp

Full discussion bigger than this presentation, check out "Metaprogramming Elixir", by Chris McCord

4. Concurrent & Fast

WhatsApp Runs On Erlang VM

At time of Facebook acquisition for $19 Billion

10 Developers

Great Single-Box Scalability

Often 100's of thousands to millions of processes per machine
~2KB of stack/heap per thread on Single 512MB Heroku Dyno

(~0.15 load, from

Concurrency Built-in

iex> parent = self()
iex> spawn(fn -> send parent, "hello world" end)
iex> receive do message -> IO.puts message end
hello world

Isolation/Immutability Allows Garbage Collection at Process Level

No big garbage collection pauses

5. Failure Management

OTP Apps are Supervision Trees

Supervisors monitor/start/stop Child Workers/Supervisors

Elixir/OTP motto: "Let it Crash"

Most Languages Littered with
Defensive Programming

Miss an edge case and your app crashes
ex: Goroutines aren't memory isolated…one dying takes down entire process

Better Architecture -> Cleaner Code

Exception handling is rare

Other Reasons for Picking Elixir

Phoenix Framework

Elixir killer app; most developers weren't interested in
Ruby till Rails & Groovy till Grails

Great, Growing Community

Hex Downloads (from @emjii on 2015-06-24)

Solid Documentation

Elixir's Strengths

Apps with many connections & high uptime requirements

(i.e. Internet of Things, REST/socket webservices, Mobile App back-end, Telephony)

Elixir Weaknesses

Significant Graphics/GUI or Sequential Math

There are better languages for the next Doom or Bitcoin mining

"Three Major Hurdles to Learning"

(from Francesco Cesarini, founder of Erlang Solutions)

1. Functional Programming

Pattern Matching and Tail Recursion

2. Thinking/Reasoning Concurrently

Have a process for every truly concurrent activity in your system

3. Understanding Fault Tolerance and 'Let it Crash' Mentality

The Pragmatic Programmer

"Learn at least one new language every year"

Don't make it one that's the same paradigms that you already know.

That's learning syntax, not better programming

Getting Started

Programming Elixir

Notice the author?

Elixir in Action

Released in June 2015

#elixir-lang on Freenode IRC

Follow @ElixirMN and @elixirlang