Slide 1

Slide 1 text

ilAiSIPlll. OF Elixir Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 2

Slide 2 text

Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 3

Slide 3 text

AGENDA ▸ The History of Elixir ▸ Syntax Crash Course ▸ Design Aspects Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 4

Slide 4 text

WHAT IS ELIXIR? Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 5

Slide 5 text

WHAT IS ELIXIR? Elixir is a dynamic, functional language designed for building scalable and maintainable applications. — elixir-lang.org Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 6

Slide 6 text

TO UNDERSTAND ELIXIR1 WE NEED TO UNDERSTAND ITS HISTORY 1 and the problems it tries to solve Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 7

Slide 7 text

THE YEAR IS 2012 Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 8

Slide 8 text

JOSÉ VALIM Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 9

Slide 9 text

JOSÉ VALIM A well-known Rubyist ▸ Rails 44.2k ⭐ (Contributor) ▸ Devise 20.2k ▸ Simple Form 7.5k ▸ And more ... Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 10

Slide 10 text

CONCURRENCY Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 11

Slide 11 text

Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 12

Slide 12 text

ERLANG Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 13

Slide 13 text

BEAM ERLANG VM Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 14

Slide 14 text

ACTOR MODEL2 2 Technically almost-actor (https://www.youtube.com/watch?v=_0m0_qtfzLs) Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 15

Slide 15 text

source: https://www.brianstorti.com/the-actor-model/

Slide 16

Slide 16 text

ERLANG WAS CREATED AT ERICSSON FOR TELEPHONY SWITCHES Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 17

Slide 17 text

▸ Distributed ▸ Fault-tolerant ▸ Soft real-time ▸ High-availability Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 18

Slide 18 text

WORK ON ERLANG STARTED IN 1987 Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 19

Slide 19 text

IT WENT OPEN-SOURCE IN 1998 Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 20

Slide 20 text

BATTLE-TESTED IN OVER 30 YEARS OF USAGE Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 21

Slide 21 text

-module(greetings). -export([hello/1]). hello(Name) -> io:format("Hello ~s~n", [Name]). Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 22

Slide 22 text

 RUBY         ERLANG Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 23

Slide 23 text

Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 24

Slide 24 text

BEAM Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 25

Slide 25 text

-module(greetings). -export([hello/1]). hello(Name) -> io:format("Hello ~s~n", [Name]). Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 26

Slide 26 text

defmodule Greetings do def hello(name) do IO.puts("Hello #{name}") end end Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 27

Slide 27 text

RUBY + ERLANG = Elixir Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 28

Slide 28 text

SYNTAX CRASH COURSE Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 29

Slide 29 text

SYNTAX CRASH COURSE - BASIC TYPES ▸ List: [3, 1, 4, 1, 5] ▸ Map: %{key: "value"} ▸ Atom: :an_atom ▸ Boolean: true || false ▸ Tuple: {"have some PI", 3.1415, :the_pi_is_a_lie} ▸ Function: fn x, y -> x * y end Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 30

Slide 30 text

SYNTAX CRASH COURSE - OPERATORS ▸ Basics: +, -, *, /, ==, <, >, &&, || ▸ String Concatination: "Hello" <> " Lambda Cologne" ▸ List Concatination: [3, 1, 4] ++ [1, 5] ▸ Pipe: [3, 1, 4, 1, 5] |> Enum.map(fn x -> x * 2 end) |> Enum.sum() Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 31

Slide 31 text

SYNTAX CRASH COURSE - PIPE iex> [3, 1, 4, 1, 5] |> Enum.map(fn x -> x * 2 end) |> Enum.sum() 28 iex> Enum.sum(Enum.map([3, 1, 4, 1, 5], fn x -> x * 2 end)) 28 Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 32

Slide 32 text

Elixir ▸ developer happiness ▸ pattern-matching ▸ syntactic macro system ▸ Erlang goodness Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 33

Slide 33 text

DEVELOPER HAPPINESS Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 34

Slide 34 text

GREAT TOOLING ▸ build tool mix ▸ code formatter ▸ unit testing framework ▸ first-class documentation ▸ and more ... Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 35

Slide 35 text

UNIT TESTING FRAMEWORK ExUnit Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 36

Slide 36 text

defmodule GreetingsTest do use ExUnit.Case, async: true test "it greets friendly" do assert Greetings.hello("Lambda Cologne") == "Hello Lambda Cologne!" end end Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 37

Slide 37 text

Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 38

Slide 38 text

FIRST-CLASS DOCUMENTATION Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

defmodule Greetings do @doc """ Prints a friendly greeting. ## Examples iex> Greetings.hello("Lambda Cologne") "Hello Lambda Cologne!" """ def hello(name) do IO.puts("Hello #{name}") end end Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 41

Slide 41 text

Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

defmodule GreetingsTest do use ExUnit.Case, async: true doctest Greetings end Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 44

Slide 44 text

Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 45

Slide 45 text

AND MORE ... ▸ Powerful interactive console (iex) ▸ "Batteries included" web framework (Phoenix) ▸ A bunch more neat Erlang/OTP things: ▸ Supervision trees, observer, remote debugging, hot code upgrades ... Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 46

Slide 46 text

PATTERN MATCHING Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 47

Slide 47 text

iex> my_list = [3, 1, 4, 1, 5, 9, 2, 6, 5] iex> [first, second | rest] = my_list iex> first 3 iex> second 1 iex> rest [4, 1, 5, 9, 2, 6, 5] Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 48

Slide 48 text

iex> my_map = %{a: 1, b: 2, c: 3} iex> %{a: a, b: b} = my_map iex> a 1 iex> b 2 Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 49

Slide 49 text

iex> greeting = "Hello Lambda Cologne" iex> "Hello " <> name = greeting iex> name "Lambda Cologne" Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 50

Slide 50 text

= IS THE ASSIGNMENT OPERATOR MATCH OPERATOR Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 51

Slide 51 text

iex> "Hello " <> name = "Salut Lambda Cologne" ** (MatchError) no match of right hand side value: "Salut Lambda Cologne" (stdlib) erl_eval.erl:453: :erl_eval.expr/5 (iex) lib/iex/evaluator.ex:257: IEx.Evaluator.handle_eval/5 (iex) lib/iex/evaluator.ex:237: IEx.Evaluator.do_eval/3 (iex) lib/iex/evaluator.ex:215: IEx.Evaluator.eval/3 (iex) lib/iex/evaluator.ex:103: IEx.Evaluator.loop/1 (iex) lib/iex/evaluator.ex:27: IEx.Evaluator.init/4 Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 52

Slide 52 text

PATTERN MATCHING IS EVERYWHERE Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 53

Slide 53 text

defmodule Greetings do def hello("") do hello("anonymous") end def hello("Lambda " <> city) do hello("FP-Enthusiast from #{city}") end def hello(name) do "Hello #{name}!" end end Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 54

Slide 54 text

SYNTACTIC MACROS Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 55

Slide 55 text

TRANSFORM THE AST ABSTRACT SYNTAX TREE Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 56

Slide 56 text

USE THE FULL POWER OF Elixir Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 57

Slide 57 text

defmodule Conditional do defmacro if(condition, do: true_block, else: false_block) do quote do case unquote(condition) do true -> unquote(true_block) false -> unquote(false_block) end end end end Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 58

Slide 58 text

iex> import Conditional iex> if true do ...> "dis is true" ...> else ...> "dis is false" ...> end "dis is true" Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 59

Slide 59 text

application/andrew-inset ez application/applixware aw application/atom+xml atom application/atomcat+xml atomcat application/atomsvc+xml atomsvc application/ccxml+xml ccxml application/cdmi-capability cdmia application/cdmi-container cdmic application/cdmi-domain cdmid application/cdmi-object cdmio application/cdmi-queue cdmiq application/cu-seeme cu Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 60

Slide 60 text

defmodule MimeType do "path/to/mime-types.txt" |> File.read!() |> Enum.map(fn line -> [mime_type, extension] = String.split(line, " ", trim: true) def to_extension(unquote(mime_type)), do: unquote(extension) end) end Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 61

Slide 61 text

iex> MimeType.to_extension("application/applixware") "aw" Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 62

Slide 62 text

Elixir MACROS ARE HYGENIC Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 63

Slide 63 text

ERLANG GOODNESS Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 64

Slide 64 text

-module(greetings). -export([hello/1]). hello(Name) -> io:format("Hello ~s~n", [Name]). Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 65

Slide 65 text

defmodule Greetings do def hello(name) do :greetings.hello(name) end end Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 66

Slide 66 text

OTP OPEN TELECOM PLATFORM Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 67

Slide 67 text

OPEN TELECOM PLATFORM If half of Erlang's greatness comes from its concurrency and distribution and the other half comes from its error handling capabilities, then the OTP framework is the third half of it. — Learn You Some Erlang for Great Good! (Frederic Trottier-Hebert)3 3 https://learnyousomeerlang.com/what-is-otp Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 68

Slide 68 text

PROCESS ACTOR Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 69

Slide 69 text

DATABASE CONNECTION Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 70

Slide 70 text

DATABASE CONNECTION ▸ establish a connection ▸ do some work* ▸ disconnect Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 71

Slide 71 text

DATABASE CONNECTION ▸ establish a connection ▸ run a query* ▸ disconnect * Usually you would have some kind of checkout/checkin mechanism Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 72

Slide 72 text

GENSERVER Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 73

Slide 73 text

defmodule DbConnection do use GenServer def init(uri) do connection = MyDatabase.establish_connection(uri) {:ok, connection} end def handle_call({:query, query}, _from, connection) do result = MyDatabase.run_query(connection, query) {:reply, result, connection} end def handle_cast(:disconnect, connection) do connection = MyDatabase.close_connection(connection) {:stop, :normal, connection} end end Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 74

Slide 74 text

iex> {:ok, pid} = GenServer.start_link(DbConnection, "my-database-uri") iex> query = "SELECT * FROM users" iex> GenServer.call(pid, {:query, query}) [ ... ] # List of users iex> GenServer.cast(pid, :disconnect) :ok Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 75

Slide 75 text

defmodule DbConnection do use GenServer def start_link(uri) do GenServer.start_link(DbConnection, uri) end def query(pid, query) do GenServer.call(pid, {:query, query}) end def disconnect(pid) do GenServer.cast(pid, :disconnect) end # init, handle_call, handle_cast end Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 76

Slide 76 text

WHAT IF THE DATABASE GOES DOWN? Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 77

Slide 77 text

! Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 78

Slide 78 text

Let it crash — Old Erlang wisdom Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 79

Slide 79 text

Let it crash 131 out of 132 bugs are transient bugs — Erlang in Anger (which refers here to Jim Gray)4 4 https://www.erlang-in-anger.com Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 80

Slide 80 text

EXAMPLES OF TRANSIENT BUGS ▸ Network request fails ▸ File IO has a hickup ▸ Odd race condition ▸ Weird datetime issue ▸ Database goes down Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 81

Slide 81 text

Let it crash — Old Erlang wisdom Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 82

Slide 82 text

SUPERVISORS Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 83

Slide 83 text

SUPERVISORS The supervisor is responsible for starting, stopping, and monitoring its child processes. The basic idea of a supervisor is that it must keep its child processes alive by restarting them when necessary. — Erlang Documentation5 5 http://erlang.org/doc/man/supervisor.html#supervision-principles Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 84

Slide 84 text

No content

Slide 85

Slide 85 text

defmodule MyApp.Application do # See https://hexdocs.pm/elixir/Application.html # for more information on OTP Applications use Application def start(_type, _args) do # List all child processes to be supervised children = [ MyApp.Repo, MyApp.Endpoint ] # See https://hexdocs.pm/elixir/Supervisor.html # for other strategies and supported options opts = [strategy: :one_for_one, name: MyApp.Supervisor] Supervisor.start_link(children, opts) end end Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 86

Slide 86 text

STANDING ON THE SHOULDERS OF GIANTS ▸ Agent - keep and manipulate state ▸ Task - easy asynchronous processing ▸ GenStage - exchange events with back-pressure between producer and consumer processes Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 87

Slide 87 text

THERE'S MORE ... ▸ remote debugging ▸ built-in support for node clustering ▸ hot code upgrades (upgrade while running) ▸ great support for metrics and introspection ▸ ... Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 88

Slide 88 text

SUMMARY Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 89

Slide 89 text

Elixir ▸ functional and dynamically typed ▸ focusses on developer happiness ▸ considers documentation a first-class citizen ▸ provides a full syntactic macro system ▸ stands on the shoulders of giants (Erlang/OTP) Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 90

Slide 90 text

THANK YOU FOR LISTENING Sascha Wolf | ! wolf4earth | saschawolf.me

Slide 91

Slide 91 text

QUESTIONS? Sascha Wolf | ! wolf4earth | saschawolf.me