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

Elixir - introduction

Elixir - introduction

karol.galanciak

November 18, 2015
Tweet

More Decks by karol.galanciak

Other Decks in Programming

Transcript

  1. Elixir - Introduction

    View Slide

  2. Karol Galanciak
    • Full-stack developer at
    • Twitter: @Azdaroth
    • blog: karolgalanciak.com, blog.ragnarson.com

    View Slide

  3. Programming should be
    about transforming data

    View Slide

  4. Programming should be
    about transforming data
    OOP:

    View Slide

  5. Programming should be
    about transforming data
    OOP:
    • classes

    View Slide

  6. Programming should be
    about transforming data
    OOP:
    • classes
    • objects

    View Slide

  7. Programming should be
    about transforming data
    OOP:
    • classes
    • objects
    • state

    View Slide

  8. Programming should be
    about transforming data
    OOP:
    • classes
    • objects
    • state
    • modelling real world with hierarchies

    View Slide

  9. Programming should be
    about transforming data
    Elixir:

    View Slide

  10. Programming should be
    about transforming data
    Elixir: getting things done

    View Slide

  11. Why Elixir?

    View Slide

  12. Why Elixir?
    • Functional

    View Slide

  13. Why Elixir?
    • Functional:
    • immutability

    View Slide

  14. Why Elixir?
    • Functional:
    • immutability
    • pattern matching

    View Slide

  15. Why Elixir?
    • Functional:
    • pattern matching
    • immutability
    • side-effects free

    View Slide

  16. Why Elixir?
    • Functional
    • Erlang VM

    View Slide

  17. Why Elixir?
    • Functional
    • Erlang VM
    • Concurrency

    View Slide

  18. Why Elixir?
    • Functional
    • Erlang VM
    • Concurrency
    • Syntax

    View Slide

  19. Why Elixir?
    • Functional
    • Erlang VM
    • Concurrency
    • Syntax
    • Erlang compatible

    View Slide

  20. Match operator
    • a = 1

    View Slide

  21. Match operator
    • a = 1=> 1

    View Slide

  22. Match operator
    • a = 1 => 1
    • 1 = a

    View Slide

  23. Match operator
    • a = 1 => 1
    • 1 = a => 1

    View Slide

  24. Match operator
    • a = 1 => 1
    • 1 = a => 1
    • 2 = a

    View Slide

  25. Match operator
    • a = 1 => 1
    • 1 = a => 1
    • 2 = a => (MatchError) no match of right hand side
    value: 1

    View Slide

  26. Match operator
    • a = 1 => 1
    • 1 = a => 1
    • 2 = a => (MatchError) no match of right hand side
    value: 1
    • list = [1, 2, 3]

    View Slide

  27. Match operator
    • a = 1 => 1
    • 1 = a => 1
    • 2 = a => (MatchError) no match of right hand side
    value: 1
    • list = [1, 2, 3]
    • [a, b, c] = list

    View Slide

  28. Match operator
    • a = 1 => 1
    • 1 = a => 1
    • 2 = a => (MatchError) no match of right hand side
    value: 1
    • list = [1, 2, 3]
    • [a, b, c] = list
    • [1, b, 3] = list

    View Slide

  29. Match operator
    • a = 1 => 1
    • 1 = a => 1
    • 2 = a => (MatchError) no match of right hand side value: 1
    • list = [1, 2, 3]
    • [a, b, c] = list
    • [1, b, 3] = list
    • [2, 2, 3] = list

    View Slide

  30. Match operator
    • a = 1 => 1
    • 1 = a => 1
    • 2 = a => (MatchError) no match of right hand side value: 1
    • list = [1, 2, 3]
    • [a, b, c] = list
    • [1, b, 3] = list
    • [2, 2, 3] = list
    • [d, _, _] = list

    View Slide

  31. Match operator
    • a = 1 => 1
    • 1 = a => 1
    • 2 = a => (MatchError) no match of right hand side value: 1
    • list = [1, 2, 3]
    • [a, b, c] = list
    • [1, b, 3] = list
    • [2, 2, 3] = list
    • [d, _, _] = list
    • { status, _ } = { :ok, ”content” }

    View Slide

  32. Types

    View Slide

  33. Types
    • Value Types:

    View Slide

  34. Types
    • Value Types:
    • Integers

    View Slide

  35. Types
    • Value Types:
    • Integers
    • Floats

    View Slide

  36. Types
    • Value Types:
    • Integers
    • Floats
    • Atoms (:like_ruby_symbol)

    View Slide

  37. Types
    • Value Types:
    • Integers
    • Floats
    • Atoms (:like_ruby_symbol)
    • Ranges (1..100)

    View Slide

  38. Types
    • Value Types:
    • Integers
    • Floats
    • Atoms (:like_ruby_symbol)
    • Ranges (1..100)
    • Regular expressions (%r{regexp})

    View Slide

  39. Tpes
    • System types:

    View Slide

  40. Types
    • System types:
    • PIDs

    View Slide

  41. Types
    • System types:
    • PIDs
    • Ports

    View Slide

  42. Types
    • System types:
    • PIDs
    • Ports
    • References

    View Slide

  43. Types
    • Collection types:

    View Slide

  44. Types
    • Collection types:
    • Tuples

    View Slide

  45. Types
    • Collection types:
    • Tuples
    • => {:ok, ”content”}

    View Slide

  46. Types
    • Collection types:
    • Tuples
    • => {:ok, ”content”}
    • => {:error, ”error message”}

    View Slide

  47. Types
    • Collection types:
    • Tuples
    • => {:ok, ”content”}
    • => {:error, ”error message”}
    • Lists

    View Slide

  48. Types
    • Collection types:
    • Tuples
    • => {:ok, ”content”}
    • => {:error, ”error message”}
    • Lists
    • => [1, 2, 3]

    View Slide

  49. Types
    • Collection types:
    • Tuples
    • => {:ok, ”content”}
    • => {:error, ”error message”}
    • Lists
    • => [1, 2, 3]
    • => [1, 2, 3] ++ [4]

    View Slide

  50. Types
    • Collection types:
    • Tuples
    • => {:ok, ”content”}
    • => {:error, ”error message”}
    • Lists
    • => [1, 2, 3]
    • => [1, 2, 3] ++ [4]
    • => [1, 2, 3] -- [1]

    View Slide

  51. Types
    • Collection types:
    • Tuples
    • => {:ok, ”content”}
    • => {:error, ”error message”}
    • Lists
    • => [1, 2, 3]
    • => [1, 2, 3] ++ [4]
    • => [1, 2, 3] -- [1]
    • => 1 in [1, 2, 3]

    View Slide

  52. Types
    • Collection types:
    • Keyword Lists

    View Slide

  53. Types
    • Collection types:
    • Keyword Lists
    • => [name: ”Elixir”, status: ”awesome”]

    View Slide

  54. Types
    • Collection types:
    • Keyword Lists
    • => [name: ”Elixir”, status: ”awesome”]
    • => [name: ”Elixir”, status: ”awesome”][:name]

    View Slide

  55. Types
    • Collection types:
    • Keyword Lists
    • => [name: ”Elixir”, status: ”awesome”]
    • => [name: ”Elixir”, status: ”awesome”][:name]
    • Maps

    View Slide

  56. Types
    • Collection types:
    • Keyword Lists
    • => [name: ”Elixir”, status: ”awesome”]
    • => [name: ”Elixir”, status: ”awesome”][:name]
    • Maps
    • %{”ruby” => ”oop”, :elixir => ”functional”}

    View Slide

  57. Types
    • Collection types:
    • Keyword Lists
    • => [name: ”Elixir”, status: ”awesome”]
    • => [name: ”Elixir”, status: ”awesome”][:name]
    • Maps
    • %{”ruby” => ”oop”, :elixir => ”functional”}
    • %{”ruby” => ”oop”, :elixir => ”functional”}[:elixir]

    View Slide

  58. Functions

    View Slide

  59. Functions
    • add_one = fn n -> n + 1 end

    View Slide

  60. Functions
    • add_one = fn n -> n + 1 end
    • add_one.(1) => 2

    View Slide

  61. Functions
    • add_one = fn n -> n + 1 end
    • add_one.(1) => 2
    • square = &(&1 * &1)

    View Slide

  62. Functions
    • add_one = fn n -> n + 1 end
    • add_one.(1) => 2
    • square = &(&1 * &1)
    • => square.(3) => 9

    View Slide

  63. Functions
    • add_one = fn n -> n + 1 end
    • add_one.(1) => 2
    • square = &(&1 * &1)
    • => square.(3) => 9
    • len = &Enum.count/1

    View Slide

  64. Functions
    • add_one = fn n -> n + 1 end
    • add_one.(1) => 2
    • square = &(&1 * &1)
    • => square.(3) => 9
    • len = &Enum.count/1
    • len.([1, 2, 3]) => 3

    View Slide

  65. Organizing code

    View Slide

  66. Organizing code
    defmodule SomeName do
    end

    View Slide

  67. Organizing code
    defmodule SomeName do
    def hello_world do
    IO.puts ”hello world”
    end
    end

    View Slide

  68. Organizing code
    defmodule SomeName do
    def hello_world do
    IO.puts ”hello world”
    end
    end
    SomeName.hello_world
    => ”hello world”

    View Slide

  69. Functions and Pattern
    Matching

    View Slide

  70. Functions and Pattern
    Matching
    defmodule MySum do
    end

    View Slide

  71. Functions and Pattern
    Matching
    defmodule MySum do
    def sum(array), do: _sum(0, array)
    end

    View Slide

  72. Functions and Pattern
    Matching
    defmodule MySum do
    def sum(array), do: _sum(0, array)
    defp _sum(total, []), do: total
    end

    View Slide

  73. Functions and Pattern
    Matching
    defmodule MySum do
    def sum(array), do: _sum(0, array)
    defp _sum(total, []), do: total
    defp _sum(total, [head | tail]), do: _sum(total +
    head, tail)
    end

    View Slide

  74. Functions and Pattern
    Matching
    defmodule MySum do
    def sum([head | tail]), do: _sum(head, tail)
    defp _sum(total, []), do: total
    defp _sum(total, [head | tail]), do: _sum(total +
    head, tail)
    end
    MySum.sum([1, 2, 3]) => 6

    View Slide

  75. Guard Clauses

    View Slide

  76. Guard Clauses
    defmodule NumberType do
    def print_type(num) when num < 0 do
    IO.puts "#{num} - I’m negative!"
    end
    def print_type(num) when num == 0 do
    IO.puts "I’m 0!"
    end
    def print_type(num) when num > 0 do
    IO.puts "#{num} - I’m positive!"
    end
    end

    View Slide

  77. Guard Clauses
    defmodule NumberType do
    def print_type(num) when num < 0 do
    IO.puts "#{num} - I’m negative!"
    end
    def print_type(num) when num == 0 do
    IO.puts "I’m 0!"
    end
    def print_type(num) when num > 0 do
    IO.puts "#{num} - I’m positive!"
    end
    end
    • NumberType.print_type(1) => 1 - I’m positive!
    • NumberType.print_type(0) => I’m 0!
    • NumberType.print_type(-1) => -1 - I’m negative!

    View Slide

  78. Pipe operator - |>
    ps awux | grep spring | awk '{print $2}' | xargs kill

    View Slide

  79. Pipe operator - |>
    [1, 2, 3]
    |> Enum.map(&(&1 * &1))
    |> Enum.map(&to_string/1)
    |> Enum.map(&(&1 <> "0"))
    |> Enum.join(" - ")
    => "10 - 40 - 90"

    View Slide

  80. List comprehensions

    View Slide

  81. List comprehensions
    for x <- [1, 2, 3], y <- [10, 20, 30], x * y > 20, do: x + y
    => [31, 22, 32, 13, 23, 33]

    View Slide

  82. Cond, if, case

    View Slide

  83. Cond, if, case
    if 1 == 1 do
    ”I’m truthy”
    else
    ”I’m falsey”
    end

    View Slide

  84. Cond, if, case
    if 1 == 1 do
    ”I’m truthy”
    else
    ”I’m falsey”
    end
    unless 1 == 1, do: ”error”, else: ”ok”

    View Slide

  85. Cond, if, case
    cond do
    rem(number, 3) == 0 and rem(number, 5) == 0 -> "FizzBuzz"
    rem(number, 3) == 0 -> "Fizz"
    rem(number, 5) == 0 -> "Buzz"
    true -> number
    end

    View Slide

  86. Cond, if, case
    case File.open(”some_file.exs”) do
    { :ok, file } => IO.puts ”success”
    { :error, reason } => IO.puts ”error: #{reason}”
    end

    View Slide

  87. Structs

    View Slide

  88. Structs
    defmodule User do
    defstruct fullname: "", email: ""
    end

    View Slide

  89. Structs
    defmodule User do
    defstruct fullname: "", email: ""
    end
    user = %User{fullname: ”name”}

    View Slide

  90. Structs
    defmodule User do
    defstruct fullname: "", email: ""
    end
    user = %User{fullname: ”name”}
    user.fullname = > ”name”

    View Slide

  91. Structs
    defmodule User do
    defstruct fullname: "", email: ""
    def has_email?(user) do
    String.length(user.email) > 0
    end
    end

    View Slide

  92. Macros

    View Slide

  93. Macros
    defmodule Test do
    require Plus
    Plus.add_n(3)
    Plus.add_n(4)
    end
    Test.add_3(4) => 7
    Test.add_4(5) => 9

    View Slide

  94. Macros
    defmodule Plus do
    defmacro add_n(number) do
    name = String.to_atom("add_#{number}")
    quote do
    def unquote(name)(other_number) do
    other_number + unquote(number)
    end
    end
    end
    end

    View Slide

  95. Concurrency

    View Slide

  96. Concurrency
    defmodule Spawnee do
    def hi do
    receive do
    { sender, message } -> send sender, { :ok, "Hi
    #{message}!"}
    end
    end
    end

    View Slide

  97. Concurrency
    defmodule Spawnee do
    def hi do
    receive do
    { sender, message } -> send sender, { :ok, "Hi
    #{message}!"}
    end
    end
    end
    pid = spawn(Spawnee, :hi, [])
    send pid, { self, "Elixir" }

    View Slide

  98. Concurrency
    defmodule Spawnee do
    def hi do
    receive do
    { sender, message } -> send sender, { :ok, "Hi #{message}!"}
    end
    end
    end
    pid = spawn(Spawnee, :hi, [])
    send pid, { self, "Elixir" }
    receive do
    { :ok, message } -> IO.puts message
    end

    View Slide

  99. Concurrency
    defmodule Spawnee do
    def hi do
    receive do
    { sender, message } -> send sender, { :ok, "Hi #{message}!"}
    end
    end
    end
    pid = spawn(Spawnee, :hi, [])
    send pid, { self, "Elixir" }
    receive do
    { :ok, message } -> IO.puts message
    end
    =>
    Hi Elixir!
    :ok

    View Slide

  100. Encapsulating state by
    processes

    View Slide

  101. Encapsulating state by
    processes
    defmodule Counter do
    def start do
    do_count(0)
    end
    defp do_count(current_number) do
    receive do
    { :increment, listener } ->
    send listener, current_number + 1
    do_count(current_number + 1)
    end
    end
    end

    View Slide

  102. Encapsulating state by
    processes
    defmodule Counter do
    def start do
    do_count(0)
    end
    defp do_count(current_number) do
    receive do
    { :increment, listener } ->
    send listener, current_number + 1
    do_count(current_number + 1)
    end
    end
    end
    counter_pid = spawn(Counter, :start, [])
    send(counter_pid, { :increment, self })
    receive do count -> count end
    => 1

    View Slide

  103. Encapsulating state by
    processes
    defmodule Counter do
    def start do
    do_count(0)
    end
    defp do_count(current_number) do
    receive do
    { :increment, listener } ->
    send listener, current_number + 1
    do_count(current_number + 1)
    end
    end
    end
    counter_pid = spawn(Counter, :start, [])
    send(counter_pid, { :increment, self })
    receive do count -> count end
    => 1
    send(counter_pid, { :increment, self })
    receive do count -> count end
    => 2

    View Slide

  104. Elixir FTW!

    View Slide