Why Elixir? &
Getting Started
Elixir (and Functional JS) is Gaining Traction

Elixir - April 2016: Assess → November 2016: Trial
Phoenix - First Appearance → November 2016: Trial
It's Fast

Websocket Client Concurrency Performance

Web Framework Performance
It's a Readable Functional Language
object HelloWorld {
def main(args: Array[String]) {
println("Hello, world!")
}
}Scala
module Main where
main = putStrLn "Hello, World!"Haskell
fn main() {
println!("Hello World!");
}Rust
(ns helloworld.core)
(defn -main []
"I can say 'Hello World'."
(println "Hello, World!"))Clojure
defmodule HelloWorld do
def hello do
IO.puts "Hello World"
end
endElixir
The Ruby → Elixir Migration?

It's heavily inspired by Ruby.
The Ruby → Elixir Migration?
- Plaformatec, creators of the popular Ruby gems, Devise and Simple Form, back/created Elixir.
-
Jose Valim, creator of Elixir, is a former core team member of Ruby on Rails.
-
Chris McCord, creator of the Phoenix framework, was hired by Dockyard in Oct. 2015, when they dropped RoR to go full-on Elixir, Phoenix, and Ember.
- Thoughtbot, creators of Ruby gems Paperclip and Factory Girl, are also adopting it and heading up new open-source efforts (Hex Packages Bamboo and ExMachina).
It's Great For Artificial Neural Networks and Deep Learning

# Create nodes
neuron = Neuron.start_node(bias: 10, activation_function: function(identity/1))
sensor = Sensor.start_node(sync_function: fake_sensor_data([[1, 1, 1, 1, 1]]))
actuator = Actuator.start_node([])
# Wire up network
connect(from: sensor, to: neuron, weights: [20, 20, 20, 20, 20])
connect(from: neuron, to: actuator)
# tap into actuator for testing purposes
NodeProcess.add_outbound_connection(actuator, self())
# feed input into sensor
NodeProcess.sync(sensor)
# verify actuator output
assert actuator_next_output() == 110Paradigms
- Functional
- Concurrent
- Dynamic
- Fast, Elegant, and Fun
- 6 years young
- Built on Erlang (31 years young)
Familiar Concepts
| Name | Example | Kind of Like |
|---|---|---|
| Atom | :foo | Symbols in Ruby |
| Lists | [:item, 30, "hat"] | Arrays |
| Tuples | {:ok, "It the was the best of times..."} | Objects + Pointers (stored contiguously) |
| Maps | %{:first => "Bob", :last => "Barker} | Objects, Key-Value Stores |
| Keyword Lists | [age: 40, gender: "F"] | [{:age, 40}, {:gender, "F"}] |
Exciting Concepts
- Pattern Matching
- First-Class Functions
- Closures
- Pipelines
- First-Class Documentation
- First-Class Testing
- Erlang Concurrency
- Phoenix Framework
Pattern Matching
# The equal sign is a Match Operator
# It binds when empty
iex> x = 1
1
# It fails on mismatches
iex> 2 = x
** (MatchError) no match of right hand side value: 1
# It can match simple values, data structures, and functions
iex> {:ok, result} = {:ok, 13}
{:ok, 13}
iex> result
13
First-Class Functions
iex> greeter = fn -> "Hey Buddy" end
#Function<20.52032458/0 in :erl_eval.expr/5>
iex> greeter.()
"Hey Buddy"Functions can be assigned to variables
iex> apply.(minus_2,6)
4Functions can be passed to other functions
First-Class Functions
Functions can return functions
inception_greeter = fn ->
fn ->
"Hiya"
end
end
#Function<20.52032458/0 in :erl_eval.expr/5>
iex> inception_greeter.()
#Function<20.52032458/0 in :erl_eval.expr/5>
iex> greeter = inception_greeter.()
#Function<20.52032458/0 in :erl_eval.expr/5>
iex> greeter.() # in other words, inception_greeter.().()
"Hiya"First-Class Functions
name_greeter = fn name ->
fn ->
"Hiya #{name}!"
end
end
#Function<20.52032458/0 in :erl_eval.expr/5>
iex> tiff_greeter = name_greeter.("Tiff") # 'name' argument passed to outer function
#Function<20.52032458/0 in :erl_eval.expr/5>
iex> tiff_greeter.() # inner function uses 'name' argument from outer function argument
"Hiya Tiff!"Functions carry with them the bindings of variables in the scope they're defined (closures).
First-Class Functions
It's a modern, functional language! Huge libraries of functions are built-in and the convention is to use them.
First-Class Functions
Pipelines!
people = DB.find_customers
orders = Order.for_customers(people)
tax = sales_tax(orders, 2016)
filing = prepare_filing(tax)filing = DB.find_customers
|> Orders.for_customers
|> sales_tax(2016)
|> prepare_filing

→
First-Class Documentation
defmodule Butler.Tableflip do
@moduledoc """
Flip some tables
"""
use Butler.Plugin
@usage """
tableflip - replies with a flipped table
"""
def flip_table do
:random.seed(:os.timestamp)
table_list = [
"(╯°□°)╯︵ ┻━┻",
"(╯°□°)╯︵ <ǝlqɐʇ>",
"the table flipped you! ノ┬─┬ノ ︵ ( \o°o)\ ",
"┻━┻ ︵ヽ(`Д´)ノ︵ ┻━┻"
]
Enum.random(table_list)
end
hear ~r/tableflip/, conn do
reply conn, flip_table
end
endFirst-Class Documentation
Concurrency & Erlang
| OS Threads | OS Processes | Green Threads | Erlang Processes |
|---|---|---|---|
| - Uses shared memory - Runs on separate CPUs - Do not block each other |
- Uses separate sections of memory - Expensive, e.g. requires different instances of app |
- Scheduled by a VM, e.g. Java, Ruby - Not always true parallelism - a blocking I/O operation can bottleneck all green threads |
- No shared state due to immutable data - Processes can be truly parallel / multiplex on processors - One process can fail and leave others untouched - Dynamically allocates memory |
Erlang Concurrency
Actor
PID <0.30.0>
Actor
PID <0.30.1>
Mailbox
Mailbox
Text
MSG
MSG
Supervisor
Text
iex > :observer.start
Learning Resources
Books
- Programming Elixir
- Programming Phoenix
- Elixir in Action
- Elixir Cookbook
Screencasts
- ElixirConf 2014
- ElixirSips
- LearnElixir.tv
- LearnPhoenix.tv
Exercises
- Elixir Koans
- Exercism
- 30 Days of Elixir - Katas
- Elixir Quiz
Newsletters
- Elixir Radar
- Functional Elixir
More...
- Elixir Fountain Podcasts
- Elixir Nation
- Udemy Elixir & Phoenix Bootcamp
- Elixir Radar
- Functional Elixir
- Elixir School
Why Elixir? & Getting Started - for Vermonster Talks & Picks
By Rachael Serur
Why Elixir? & Getting Started - for Vermonster Talks & Picks
- 272