Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Elixir - Part 1

Elixir - Part 1

A talk about Elixir and OTP given at Codeaholics in Hong Kong on August 12th 2015

Matthew Rudy Jacobs

August 12, 2015
Tweet

More Decks by Matthew Rudy Jacobs

Other Decks in Technology

Transcript

  1. Real-time Apps
    With Elixir
    Matthew Rudy Jacobs
    @ Codeaholics HK

    View full-size slide

  2. THE PROBLEM SPACE

    View full-size slide

  3. Line
    100s of millions of
    online users
    Can’t lose a message
    Don’t want downtime

    View full-size slide

  4. Uber
    100,000s online
    users
    Can’t lose a message
    Don’t want downtime

    View full-size slide

  5. GoGoVan
    ? online users
    Can’t lose a message
    Don’t want
    downtime

    View full-size slide

  6. THE SOLUTION?

    View full-size slide

  7. Erlang
    The Movie

    View full-size slide

  8. Ericsson (in 1998)
    99.9999999% UPTIME
    32MS / YEAR

    View full-size slide

  9. Ericsson (in 1998)
    99.9999999% UPTIME
    < 1SECOND / 20 YEARS

    View full-size slide

  10. Whatsapp
    64 billion messages per day
    700 million monthly active users
    1000 servers doing the work

    View full-size slide

  11. Erlang
    Elixir
    OTP
    Phoenix

    View full-size slide

  12. Part 1
    Erlang

    View full-size slide

  13. WHAT IS ERLANG?

    View full-size slide

  14. Erlang
    • functional
    • concurrent
    • realtime

    View full-size slide

  15. Erlang
    • pattern matching
    • message passing
    • actors
    • hot code reloading

    View full-size slide

  16. -module(roman).
    -export([to_roman/1]).
    to_roman(0) -> [];
    to_roman(X) when X >= 1000 -> [$M | to_roman(X - 1000)];
    to_roman(X) when X >= 100 ->
    digit(X div 100, $C, $D, $M) ++ to_roman(X rem 100);
    to_roman(X) when X >= 10 ->
    digit(X div 10, $X, $L, $C) ++ to_roman(X rem 10);
    to_roman(X) when X >= 1 -> digit(X, $I, $V, $X).
    digit(1, X, _, _) -> [X];
    digit(2, X, _, _) -> [X, X];
    digit(3, X, _, _) -> [X, X, X];
    digit(4, X, Y, _) -> [X, Y];
    digit(5, _, Y, _) -> [Y];
    digit(6, X, Y, _) -> [Y, X];
    digit(7, X, Y, _) -> [Y, X, X];
    digit(8, X, Y, _) -> [Y, X, X, X];
    digit(9, X, _, Z) -> [X, Z].
    Complex?
    Ugly?

    View full-size slide

  17. OTP IS A FRAMEWORK

    View full-size slide

  18. OTP IS A SET OF
    CONVENTIONS

    View full-size slide

  19. YOUR APPLICATION IS MADE OF “SERVERS”
    “AGENTS” AND “STATE MACHINES”
    KEPT ALIVE BY A COMPLICATED TREE OF SUPERVISORS

    View full-size slide

  20. Part 3
    Elixir

    View full-size slide

  21. #4 Rails
    Contributor

    View full-size slide

  22. Creator of
    Devise

    View full-size slide

  23. Creator of
    Elixir

    View full-size slide

  24. “I felt the same
    way I felt when I
    first saw Ruby.”

    View full-size slide

  25. ERLANG AND RUBY HAD A BABY

    View full-size slide

  26. %%% erlang
    -module(recursve).
    -export([fac/1]).
    fac(N) when N == 0 -> 1;
    fac(N) when N > 0 -> N*fac(N-1).
    # Ruby
    module Recursive
    def fac(n)
    return 1 if n == 0
    fail ArgumentError unless n > 0
    n*fac(n-1)
    end
    end

    View full-size slide

  27. # Elixir
    defmodule Recursive do
    def fac(n) when n == 0, do: 1
    def fac(n) when n > 0 do
    n*fac(n-1)
    end
    end

    View full-size slide

  28. # Elixir - with tail call
    defmodule Recursive do
    def fac(0), do: 1
    def fac(n) when n > 0 do
    fac(n, 1)
    end
    defp fac(1, acc), do: acc
    defp fac(n, acc) do
    fac(n-1, acc*n)
    end
    end

    View full-size slide

  29. “str”<>”ings”

    View full-size slide

  30. "with #{:interpolation}"

    View full-size slide

  31. [:list, “type”]

    View full-size slide

  32. {:tuple, “type”}

    View full-size slide

  33. [key: “word”, list: “…”]

    View full-size slide

  34. %{map: “is”, like: “a hash”}

    View full-size slide

  35. defmodule My.Module do
    def exported() do
    42
    end
    defp private() do
    76
    end
    end

    View full-size slide

  36. [head|tail] = [:a, :b, :c]

    View full-size slide

  37. defmodule Math do
    def sum([head|tail], acc) do
    sum(tail, head + acc)
    end
    def sum_list([], acc) do
    acc
    end
    end

    View full-size slide

  38. bessy = %{
    type: “cow”,
    name: “bessy”
    }
    %{name: name} = bessy
    name == “bessy”

    View full-size slide

  39. fn x -> 2*x end

    View full-size slide

  40. list = [1,3,3,7]
    Enum.sum(
    Enum.map(list, fn x -> x*x end)
    )
    # 68

    View full-size slide

  41. [1,3,3,7]
    |> Enum.map(fn x -> x*x end)
    |> Enum.sum
    # 68

    View full-size slide

  42. Part 4
    Phoenix

    View full-size slide

  43. Elixir
    on Phoenix

    View full-size slide

  44. Phoenix
    Ecto for the database
    Plug for routing
    Channels for websockets

    View full-size slide

  45. mix phoenix.new
    phoenix_play

    View full-size slide

  46. MORE NEXT TIME

    View full-size slide

  47. Appendix A
    Thoughts

    View full-size slide

  48. Gateway
    Todos
    Users
    Auth
    SERVICES OVER HTTP
    Mailer
    Search
    •HTTP
    •Ports
    •Monitoring
    •Scaling
    •Logging
    Issues

    View full-size slide

  49. Gateway
    Todos
    Users
    Auth
    A SINGLE OTP SYSTEM
    Mailer
    Search
    •HTTP
    •Ports
    •Monitoring
    •Scaling
    •Logging
    Issues

    View full-size slide

  50. Ruby people
    finally with technology that can scale

    View full-size slide

  51. PEPE
    Postgres
    Elixir
    Phoenix
    Ember

    View full-size slide

  52. Appendix B
    Addendum

    View full-size slide

  53. COME WORK AT GOGOVAN!!!

    View full-size slide