Elixir

35
@marekkirejczyk

Transcript of Elixir

@marekkirejczyk

Founder & animatorAgile Coach

Shareholder & advisor VP of engineering

Some random Rails problems

● gem explosion (e.g. background processing)● websockets● scaling, deployment, transparent failover● ddd, dci, microservices

Still there is no real competition to RoR on horizont? Or is there?

It is all getting complex

Elixir?

● Compiled to Erlang VM● Created by Jose Valim

Elixir?

● Purely functional (no state!)● Concurrency oriented, distributed● Fault tolerant● Strong metaprogramming● Growing Ecosystem

Elixir is purely functional

Some basic data types

● (Immutable) Lists: [1, 2, 3]● (Immutable) Tuples: {:meaning_of_life, 42}● (Immutable) Strings: “Hello Elixir”

No loops!

sum = 0for(i = 0; i < array.length; i++) { sum += array[i]}

List & recursion

def sum_list([head|tail], accumulator) do sum_list(tail, head + accumulator)end

sum_list([1,2,3], 0)

List & Enum

Enum.reduce([1, 2, 3], 0, fn(x, acc) -> x + acc end)

or

Enum.reduce([1, 2, 3], 0, &+/2)

Lists & Streams

1..100_000 |> Stream.map(&(&1 * 3)) |> Stream.filter(odd?) |> Enum.sum

No classes

class String ...end

String.new

defmodule Math do def sum(a, b) do a + b endend

Modules

Modules

s = “hello”

String.length s

Kernel.byte_size s

byte_size s

● No inheritance● No mixins● No interfaces● No OOP, DCI

No classes

Elixir encourage SOLID design

Protocols

defprotocol Blank do @doc "Returns true if data is blank" def blank?(data)end

Protocols implementationdefimpl Blank, for: Integer do def blank?(_), do: falseend

defimpl Blank, for: List do def blank?([]), do: true def blank?(_), do: falseend

Pattern matching and tuples

{a, b, c} = {:hello, "world", 42}

{:hello, _, c} = {:hello, "world", 42}

{:yellow, _, c} = {:hello, "world", 42}

Why Pattern matching

● tuples are used all the time for everything (remember: no classes!)

● exceptions usage is discouraged● managing messages (see later)

Concurrency oriented, distributed

Spawning a process is easy

spawn fn -> 1 + 2 end

Sending a message is easy

send self(), {:hello, "world"}

Receiving

receive do {:hello, msg} -> msg {:world, msg} -> "won't match"end

State

The way to store state in elixir is to spawn processes.

Concurrency oriented, distributed

● GenServer● GenEvent● Supervisors● Distributed configuration

Metaprogramming

Quote

quote do: sum(1, 2, 3){:sum, [], [1, 2, 3]}

quote do: 1 + 2{:+, [context: Elixir, import: Kernel], [1, 2]}

defmacro macro_unless(clause, expression) do quote do if(!unquote(clause), do: unquote(expression)) endend

And… what else?

● Mix● www.phoenixframework.org

elixir-lang.org

Questions?@marekkirejczyk