Me • Originally from SF Bay Area • Writing Python since 2001 • Mostly backend systems + SAAS architecture + (micro)services • Plenty of Django • Plenty of horrible codebases • Looking for a better way
Why Elixir? • Scalability / concurrency • Distributed system / microservices usually requires tooling, systems and lots of management • Distributed programming built into the language via Erlang/BEAM • Performance • Many languages aren't that good at resource utilization: Python, Ruby, JavaScript/Node • Other more performant languages are a bit too low-level: C, Go, Rust • Functional • Immutable state means concurrency is easier • Immutable state means is harder to write big balls of mud
Elixir Strings • Single quoted • List of integers • iex represents this as a string if each char is printable • Double quoted • Sequence of UTF-8 bytes • Each byte is a binary
1 = a cannot work in Elixir too! a must be defined before matching iex(1)> 1 = a ** (CompileError) iex:1: undefined function a/0 iex(1)> a = 1 1 iex(2)> 1 = a 1
iex(7)> %{name: "Brian"} = me %{age: 43, name: "Brian"} iex(8)> %{name: "Joe"} = me ** (MatchError) no match of right hand side value: %{age: 43, name: "Brian"} Mis-matching with maps
Simple GenServer defmodule Calculator.Server do use GenServer # API def start_link do GenServer.start_link(__MODULE__, nil, name: :calculator) end def divide(n, m) do GenServer.call(:calculator, {:divide, n, m}) end # end API
Simple GenServer # Server callbacks def init(nil) do {:ok, nil} end def handle_call({:multiply, n, m}, _from, _state) do { :reply, n * m, nil } end end
Running with Supervisor 1 defmodule Calculator.Supervisor do 2 use Supervisor 3 4 def start_link do 5 Supervisor.start_link(__MODULE__, []) 6 end 7 8 def init(_) do 9 children = [ 10 worker(Calculator.Server, []) 11 ] 12 supervise(children, strategy: :one_for_one) 13 end 14 end