Leszek Zalewski
Overview & history
Language basics
Erlang VM
OTP
Extras
Summary
iex> 1 # integer
iex> 0x1F # integer
iex> 1.0 # float
iex> true # boolean
iex> :atom # atom / symbol
iex> "elixir" # string
iex> <<104, 101, 108, 108, 111, 0>> # binary
iex> fn a, b -> a + b end # function
iex> [1, 2, 3] # list
iex> {1, 2, 3} # tuple (fixed size array)
iex> %{"foo" => "bar", "baz" => 2} # hash map
# Modules & Structs
defmodule Person do
defstruct name: "", age: nil
end
iex> %Person{name: "John", age: 67}
iex> x = "foo"
"foo"
iex> "foo" = x # WAT!?
"foo"
iex> x = "bar"
"bar"
iex> ^x = "baz"
** (MatchError) no match of right hand side value: "baz"
iex> [color] = ["red"]
["red"]
iex> color
"red"
case call_api() do
# pattern match against Response struct with status code 200,
# extract body from the struct
{:ok, %Response{status_code: 200, body: body}} ->
{:ok, body}
# pattern match against Response struct with status code 404
# return normalized error
{:ok, %Response{status_code: 404}} ->
{:error, :not_found}
# catch all
msg ->
msg |> inspect() |> Logger.error()
{:error, :panic}
end
defmodule Person do
defstruct name: "", age: nil
def introduce(%Person{name: name, age: age}) do
"Hi, my name is #{name} and I'm #{age} years old"
end
end
iex> john = %Person{name: "John", age: 67}
%Person{name: "John", age: 67}
iex> Person.introduce(john)
"Hi, my name is John and I'm 67 years old"
defmodule Person do
defstruct age: nil
def complain(%Person{age: age}) when is_number(age) and age > 60 do
"Im too old for this crud"
end
def complain(_) do
"Not again!"
end
end
iex> Person.complain(%Person{age: 67})
"I'm too old for this crud"
iex> Person.complain(%Person{age: 50})
"Not again!"
defmodule Recursion do
# pattern matching against empty list
def print_list([]) do
end
# pattern matching against head and tail
def print_list([head | tail]) do
head |> inspect |> IO.puts
print_list(tail)
end
end
iex> Recursion.print_list([1, 2, 3])
1
2
3
nil
# Eager `Enum` module
iex> Enum.map([1, 2, 3], fn x -> x * 2 end)
[2, 4, 6]
iex> Enum.map(%{1 => 2, 3 => 4}, fn {k, v} -> k * v end)
[2, 12]
# each operation is going to generate
# an intermediate list until we reach the result
#
1..100_000
|> Enum.map(&(&1 * 3)) # fn x -> x * 3 end
|> Enum.filter(&(rem(&1, 2) != 0)) # fn x -> rem(x, 2) != 0 end
|> Enum.sum
7500000000
# operations are delayed till final result is requested
#
1..100_000
|> Stream.map(&(&1 * 3)) # fn x -> x * 3 end
|> Stream.filter(&(rem(&1, 2) != 0)) # fn x -> rem(x, 2) != 0 end
|> Enum.sum
7500000000
spawn(fn ->
IO.puts("neat!")
end)
spawn_link(fn ->
raise("Ops!")
end)
pid = spawn(fn ->
:timer.sleep(10_000)
raise("Ops!")
end)
Process.monitor(pid)
Basic process, when it crashes, parent process stays alive
Linked process, when it crashes, parent process dies as well
Monitored process, when crashed,
the parent process will be notified about it
Mailbox
Memory / State
Computation
Process
Lightweight compared to processes and threads in other languages
Communication happens only via message passing
Each process have it's own memory stack, not accessible from outside
Can process only one message from mailbox at a time
Reliably guarantees each process a regular "slice" of computing time
By default occupies all available cores
Generic Servers
Gradual type system
Supervision Trees
Nodes clustering
In-memory DBs
Observer
Hot code upgrades
Construct / framework on top of processes and message passing
A server/client approach
Synchronous and asynchronous messaging
Demo
supervisor
workers
(supervisor is worker as well)
when worker process dies
supervisor gets notified
worker gets restarted
Hex package manager
DocTests - based on examples from documentation
Consistent code bases across community with code formatter
First class documentation
Concurrent tests by design
Crucial packages are maintained by elixir core developers
Phoenix web framework, with focus on event driven architecture
Nerves project - IoT made easy
Flow - Apache Spark alike data processing
Takes best things from both world - static and dynamic
Build in building blocks for easy creation of decoupled and easy to understand systems
Great performance
Fast development
Great community