Slide 1

Slide 1 text

An intro to Elixir

Slide 2

Slide 2 text

A is not a Sandwich

Slide 3

Slide 3 text

This talk - About Me - wtf is Elixir - Basics - Cool in Elixir - Phoenix

Slide 4

Slide 4 text

I’m Tommy

Slide 5

Slide 5 text

I’m Tommy - ~3 years @ Deliveroo

Slide 6

Slide 6 text

I’m Tommy - ~3 years @ Deliveroo - Ruby for ~10 years

Slide 7

Slide 7 text

I’m Tommy - ~3 years @ Deliveroo - Ruby for ~10 years - Elixir for ~2 years

Slide 8

Slide 8 text

I’m Tommy - ~3 years @ Deliveroo - Ruby for ~10 years - Elixir for ~2 years - I know that I look like Tormund Giantsbane

Slide 9

Slide 9 text

wtf is Elixir?

Slide 10

Slide 10 text

wtf is Elixir? Elixir is a dynamic, functional language designed for building scalable and maintainable applications.

Slide 11

Slide 11 text

wtf is Elixir? - Created in 2012 by José Valim (former Rails Core Team)

Slide 12

Slide 12 text

wtf is Elixir? - Created in 2012 by José Valim (former Rails Core Team) - Built on top of, and compiles to, Erlang

Slide 13

Slide 13 text

wtf is Elixir? - Created in 2012 by José Valim (former Rails Core Team) - Built on top of, and compiles to, Erlang - Functional

Slide 14

Slide 14 text

wtf is Elixir? - Created in 2012 by José Valim (former Rails Core Team) - Built on top of, and compiles to, Erlang - Functional - Built with distributed resiliency in mind

Slide 15

Slide 15 text

Built on top of Erlang

Slide 16

Slide 16 text

Built on top of Erlang - Made by Ericsson in 1986

Slide 17

Slide 17 text

Built on top of Erlang - Made by Ericsson in 1986 - Erlang runs:

Slide 18

Slide 18 text

Built on top of Erlang - Made by Ericsson in 1986 - Erlang runs: - WhatsApp

Slide 19

Slide 19 text

Built on top of Erlang - Made by Ericsson in 1986 - Erlang runs: - WhatsApp - Facebook Messanger

Slide 20

Slide 20 text

Built on top of Erlang - Made by Ericsson in 1986 - Erlang runs: - WhatsApp - Facebook Messanger - SMS

Slide 21

Slide 21 text

Built on top of Erlang - Made by Ericsson in 1986 - Erlang runs: - WhatsApp - Facebook Messanger - SMS - GPRS and 3G networks

Slide 22

Slide 22 text

Built on top of Erlang - Made by Ericsson in 1986 - Erlang runs: - WhatsApp - Facebook Messanger - SMS - GPRS and 3G networks - Lots of Online Gaming

Slide 23

Slide 23 text

You’ve probably interacted with Erlang today and didn’t even know it

Slide 24

Slide 24 text

Erlang: The Movie

Slide 25

Slide 25 text

Erlang: The Moustache

Slide 26

Slide 26 text

Erlang’s pretty old, so why isn’t it more popular?

Slide 27

Slide 27 text

* OTP means Open Telephony Platform * Erlang/OTP is run by Ericsson * the syntax is prolog-y & not c-y or ruby-y or python-y, its just too damn erlang-y * no package manager * no list of open source packages * no community site * the mailing list is the community * everyone knows each other from Stockholm * it is too hard to get a first working app * lists for strings, aargh! * no for loops, eek! * variables don't vary, whimper! * people don't learn OTP first but start with Erlang * people don't learn Erlang first but start with OTP * no docs * too many docs but it is the wrong sort * not enough teaching materials * doesn't run on the JVM * we used to think that it was because there were no books... * Erlang Solutions isn't a proper internet company * the language develops too slowly * emacs is the IDE

Slide 28

Slide 28 text

Elixir fixes these problems

Slide 29

Slide 29 text

Basics

Slide 30

Slide 30 text

Functional No objects! Modules, functions and arguments. Module.Module.function(arg)

Slide 31

Slide 31 text

Distributed resiliency - Elixir is a multi-core language - State is held in lightweight Elixir processes - Processes can start, run, crash and restart easily

Slide 32

Slide 32 text

Distributed resiliency Supervisor Process Supervisor Process Supervisor Process Worker Process Worker Process Worker Process Worker Process

Slide 33

Slide 33 text

Distributed resiliency Supervisor Process Supervisor Process Supervisor Process Worker Process Worker Process Worker Process Worker Process

Slide 34

Slide 34 text

Distributed resiliency Supervisor Process Supervisor Process Supervisor Process Worker Process Worker Process Worker Process

Slide 35

Slide 35 text

Distributed resiliency Supervisor Process Supervisor Process Supervisor Process Worker Process Worker Process Worker Process Worker Process

Slide 36

Slide 36 text

Let it crash and allow your system to recover

Slide 37

Slide 37 text

Cool in Elixir

Slide 38

Slide 38 text

Equals is not equals > a = 2 2

Slide 39

Slide 39 text

Equals is pattern match > [1, 2, val] = [1, 2, 3] > val 3

Slide 40

Slide 40 text

Equals is pattern match > [2, 4, val] = [1, 2, 3] ** (MatchError) no match of right hand side value: [1, 2, 3]

Slide 41

Slide 41 text

Pattern matching a Tuple > {:hello, value} = {:hello, "world"} > value “world"

Slide 42

Slide 42 text

Pattern matching a Tuple case ApiFetcher.fetch(url) do {:ok, body} -> # Do something with `body` {:error, error} -> # Do something with `error` end

Slide 43

Slide 43 text

defmodule Text do def to_upcase(arg) do String.upcase(arg) end end > Text.to_upcase("hello") "HELLO" Defining functions

Slide 44

Slide 44 text

defmodule Formatter do def format("up:" <> username) do String.upcase(username) end def format(“reverse:" <> title) do String.reverse(title) end end Defining multiple versions of the same function

Slide 45

Slide 45 text

> Formatter.format("up:hello") "HELLO" > Formatter.format(“reverse:world") "dlrow" Defining multiple versions of the same function

Slide 46

Slide 46 text

defmodule Numbers do def double(arr) do Enum.map(arr, fn(x) -> x * 2 end) end end > Numbers.double([1, 2, 3]) [2, 4, 6] Loops

Slide 47

Slide 47 text

Pipes

Slide 48

Slide 48 text

defmodule Formatter do def format(data) do Map.get(data, :warning) |> String.upcase |> String.reverse end end > Formatter.format(%{warning: "murder"}) "REDRUM" Pipes

Slide 49

Slide 49 text

defmodule Formatter do def format(data) do Map.get(data, :warning) |> String.upcase |> String.reverse end end Pipes

Slide 50

Slide 50 text

defmodule Formatter do def format(data) do data |> Map.get(:warning) |> String.upcase |> String.reverse end end Pipes

Slide 51

Slide 51 text

def publish(%Post{status: status}) when status == :draft do # Publish a post end > Publisher.publish(%Post{status: :published}) ** (FunctionClauseError) no function clause matching in Publisher.publish/1 The following arguments were given to Publisher.publish/1: # 1 %Post{status: :published} Guards

Slide 52

Slide 52 text

GenServer Concurrently holding state in an Elixir Process

Slide 53

Slide 53 text

defmodule Basket do use GenServer def init(items) do {:ok, item} end def handle_call(:pop, _from, [head | tail]) do {:reply, head, tail} end def handle_cast({:push, item}, state) do {:noreply, [item | state]} end end GenServer

Slide 54

Slide 54 text

> {:ok, pid} = GenServer.start_link(Basket, [:burger]) {:ok, #PID<0.354.0>} > GenServer.call(pid, :pop) :burger > GenServer.cast(pid, {:push, :fries}) :ok > GenServer.call(pid, :pop) :fries GenServer

Slide 55

Slide 55 text

Phoenix

Slide 56

Slide 56 text

Phoenix - A Rails like web framework for Elixir - Controllers - Views (like Presenters) - Templates with Embedded Elixir (.eex) - Ecto (for DB interaction, like Active Record) - WebSockets - Contexts

Slide 57

Slide 57 text

WebSockets Phoenix has Channels

Slide 58

Slide 58 text

defmodule ChatWeb.ChatChannel do use Phoenix.Channel def join("chat:lobby", _message, socket) do {:ok, socket} end def join("chat:" <> room_id, _params, socket) do socket = assign(socket, :room_id, room_id) {:ok, socket} end def handle_in("join_room", %{"username" => username}, socket) do body = %{ new_user: username } broadcast!(socket, “new_user”, %{body: body}) {:noreply, socket} end end Channels

Slide 59

Slide 59 text

import {Socket} from "phoenix" let socket = new Socket("ws://localhost:4000/socket") socket.connect() let channel = socket.channel("room:lobby", {}) channel.join() channel.on("new_user", (body) => { console.log("New user!", body.user) }) Channels

Slide 60

Slide 60 text

Without models, where do we put our code?

Slide 61

Slide 61 text

No content

Slide 62

Slide 62 text

Contexts help us organise our code

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

Conclusion

Slide 65

Slide 65 text

Elixir is good Phoenix is good

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

No content

Slide 68

Slide 68 text

{:ok, :finish}

Slide 69

Slide 69 text

Further reading - elixir-lang.com - phoenixframework.org - github.com/h4cc/awesome-elixir - #elixir-lang on Deliveroo Slack - We’re hosting London Elixir on Tuesday