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

Pinball Elixir

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

Pinball Elixir

Intro to Elixir with Pinball

Avatar for Adrian Dunston

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