Elixir - introduction

Elixir - introduction

347a1b64f3a6e38981bc99b53919e2b1?s=128

karol.galanciak

November 18, 2015
Tweet

Transcript

  1. 2.

    Karol Galanciak • Full-stack developer at • Twitter: @Azdaroth •

    blog: karolgalanciak.com, blog.ragnarson.com
  2. 8.

    Programming should be about transforming data OOP: • classes •

    objects • state • modelling real world with hierarchies
  3. 24.
  4. 25.

    Match operator • a = 1 => 1 • 1

    = a => 1 • 2 = a => (MatchError) no match of right hand side value: 1
  5. 26.

    Match operator • a = 1 => 1 • 1

    = a => 1 • 2 = a => (MatchError) no match of right hand side value: 1 • list = [1, 2, 3]
  6. 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
  7. 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
  8. 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
  9. 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
  10. 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” }
  11. 32.
  12. 37.

    Types • Value Types: • Integers • Floats • Atoms

    (:like_ruby_symbol) • Ranges (1..100)
  13. 38.

    Types • Value Types: • Integers • Floats • Atoms

    (:like_ruby_symbol) • Ranges (1..100) • Regular expressions (%r{regexp})
  14. 47.

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

    • => {:error, ”error message”} • Lists
  15. 48.

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

    • => {:error, ”error message”} • Lists • => [1, 2, 3]
  16. 49.

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

    • => {:error, ”error message”} • Lists • => [1, 2, 3] • => [1, 2, 3] ++ [4]
  17. 50.

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

    • => {:error, ”error message”} • Lists • => [1, 2, 3] • => [1, 2, 3] ++ [4] • => [1, 2, 3] -- [1]
  18. 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]
  19. 53.
  20. 54.

    Types • Collection types: • Keyword Lists • => [name:

    ”Elixir”, status: ”awesome”] • => [name: ”Elixir”, status: ”awesome”][:name]
  21. 55.

    Types • Collection types: • Keyword Lists • => [name:

    ”Elixir”, status: ”awesome”] • => [name: ”Elixir”, status: ”awesome”][:name] • Maps
  22. 56.

    Types • Collection types: • Keyword Lists • => [name:

    ”Elixir”, status: ”awesome”] • => [name: ”Elixir”, status: ”awesome”][:name] • Maps • %{”ruby” => ”oop”, :elixir => ”functional”}
  23. 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]
  24. 58.
  25. 60.

    Functions • add_one = fn n -> n + 1

    end • add_one.(1) => 2
  26. 61.

    Functions • add_one = fn n -> n + 1

    end • add_one.(1) => 2 • square = &(&1 * &1)
  27. 62.

    Functions • add_one = fn n -> n + 1

    end • add_one.(1) => 2 • square = &(&1 * &1) • => square.(3) => 9
  28. 63.

    Functions • add_one = fn n -> n + 1

    end • add_one.(1) => 2 • square = &(&1 * &1) • => square.(3) => 9 • len = &Enum.count/1
  29. 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
  30. 68.

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

    world” end end SomeName.hello_world => ”hello world”
  31. 72.

    Functions and Pattern Matching defmodule MySum do def sum(array), do:

    _sum(0, array) defp _sum(total, []), do: total end
  32. 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
  33. 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
  34. 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
  35. 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!
  36. 78.

    Pipe operator - |> ps awux | grep spring |

    awk '{print $2}' | xargs kill
  37. 79.

    Pipe operator - |> [1, 2, 3] |> Enum.map(&(&1 *

    &1)) |> Enum.map(&to_string/1) |> Enum.map(&(&1 <> "0")) |> Enum.join(" - ") => "10 - 40 - 90"
  38. 81.

    List comprehensions for x <- [1, 2, 3], y <-

    [10, 20, 30], x * y > 20, do: x + y => [31, 22, 32, 13, 23, 33]
  39. 83.
  40. 84.

    Cond, if, case if 1 == 1 do ”I’m truthy”

    else ”I’m falsey” end unless 1 == 1, do: ”error”, else: ”ok”
  41. 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
  42. 86.

    Cond, if, case case File.open(”some_file.exs”) do { :ok, file }

    => IO.puts ”success” { :error, reason } => IO.puts ”error: #{reason}” end
  43. 87.
  44. 90.

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

    user = %User{fullname: ”name”} user.fullname = > ”name”
  45. 91.

    Structs defmodule User do defstruct fullname: "", email: "" def

    has_email?(user) do String.length(user.email) > 0 end end
  46. 92.
  47. 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
  48. 96.

    Concurrency defmodule Spawnee do def hi do receive do {

    sender, message } -> send sender, { :ok, "Hi #{message}!"} end end end
  49. 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" }
  50. 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
  51. 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
  52. 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
  53. 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
  54. 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