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

Pinball Elixir

Pinball Elixir

Intro to Elixir with Pinball

Adrian Dunston

October 14, 2019
Tweet

More Decks by Adrian Dunston

Other Decks in Technology

Transcript

  1. @bitcapulet Purpose To get you excited about Elixir. So you’ll

    be more powerful. So your companies will start using it. 4
  2. @bitcapulet Purpose To get you excited about Elixir. So you’ll

    be more powerful. So your companies will start using it. So my friends and I have more Elixir jobs available. 5
  3. @bitcapulet Purpose To get you excited about Elixir. So you’ll

    be more powerful. So your companies will start using it. So my friends and I have more Elixir jobs available. Because I'm excited about Elixir. 6
  4. @bitcapulet If you state your complexity clearly, it's easier to

    solve complex problems. Distributed systems = complex problems 23
  5. @bitcapulet If you state your complexity clearly, it's easier to

    solve complex problems. Functional programming forces this. 24
  6. @bitcapulet If you state your complexity clearly, it's easier to

    solve complex problems. This is what ELIXIR brings to the table. 25
  7. @bitcapulet Rob those phone companies blind! 16 years of searching

    and building. THEN 20 years of open-source improvements. 28
  8. @bitcapulet Rob those phone companies blind! 16 years of searching

    and building. THEN 20 years of open-source improvements. 29 Now a fresh new language built on top!
  9. @bitcapulet [ , , , ] a b c d

    def get_odd(list) do a = Enum.at(list, 0) c = Enum.at(list, 2) [a, c] end 76
  10. @bitcapulet [ , , , ] a b c d

    def get_odd(list) do a = Enum.at(list, 0) c = Enum.at(list, 2) [a, c] end 83
  11. @bitcapulet [ , , , ] a b c d

    def get_odd(list) do [a, b, c, d] list [a, c] end 84
  12. @bitcapulet [ , , , ] a b c d

    def get_odd(list) do [a, _, c, _] list [a, c] end 85
  13. @bitcapulet [ , , , ] a b c d

    def get_odd(list) do [a, _b, c, _d] list [a, c] end 86
  14. @bitcapulet def get_name(map) do %{name: var} map var end get_name(%{})

    ** (MatchError) no match of right hand side value: %{} 121
  15. @bitcapulet def get_name(map) do %{name: var} map var end get_name(%{})

    ** (MatchError) no match of right hand side value: %{} 125 Not just for getting values!
  16. @bitcapulet %{"name" => _, "age" => _, "fav.capt." => "Picard"

    } my_map %{name: _, age: _, fav_capt: "Picard" } my_map 127
  17. @bitcapulet %{"name" => _, "age" => _, "fav.capt." => "Picard"

    } my_map %{name: _, age: _, fav_capt: "Picard" } my_map 129
  18. @bitcapulet %{"name" => _, "age" => _, "fav.capt." => "Picard"

    } my_map [ %{fav_capt: "Kirk"}, %{fav_capt: "Picard"}, %{fav_capt: "Sisko"}, %{fav_capt: "Janeway"}, ] list_of_maps 130
  19. @bitcapulet %{"name" => _, "age" => _, "fav.capt." => "Picard"

    } my_map [ %{fav_capt: "Kirk"}, %{fav_capt: "Picard"}, %{fav_capt: "Sisko"}, %{fav_capt: "Janeway"}, %{fav_capt: ["Kirk", "Sisko"] ] list_of_maps_with_lists 131
  20. @bitcapulet %{"name" => _, "age" => _, "fav.capt." => "Picard"

    } my_map [ %{fav_capt: "Kirk", age: var}, %{fav_capt: "Picard"}, %{fav_capt: "Sisko"}, %{fav_capt: "Janeway"}, %{fav_capt: ["Kirk", "Sisko"] ] list_of_maps_with_lists 132
  21. @bitcapulet >%{} Of course it equal sign! Everyone guess that!

    Why you use clipart in first place? 141
  22. @bitcapulet case do_math(2) 4 -> "hurray" 3 -> "oops" var

    -> "Got number: #{var}" [1, 2, 3] -> "123 list" end 150
  23. @bitcapulet case do_math(2) 4 -> "hurray" 3 -> "oops" var

    -> "got number: #{var}" [1, 2, 3] -> "123 list" end 151
  24. @bitcapulet case do_math(2) 4 -> "hurray" 3 -> "oops" var

    -> "got number: #{var}" [1, 2, 3] -> "123 list" end [ , , , ] 1 2 3 152
  25. @bitcapulet case do_math(2) 4 -> "hurray" 3 -> "oops" var

    -> "got number: #{var}" [1, 2, 3] -> "123 list" end [ , , , ] 1 2 3 153
  26. @bitcapulet case do_math(2) 4 -> "hurray" 3 -> "oops" var

    -> "got number: #{var}" [1, 2, 3] -> "123 list" end [ , , , ] 1 2 3 154
  27. @bitcapulet case do_math(2) 4 -> "hurray" 3 -> "oops" var

    -> "got number: #{var}" [1, 2, 3] -> "123 list" end 155
  28. @bitcapulet case 4 -> "hurray" 3 -> "oops" var ->

    "got number: #{var}" [1, 2, 3] -> "123 list" end 156
  29. @bitcapulet case 4 -> "hurray" 3 -> "oops" var ->

    "got number: #{var}" [1, 2, 3] -> "123 list" end 157
  30. @bitcapulet case 4 -> "hurray" 3 -> "oops" var ->

    "got number: #{var}" [1, 2, 3] -> "123 list" end 158
  31. @bitcapulet case 4 -> "hurray" 3 -> "oops" var ->

    "got number: #{var}" [1, 2, 3] -> "123 list" end 159
  32. @bitcapulet case 4 -> "hurray" 3 -> "oops" var ->

    "got number: #{var}" [1, 2, 3] -> "123 list" end 160
  33. @bitcapulet case 4 -> "hurray" 3 -> "oops" var ->

    "got number: #{var}" [1, 2, 3] -> "123 list" end 161
  34. @bitcapulet case 4 -> "hurray" 3 -> "oops" var ->

    "got number: #{var}" [1, 2, 3] -> "123 list" end 162
  35. @bitcapulet case 4 -> "hurray" 3 -> "oops" var ->

    "got number: #{var}" [1, 2, 3] -> "123 list" end 163
  36. @bitcapulet case 4 -> "hurray" 3 -> "oops" var ->

    "got number: #{var}" [1, 2, 3] -> "123 list" end 164
  37. @bitcapulet case 4 -> "hurray" 3 -> "oops" var ->

    [1, 2, 3] -> "123 list" end 165
  38. @bitcapulet case 4 -> "hurray" 3 -> "oops" var ->

    [1, 2, 3] -> "123 list" end 166
  39. @bitcapulet case 4 -> "hurray" 3 -> "oops" var ->

    [1, 2, 3] -> "123 list" end 167
  40. @bitcapulet case 4 -> "hurray" 3 -> "oops" var ->

    [1, 2, 3] -> "123 list" end 168
  41. @bitcapulet case 4 -> "hurray" 3 -> "oops" var ->

    [1, 2, 3] -> "123 list" end 169
  42. @bitcapulet case 4 -> "hurray" 3 -> "oops" var ->

    [1, 2, 3] -> "123 list" end 170
  43. @bitcapulet case do_math(2) 4 -> "hurray" 3 -> "oops" var

    -> "got number: #{var}" [1, 2, 3] -> "123 list" end 171
  44. @bitcapulet case do_math(2) 4 -> "hurray" 3 -> "oops" var

    -> "got number: #{var}" [1, 2, 3] -> "123 list" end 172
  45. @bitcapulet case do_math(2) 4 -> "hurray" 3 -> "oops" [1,

    2, 3] -> "123 list" var -> "got number: #{var}" end 173
  46. @bitcapulet case do_math(2) 4 -> "hurray" 3 -> "oops" [1,

    2, 3] -> "123 list" var -> "got number: #{var}" end 174
  47. @bitcapulet defmodule MyModule def phil(state) do receive do value ->

    IO.puts("count: " <> state) IO.puts("Phil got: " <> value) end phil(state + 1) end end 205
  48. @bitcapulet Interactive Elixir (1.6.1) - press Ctrl+C to exit (type

    h() ENTER for help) iex(1)> IO.puts("Hello, world!") Hello, world! :ok iex(2)> 207
  49. @bitcapulet iex(2)> pid = spawn(MyModule, :phil, 0) #PID<0.97.0> iex(3)> Process.alive?(pid)

    true iex(4)> send(pid, "hello") count: 0 Phil got: hello "hello" iex(5)> 210
  50. @bitcapulet iex(2)> pid = spawn(MyModule, :phil, 0) #PID<0.97.0> iex(3)> Process.alive?(pid)

    true iex(4)> send(pid, "hello") count: 0 Phil got: hello "hello" iex(5)> send(pid, "hello") count: 1 Phil got: hello "hello" 211
  51. @bitcapulet A process is a recursive function that holds state

    and lives at an address with a mailbox. <0.194.0> 213
  52. @bitcapulet def run(tuple = {a,b,c,d}) do IO.inspect(tuple) {d,c,b,a} end def

    run(tuple = {a,b,c,d,e}) do IO.inspect(tuple) {e,d,c,b,a} end 252
  53. @bitcapulet def run(tuple = {a,b,c,d}) do IO.inspect(tuple) {d,c,b,a} end def

    run(tuple = {a,b,c,d,e}) do IO.inspect(tuple) {e,d,c,b,a} end 253
  54. @bitcapulet def run(tuple = {a,b,c,d}) do IO.inspect(tuple) {d,c,b,a} end def

    run(tuple = {a,b,c,d,e}) do IO.inspect(tuple) {e,d,c,b,a} end 254
  55. @bitcapulet def run(tuple = {a,b,c,d}) do IO.inspect(tuple) {d,c,b,a} end def

    run(tuple = {a,b,c,d,e}) do IO.inspect(tuple) {e,d,c,b,a} end 255
  56. @bitcapulet def run(tuple = {a,b,c,d}) do IO.inspect(tuple) {d,c,b,a} end def

    run(tuple = {a,b,c,d,e}) do IO.inspect(tuple) {e,d,c,b,a} end 256
  57. @bitcapulet def run(tuple = {a,b,c,d}) do IO.inspect(tuple) {d,c,b,a} end def

    run(tuple = {a,b,c,d,e}) do IO.inspect(tuple) {e,d,c,b,a} end 257
  58. @bitcapulet def run(tuple = {a,b,c,d}) do IO.inspect(tuple) {d,c,b,a} end def

    run(tuple = {a,b,c,d,e}) do IO.inspect(tuple) {e,d,c,b,a} end 258
  59. @bitcapulet A process is a recursive function that holds state

    and lives at an address with a mailbox. <0.194.0> 261
  60. @bitcapulet defmodule Phil do use GenServer def init(_args), do: 0

    def handle_cast(value, from, state) do IO.puts("Phil got: " <> value) {:noreply, state + 1} end end 264
  61. @bitcapulet defmodule Phil do use GenServer def init(_args), do: 0

    def handle_cast(value, from, state) do IO.puts("Phil got: " <> value) {:noreply, state + 1} end end 265
  62. @bitcapulet defmodule Phil do use GenServer def init(_args), do: 0

    def handle_cast(value, from, state) do IO.puts("Phil got: " <> value) {:noreply, state + 1} end end 266
  63. @bitcapulet defmodule Phil do use GenServer def init(_args), do: 0

    def handle_cast(value, from, state) do IO.puts("Phil got: " <> value) {:noreply, state + 1} end end 267
  64. @bitcapulet defmodule Phil do use GenServer def init(_args), do: 0

    def handle_cast(value, from, state) do IO.puts("Phil got: " <> value) {:noreply, state + 1} end def handle_call(:say_something, from, state) do {:reply, "something", state} end end 268
  65. @bitcapulet Asynchronous requests def handle_cast(value, from, state) do IO.puts("Phil got:

    " <> value) {:noreply, state + 1} end GenServer.cast(pid, "a present") move_right_along() 270
  66. @bitcapulet def handle_call(:say_something, from, state) do IO.puts("Phil got: " <>

    value) {:reply, "Thanks", state} end Synchronous requests reply = GenServer.call(pid, :say_something) 271
  67. @bitcapulet defmodule CaptJoan do use Supervisor def init(_args) do children

    = [ {Phil, []} ] Supervisor.init(children, strategy: :one_for_one) end end 278
  68. @bitcapulet defmodule CaptJoan do use Supervisor def init(_args) do children

    = [ {Phil, []} ] Supervisor.init(children, strategy: :one_for_one) end end 279
  69. @bitcapulet defmodule CaptJoan do use Supervisor def init(_args) do children

    = [ {Phil, []} ] Supervisor.init(children, strategy: :one_for_one) end end 280
  70. @bitcapulet defmodule CaptJoan do use Supervisor def init(_args) do children

    = [ {Phil, []}, {Phil, []}, {Phil, []} ] Supervisor.init(children, strategy: :one_for_one) end end 281
  71. @bitcapulet defmodule CaptJoan do use Supervisor def init(_args) do children

    = [ {Phil, []}, {Phil, []}, {Phil, []} ] Supervisor.init(children, strategy: :one_for_one) end end 282
  72. @bitcapulet defmodule CaptJoan do use Supervisor def init(_args) do children

    = [ {Phil, []}, {Phil, []}, {Phil, ["arg"]} ] Supervisor.init(children, strategy: :one_for_one) end end 286
  73. @bitcapulet defmodule CaptJoan do use Supervisor def init(_args) do children

    = [ {Phil, []}, {Phil, []}, {Phil, ["arg"]} ] Supervisor.init(children, strategy: :one_for_all) end end 287
  74. @bitcapulet defmodule AdmiralRavi do use Supervisor def init(_args) do children

    = [ {CaptJoan, []}, {CaptJoan, []}, {CaptJoan, []} ] Supervisor.init(children, strategy: :one_for_one) end end 288
  75. @bitcapulet defmodule AdmiralRavi do use Supervisor def init(_args) do children

    = [ {CaptJoan, []}, {CaptJoan, []}, {CaptJoan, []} ] Supervisor.init(children, strategy: :one_for_one) end end 307
  76. @bitcapulet def fav_capt(:kirk) do {:error, "Are you kidding me?"} end

    def fav_capt(:picard) do {:ok, "You chose wisely."} end 315
  77. @bitcapulet capt = :kirk {:ok, message} = fav_capt(capt) IO.puts(message) **

    (MatchError) no match of right hand side value: {:error, "Are you kidding me?"} 317
  78. @bitcapulet capt = :kirk case fav_capt(capt) {:ok, msg} -> msg

    {:error, msg} -> Log.error("oops") end 318
  79. @bitcapulet capt = :kirk case fav_capt(capt) {:ok, msg} -> msg

    {:error, _msg} -> Log.error("oops") end 319
  80. @bitcapulet capt = :kirk case fav_capt(capt) {:ok, msg} -> msg

    {:error, _msg} -> Log.error("oops") {_, _msg} -> Log.error("What?!") end 320
  81. @bitcapulet capt = :kirk case fav_capt(capt) {:ok, msg} -> msg

    {:error, _msg} -> Log.error("oops") {_, _msg} -> Log.error("What?!") _ -> Log.error("Oh dear.") end 321
  82. @bitcapulet case fav_capt(capt) {:ok, msg} -> Log.info("That went well.") msg

    {:error, _msg} -> Log.error("oops") {_, _msg} -> Log.error("What?!") _ -> Log.error("Oh dear.") end 322
  83. @bitcapulet def respond({:ok, msg}) do Log.info("That went well.") msg end

    def respond({:error, _msg}) do Log.error("oops") end 323
  84. @bitcapulet capt |> beam_to_planet() |> meet_aliens() |> romance?() |> case

    do {:ok, details} -> log(details) :error -> kill_off_extra() end 334
  85. @bitcapulet capt |> beam_to_planet() |> meet_aliens() |> romance?() |> case

    do {:ok, details} -> log(details) :error -> kill_off_extra() end 335
  86. @bitcapulet capt |> beam_to_planet() |> meet_aliens() |> romance?() |> case

    do {:ok, details} -> log(details) :error -> kill_off_extra() end 336
  87. @bitcapulet [1, 2, 3] |> Enum.map(fn i -> i +

    1 end) |> Enum.sum() # 9 339
  88. @bitcapulet defmodule CircleKeeper do use GenServer def init(starting_circles), do: starting_circles

    def handle_cast({:add, circle}, _, circles), do: {:noreply, circles ++ circle} def handle_call(:total_area, circles), do: {:reply, sum_radii(circles), circles} defp sum_radii(circles) do circles |> Enum.map(fn c -> Circle.area(c.radius) end) |> Enum.sum() end end 342