October 14, 2019
40

# Pinball Elixir

Intro to Elixir with Pinball

October 14, 2019

## Transcript

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

be more powerful. 3
4. ### @bitcapulet Purpose To get you excited about Elixir. So you’ll

be more powerful. So your companies will start using it. 4
5. ### @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
6. ### @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

22. ### @bitcapulet If you state your complexity clearly, it's easier to

solve complex problems. 22
23. ### @bitcapulet If you state your complexity clearly, it's easier to

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

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

solve complex problems. This is what ELIXIR brings to the table. 25

27. ### @bitcapulet Rob those phone companies blind! 16 years of searching

and building. 27
28. ### @bitcapulet Rob those phone companies blind! 16 years of searching

and building. THEN 20 years of open-source improvements. 28
29. ### @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!

49

75
76. ### @bitcapulet [ , , , ] a b c d

def get_odd(list) do a = Enum.at(list, 0) c = Enum.at(list, 2) [a, c] end 76

78

] 79

] 80

] 81

] 82
83. ### @bitcapulet [ , , , ] a b c d

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

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

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

def get_odd(list) do [a, _b, c, _d] list [a, c] end 86

} 97

} 98

99

107

120
121. ### @bitcapulet def get_name(map) do %{name: var} map var end get_name(%{})

** (MatchError) no match of right hand side value: %{} 121

125. ### @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!

127. ### @bitcapulet %{"name" => _, "age" => _, "fav.capt." => "Picard"

} my_map %{name: _, age: _, fav_capt: "Picard" } my_map 127

129. ### @bitcapulet %{"name" => _, "age" => _, "fav.capt." => "Picard"

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

} my_map [ %{fav_capt: "Kirk"}, %{fav_capt: "Picard"}, %{fav_capt: "Sisko"}, %{fav_capt: "Janeway"}, ] list_of_maps 130
131. ### @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
132. ### @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
133. ### @bitcapulet [ , , , ] [ , , ,

] 133 VALUES!
134. ### @bitcapulet [ , , , ] [ , , ,

] 134 VALUES!
135. ### @bitcapulet [ , , , ] [ , , ,

] 135 VALUES!
136. ### @bitcapulet [ , , , ] [ , , ,

] 136 VALUES!
137. ### @bitcapulet [ , , , ] [ , , ,

] 137 VALUES!

141. ### @bitcapulet >%{} Of course it equal sign! Everyone guess that!

Why you use clipart in first place? 141

behind. 145
146. ### @bitcapulet case 2 + 2 4 -> "hurray" 3 ->

"oops" end 146

147
148. ### @bitcapulet case do_math(2) 4 -> "hurray" 3 -> "oops" var

-> "Got number: #{var}" end 148
149. ### @bitcapulet case do_math(2) 4 -> "hurray" 3 -> "oops" var

-> "Got number: #{var}" end 149
150. ### @bitcapulet case do_math(2) 4 -> "hurray" 3 -> "oops" var

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2, 3] -> "123 list" var -> "got number: #{var}" end 174

end 204
205. ### @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
206. ### @bitcapulet Interactive Elixir (1.6.1) - press Ctrl+C to exit (type

h() ENTER for help) iex(1)> 206
207. ### @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

209. ### @bitcapulet iex(2)> pid = spawn(MyModule, :phil, 0) #PID<0.97.0> iex(3)> Process.alive?(pid)

true iex(4)> 209
210. ### @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
211. ### @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

213. ### @bitcapulet A process is a recursive function that holds state

and lives at an address with a mailbox. <0.194.0> 213

215. ### @bitcapulet >%{} We back in OO-land! How this not just

uglier-Java?! 215

218. ### @bitcapulet x x x x x x x x x

x x x x x 218

242. ### @bitcapulet def run(list) do [a,b,c,d] = list [d,c,b,a] end 242

What if > 4 items?
243. ### @bitcapulet run([1,2,3,4,5]) ** (MatchError) no match of right hand side

value: [1, 2, 3, 4, 5] 243

object?

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

Now reverse 5!
252. ### @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
253. ### @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
254. ### @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
255. ### @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
256. ### @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
257. ### @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
258. ### @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

261. ### @bitcapulet A process is a recursive function that holds state

and lives at an address with a mailbox. <0.194.0> 261

263
264. ### @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
265. ### @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
266. ### @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
267. ### @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
268. ### @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
269. ### @bitcapulet {:ok, pid} = GenServer.start_link(Phil, "arg") def init(_args), do: 0

Spawn a GenServer 269
270. ### @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
271. ### @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

gets old

274. ### @bitcapulet GenServer.start_link(Phil, "arg", name: :phil) GenServer.cast(:phil, "a present with your

name on it") Fee pid Registry 274
275. ### @bitcapulet GenServer.start_link(Phil, "arg", name: :phil) GenServer.cast(:phil, "a present with your

name on it") pid = Process.whereis(:phil) Fee pid Registry 275

278. ### @bitcapulet defmodule CaptJoan do use Supervisor def init(_args) do children

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

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

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

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

= [ {Phil, []}, {Phil, []}, {Phil, []} ] Supervisor.init(children, strategy: :one_for_one) end end 282

286. ### @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
287. ### @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
288. ### @bitcapulet defmodule AdmiralRavi do use Supervisor def init(_args) do children

= [ {CaptJoan, []}, {CaptJoan, []}, {CaptJoan, []} ] Supervisor.init(children, strategy: :one_for_one) end end 288

it")
306. ### @bitcapulet ◍ timeouts ◍ linking processes ◌ monitoring ◌ trapping

exits ◍ error handling Other benefits 306
307. ### @bitcapulet defmodule AdmiralRavi do use Supervisor def init(_args) do children

= [ {CaptJoan, []}, {CaptJoan, []}, {CaptJoan, []} ] Supervisor.init(children, strategy: :one_for_one) end end 307

315. ### @bitcapulet def fav_capt(:kirk) do {:error, "Are you kidding me?"} end

def fav_capt(:picard) do {:ok, "You chose wisely."} end 315

317. ### @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
318. ### @bitcapulet capt = :kirk case fav_capt(capt) {:ok, msg} -> msg

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

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

{:error, _msg} -> Log.error("oops") {_, _msg} -> Log.error("What?!") end 320
321. ### @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
322. ### @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
323. ### @bitcapulet def respond({:ok, msg}) do Log.info("That went well.") msg end

def respond({:error, _msg}) do Log.error("oops") end 323

334. ### @bitcapulet capt |> beam_to_planet() |> meet_aliens() |> romance?() |> case

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

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

do {:ok, details} -> log(details) :error -> kill_off_extra() end 336

338. ### @bitcapulet [1, 2, 3] |> Enum.map(fn i -> i +

1 end) # [2, 3, 4] 338
339. ### @bitcapulet [1, 2, 3] |> Enum.map(fn i -> i +

1 end) |> Enum.sum() # 9 339
340. ### @bitcapulet %{} It late. Wrap it up. 340

GenServer.call(:circle_keeper, :total_area)

talk. 347

350. ### @bitcapulet %{} It matter you do job. And you happy

with job you do. 350

351

353. ### @bitcapulet %{} This language not make more money. But maybe

make more happy. 353

376. ### @bitcapulet Pinball Elixir Presentation template by SlidesCarnival 376 Adrian P.

Dunston @bitcapulet [email protected] joinpapa.com