Slide 1

Slide 1 text

外傷的Elixir

Slide 2

Slide 2 text

外傷的Elixir

Slide 3

Slide 3 text

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)

Slide 4

Slide 4 text

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆) 仕事で使ってゐる⾔語 : Ruby, Elixir, Crystal Privateで使ってゐる⾔語 : Clojure (Android, SuperCollider, Processing), Haskell (Everything except JVM), ユーラル語 (yUraru yUsin) ⼀番仕事で使ひたい⾔語 : J, Lojban

Slide 5

Slide 5 text

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆) 7 libraries I made by Elixir ヾ(〃l _ l)ノ゙ http://c4se.hatenablog.com/entry/2017/12/05/232150

Slide 6

Slide 6 text

Elixir is _?_

Slide 7

Slide 7 text

defmodule Demo do def ok?(likes) do if likes do :ok else :died end end end IO.inspect Demo.ok? true

Slide 8

Slide 8 text

Elixir looks like Ruby.

Slide 9

Slide 9 text

for i <- 1..4, do: IO.puts :erlang.term_to_binary i

Slide 10

Slide 10 text

Elixir & Erlang are very close.

Slide 11

Slide 11 text

Erlang -module(momonga). -behaviour(gen_server). -export([start_link/0, init/1, handle_call/3]). start_link() -> gen_server:start_link(momonga, 0, []). init(Number) -> {ok, Number}. handle_call(bear, _From, Number) -> Number2 = Number + 0, {reply, Number2, Number2}. Elixir defmodule Momonga do use GenServer def start_link, do: GenServer.start_link __MODULE__, 0 def init(number), do: {:ok, number} def handle_call(:bear, _from, number) do number = number + 0 {:reply, number, number} end end

Slide 12

Slide 12 text

Elixir looks familiar than Erlang.

Slide 13

Slide 13 text

1..4 |> Enum.map(fn i when rem(i, 2) == 0 -> true _ -> false end) |> Enum.map(&Task.async fn -> if &1, do: Process.sleep(4000), else: IO.puts("No wait") end) |> Enum.each(&Task.await/1)

Slide 14

Slide 14 text

Elixir has some nice language feature. * Strong pattern match that originated from Prologʼs unification. * Chain functions |> fluently |> by “pipe operator”. * Easy parallel computing (Task, GenStage, …).

Slide 15

Slide 15 text

Elixir has nice & fast Rails like WAF called “Phoenix”.

Slide 16

Slide 16 text

We are Rubyist. So we can be Alchemist!

Slide 17

Slide 17 text

?

Slide 18

Slide 18 text

Elixir is _?_

Slide 19

Slide 19 text

Elixir was Clojure

Slide 20

Slide 20 text

Elixir was Clojure on Erlang VM

Slide 21

Slide 21 text

Elixir was Clojure on Erlang VM that looks like Ruby.

Slide 22

Slide 22 text

Elixirʼs syntax & standard library are like Ruby. Elixir is a functional programming language with immutable data. Elixir has supervisor architecture same as Erlang.

Slide 23

Slide 23 text

Elixirʼs syntax & standard library are like Ruby. Elixir is a functional programming language with immutable data. Elixir has supervisor architecture same as Erlang.

Slide 24

Slide 24 text

x = [1] y = x y = [2 | y] IO.inspect x # => [1] IO.inspect y # => [2, 1]

Slide 25

Slide 25 text

Variables can be reassigned. Data is immutable. Immutable data makes app thread safe.

Slide 26

Slide 26 text

result = state.f value {result, state} = f value, state

Slide 27

Slide 27 text

p y x.f # x has pointer to y. p y IO.inspect y y = f x, y IO.inspect y

Slide 28

Slide 28 text

# x1, …, x10000 have pointers to large_data. f x1 f x1, large_data

Slide 29

Slide 29 text

Immutable data has no hidden state (unlike OOP). Function has no implicit arguments because thereʼs no shared data.

Slide 30

Slide 30 text

The best way is to learn functional programming. (I recommend Clojure & Haskell.) But most apps should have hidden state & shared state. How can I do?

Slide 31

Slide 31 text

defmodule Momonga do def start, do: loop 0 defp loop(number) do receive do {:bear, from} -> number = number + 0 send from, {self(), number} loop number _ -> loop number end end end momonga = spawn Momonga, :start, [] send momonga, {:bear, self()} IO.inspect receive do: ({^momonga, number} -> number)

Slide 32

Slide 32 text

defmodule Momonga do use GenServer def start, do: GenServer.start __MODULE__, 0 def init(number), do: {:ok, number} def handle_call(:bear, _from, number) do number = number + 0 {:reply, number, number} end end {:ok, momonga} = Momonga.start IO.inspect GenServer.call(momonga, :bear)

Slide 33

Slide 33 text

{:ok, momonga} = Agent.start fn -> 0 end IO.inspect Agent.get_and_update(momonga, fn number -> number = number + 0 {number, number} end)

Slide 34

Slide 34 text

Process has a hidden state. Agent & GenServer is useful.

Slide 35

Slide 35 text

defmodule Momonga do use GenServer def start, do: GenServer.start __MODULE__, 0, name: __MODULE__ def init(number), do: {:ok, number} def handle_call(:bear, _from, number) do number = number + 0 {:reply, number, number} end end Momonga.start IO.inspect GenServer.call(Momonga, :bear)

Slide 36

Slide 36 text

:ets.new :momonga, [:public, :named_table] :ets.insert :momonga, {:number, 0} :ets.safe_fixtable :momonga, true number = :ets.lookup(:momonga, :number)[:number] + 0 :ets.insert :momonga, {:number, number} :ets.safe_fixtable :momonga, false IO.inspect number

Slide 37

Slide 37 text

Registered process has shared state. ETS, DETS, Mnesia can read/write parallel. We can use external DB of course.

Slide 38

Slide 38 text

Elixirʼs syntax & standard library are like Ruby. Elixir is a functional programming language with immutable data. Elixir has supervisor architecture same as Erlang.

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

Your app should be parallel & fault tolerant. Elixir is better but itʼs not a silver bullet.

Slide 41

Slide 41 text

Elixir has some mechanism. * Monitor * Link * Supervisor * Registry Elixir has some good restriction. * Immutable data * Sending messages canʼt fail * No shared state (Thereʼs some exception) * Process doesn't block other processes (Thereʼs some exception) But testing parallel fault is too-oo-oo hard for human.

Slide 42

Slide 42 text

Elixir is better but itʼs not a silver bullet. We are searching the best…