{%hackmd SyQbZi4Mr %}
## Not familiar with Elixir? Let me do a simple intro in 30 minutes
借用您半小時,請問有聽過 elixir 嗎?
by [PastLeo](https://pastleo.me), a little developer at [5xruby](https://5xruby.tw)
---
## Outline
* Functional Syntax
* Macro
* Process, message passing
* Application
* A database migration tool
* Resources
---
## Functional Syntax
---
#### let's say I want a function...
```elixir
Demo.sum_ints("1,3,asdf,5")
# => 9
```
---
## let me demo how to create this function
```elixir
test "sum_ints" do
assert Demo.sum_ints(
"1,3,asdf,5"
) == 9
end
```
---
### pipe, pattern matching
```elixir
defmodule Demo do
def sum_ints(str) do
String.split(str, ",")
|> Enum.map(&Integer.parse/1)
|> Enum.flat_map(&valid_int/1)
|> Enum.sum()
end
defp valid_int({int, _}), do: [int]
defp valid_int(_), do: []
end
```
---
## Macro
---
#### a glimpse of ecto
a bridge between database in elixir
```elixir
query = from u in "users",
where: u.age > 18,
select: u.name
```
[Ecto.Query document](https://hexdocs.pm/ecto/Ecto.Query.html#content)
---
#### how macro works
```elixir
quote do 1 + 1 end
```
```elixir
defmodule Demo.Macro do
defmacro hello(ast) do
IO.inspect(ast)
end
end
```
---
#### let's bring `begin` from ruby
```elixir
begin do
1/0
rescue
:error
end
# => :error
```
---
#### `quote` and `unquote`
```elixir
defmacro begin(
do: do_block, rescue: rescue_block
) do
quote do
try do
unquote(do_block)
rescue
_ -> unquote(rescue_block)
end
end
end
```
---
#### actually...
* [defmacro if](https://github.com/elixir-lang/elixir/blob/v1.6.4/lib/elixir/lib/kernel.ex#L2840)
* [defmacro defmodule](https://github.com/elixir-lang/elixir/blob/v1.6.4/lib/elixir/lib/kernel.ex#L3589)
* [defmacro def](https://github.com/elixir-lang/elixir/blob/v1.6.4/lib/elixir/lib/kernel.ex#L3834)
* [defmacro defmacro](https://github.com/elixir-lang/elixir/blob/v1.6.4/lib/elixir/lib/kernel.ex#L3886)
---
## Process, message passing
---
#### why concurrent/parallel is so hard

[reddit 'Perfect demonstration of a race condition.'](https://www.reddit.com/r/ProgrammerHumor/comments/2skae8/perfect_demonstration_of_a_race_condition/)
---
#### start a process
```elixir
spawn(fn -> ... end)
```
not system process nor thread
---
#### start a lot of processes
```elixir
Enum.each(1..10000, fn(_) ->
spawn(fn ->
IO.inspect(self())
end)
end)
```
---
#### Message passing
```elixir
me = self()
spawn(fn ->
send(me, self())
end)
receive do
x -> IO.inspect(x)
end
```
---
#### Fibonacci Service
```elixir
defmodule Demo.Process do
def fibonacci_service do
receive do
x -> fibonacci(x) |> IO.puts()
end
fibonacci_service()
end
end
```
---
#### One step forward: OTP
* shorthand of [Open Telecom Platform](https://en.wikipedia.org/wiki/Open_Telecom_Platform)
* process communication
* [GenServer](https://hexdocs.pm/elixir/GenServer.html)
* process maintaining
* [Supervisor](https://hexdocs.pm/elixir/Supervisor.html)
* code replacement
---
#### Tip of the iceberg of phoenix server processes

---
## Application
#### the migration tool
---
#### Purpose

---
#### How to match
```elixir
[1, 2, 3] -- [1, 3]
# => [2]
```
```elixir
[source html nodes] --
[all possible html nodes for a template]
== []
```
```elixir
[required html nodes for a template] --
[source html nodes]
== []
```
---
#### using [GenStage](https://hexdocs.pm/gen_stage/GenStage.html) and [Flow](https://hexdocs.pm/flow/Flow.html) to do full migrate
* postgres streaming producer
* data source is only one big query
* use `Flow` to utilize all CPUs
* result speed:
* around 86000+ users, each of them has 5 pages in average
* 430000+ pages in 20 minutes
---
#### listening to postgres trigger
* user changed
* `|>` postgres trigger
* `|>` postgres channel
* `|>` elixir process event loop
* `|>` re-migrate on the specific user
* [postgrex notification module](https://github.com/elixir-ecto/postgrex/blob/master/lib/postgrex/notifications.ex)
---
#### more processes
* states:
* currently being migrated user
* excluded user
* queued user
* success rate, statistic
* progress bar
---
#### how it looks like when running

---
## Learning Resource
* [Elixirschool](https://elixirschool.com/en/)
* [Elixir official guide](https://elixir-lang.org/getting-started/introduction.html)
* [Elixir for Programmers (Video, Dave Thomas)](https://codestool.coding-gnome.com/courses/elixir-for-programmers)
* [Elixir official learning resources](https://elixir-lang.org/learning.html)
---
## Thanks for listening!
#### Any questions?
{"title":"Not familiar with Elixir? Let me do a simple intro in 30 minutes","tags":"elixir, slide, rubyelixirconf2018","type":"slide","slideOptions":{"spotlight":{"enabled":true,"size":80,"presentingCursor":"default","toggleSpotlightOnMouseDown":false,"spotlightOnKeyPressAndHold":90,"initialPresentationMode":true,"disablingUserSelect":false,"fadeInAndOut":500},"allottedMinutes":5}}