Elixir
What we'll cover
- General background
- Language basics
- Enjoyable language features (pipelines, pattern matching)
- Intro to the BEAM (I'm still a noob)
- Phoenix (mainly LiveView)
- Downsides / pain points.
General Background
- Made by José Valim (devise, rails core etc.)
- Built on top of the Erlang VM (The BEAM)
- Functional language
- Immutable
- Built for concurrency & uptime & fault tolerance
- Whatsapp (erlang), Discord, Pinterest all built on top of it.
Quick concurrency demo
Language Fun ✨
- Just going to cover what I consider the fun parts!
- Docs are really good if you want more
- No doubt you'll want more by the end of this riveting talk.
Language Fun: Maps
- Maps are the workhorse type
- Used extensively for pattern matching
- Keys & values can be anything you like
%{
1 => 2,
{"tuple"} => %{this: :that},
["even", "lists"] => ~r/regex/,
:foo => <<?h, ?e, ?l, ?l, ?o>>
}
Language Fun: Structs
- Just a fancy layer over a map.
defmodule Car do
@enforce_keys [:make]
defstruct [:model, :make]
end
Language: Assignment & Pattern Matching
- Probably the most awesome (and fun) part of Elixir. You can match all the things in all the places.
- Assignment is more like algebra (in that the two expressions on each side of the = are assumed to match eachother. In elixir = is literally called the Match Operator
Language: Assignment & Pattern Matching

a = ["foo", %{bar: %{baz: "wibble"}}, [1, 2, 3, 4]]
[_, %{bar: %{baz: value}}, [1 | tail]] = a
Language: Functions (match arity & shape)
In Elixir, functions are uniquely identified by name and arity. Within a given name/arity, you can define multiple function heads that use pattern matching and guards. At call time, Elixir picks the right clause by trying the heads in order until one matches the arguments’ shape.
def foo(), do: "empty"
def foo(a) when is_number(a) do
"you chose #{n}"
end
def foo(%{env: :prod} = _state, blah), do: "..."
def foo([]), do: "..."
def foo([h | t]), do: something_recursive
def foo(%User{} = user) # here we match a struct
Language: Can reduce* use of conditionals

Language: Pipeline Operator |>
defmodule Cleaner do
def clean_text(text) do
text
|> String.trim()
|> String.downcase()
|> String.replace(~r/[^a-z0-9\s]/, "")
|> String.split(~r/\s+/, trim: true)
|> Enum.uniq()
|> Enum.sort()
end
end
vs
Enum.sort(
Enum.uniq(
String.split(
String.replace(
String.downcase(
String.trim(" Hello, HELLO... World!! World ")
),
~r/[^a-z0-9\s]/,
""
),
~r/\s+/,
trim: true
)
)
)
Language: Misc
- no early return (well, no return keyword)
- in place mutations (x +=1) not allowed.
- lists are "linked lists", arbitrary index means traversing the list (use a map instead)
- mutating large structures means you get a new large structure*
The BEAM
- Where the magic happens.
- Paralellizes the programs
- Takes care of process isolation
- Takes care of distribution
- Takes care of responsiveness
- Process communication (message passing)
Bogdan/Björn's Erlang Abstract Machine



BEAM demo
- Sasa Juric's server!
- Start some processes
- Move them around*
- See some CPU cores light up.
- See how cpu intensive tasks don't block the system
- Play with the dashboard and observer() tooling
Other things
- Processes can be linked
- Processes can be monitored
- Supervisors can restart processes (you can have entire supervision trees)
- Obervability of the running system (see live dashboard and :observer.start()
Phoenix
- The "rails" of the elixir world.
- Can have regular "RESTful" controllers etc.
- Also "liveview" which is what we'll have a play with here.
LiveView
-
The browser renders HTML sent from the server.
-
User interactions (clicks, form changes, etc.) send events over a persistent WebSocket connection to the server.
-
The server updates the state, re-renders the relevant HTML diff, and pushes only those changes back to the browser.
LiveView - Counter
Downsides of Elixir
- Fewer devs with experience, you may need to train up.
- Ecosystem 80K erlang repo vs 331K ruby...)
- Latency for liveview is a killer / requires thinking about.
Thanks! - Questions?
Language Basics: Tuples
- Ordered collection of values
- Often used in pattern matching / pipelining- and assume happy path. e.g.

{1, 2, 3}
{:ok, "something"}
{:error, "some error message"}
{:can, 1, ["contain"], AnythingYouLike}
Language Basics: Keyword Lists
- Keyword lists are how you pass options around
- (it gets converted to a list of two-value tuples}
- Can have duplicated items (it's really just a list of tuples)
[this: "that", foo: "bar"] => [{:this, "that"}, {:foo, "bar"}]
Language Basics: Lists
- Not like ruby. Immutuable structures so can be expensive if you mutate a lot.
- More like a linked list - prepend O(1) rather than append O(n)
- Random access not easy, you must traverse the list.
- Extracting the "head" and "tail" of a list & using recursion is normal.
Language: Recursion (tail call optimized)


Language: Scoping

Language Basics: Binaries
- Access data as a sequence of bits & bytes
- Unlikely to use them directly (to begin with), but, it is what strings are represented as
- Can do pattern matching into it (think IOT stuff)

Elixir - An Introduction
By Patrick Davey
Elixir - An Introduction
- 13