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. Karol Galanciak • Full-stack developer at • Twitter: @Azdaroth •

    blog: karolgalanciak.com, blog.ragnarson.com
  2. Programming should be about transforming data OOP: • classes •

    objects • state • modelling real world with hierarchies
  3. Match operator • a = 1 => 1 • 1

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

    = a => 1 • 2 = a => (MatchError) no match of right hand side value: 1 • list = [1, 2, 3]
  5. 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
  6. 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
  7. 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
  8. 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
  9. 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” }
  10. Types • Value Types: • Integers • Floats • Atoms

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

    (:like_ruby_symbol) • Ranges (1..100) • Regular expressions (%r{regexp})
  12. Types • Collection types: • Tuples • => {:ok, ”content”}

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

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

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

    • => {:error, ”error message”} • Lists • => [1, 2, 3] • => [1, 2, 3] ++ [4] • => [1, 2, 3] -- [1]
  16. 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]
  17. Types • Collection types: • Keyword Lists • => [name:

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

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

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

    ”Elixir”, status: ”awesome”] • => [name: ”Elixir”, status: ”awesome”][:name] • Maps • %{”ruby” => ”oop”, :elixir => ”functional”} • %{”ruby” => ”oop”, :elixir => ”functional”}[:elixir]
  21. Functions • add_one = fn n -> n + 1

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

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

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

    end • add_one.(1) => 2 • square = &(&1 * &1) • => square.(3) => 9 • len = &Enum.count/1
  25. 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
  26. Organizing code defmodule SomeName do def hello_world do IO.puts ”hello

    world” end end SomeName.hello_world => ”hello world”
  27. Functions and Pattern Matching defmodule MySum do def sum(array), do:

    _sum(0, array) defp _sum(total, []), do: total end
  28. 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
  29. 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
  30. 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
  31. 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!
  32. Pipe operator - |> ps awux | grep spring |

    awk '{print $2}' | xargs kill
  33. Pipe operator - |> [1, 2, 3] |> Enum.map(&(&1 *

    &1)) |> Enum.map(&to_string/1) |> Enum.map(&(&1 <> "0")) |> Enum.join(" - ") => "10 - 40 - 90"
  34. List comprehensions for x <- [1, 2, 3], y <-

    [10, 20, 30], x * y > 20, do: x + y => [31, 22, 32, 13, 23, 33]
  35. Cond, if, case if 1 == 1 do ”I’m truthy”

    else ”I’m falsey” end unless 1 == 1, do: ”error”, else: ”ok”
  36. 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
  37. Cond, if, case case File.open(”some_file.exs”) do { :ok, file }

    => IO.puts ”success” { :error, reason } => IO.puts ”error: #{reason}” end
  38. Structs defmodule User do defstruct fullname: "", email: "" end

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

    has_email?(user) do String.length(user.email) > 0 end end
  40. 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
  41. Concurrency defmodule Spawnee do def hi do receive do {

    sender, message } -> send sender, { :ok, "Hi #{message}!"} end end end
  42. 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" }
  43. 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
  44. 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
  45. 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
  46. 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
  47. 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