Slide 1

Slide 1 text

Elixir - Introduction

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

Programming should be about transforming data

Slide 4

Slide 4 text

Programming should be about transforming data OOP:

Slide 5

Slide 5 text

Programming should be about transforming data OOP: • classes

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Programming should be about transforming data Elixir:

Slide 10

Slide 10 text

Programming should be about transforming data Elixir: getting things done

Slide 11

Slide 11 text

Why Elixir?

Slide 12

Slide 12 text

Why Elixir? • Functional

Slide 13

Slide 13 text

Why Elixir? • Functional: • immutability

Slide 14

Slide 14 text

Why Elixir? • Functional: • immutability • pattern matching

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

Why Elixir? • Functional • Erlang VM

Slide 17

Slide 17 text

Why Elixir? • Functional • Erlang VM • Concurrency

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

Match operator • a = 1

Slide 21

Slide 21 text

Match operator • a = 1=> 1

Slide 22

Slide 22 text

Match operator • a = 1 => 1 • 1 = a

Slide 23

Slide 23 text

Match operator • a = 1 => 1 • 1 = a => 1

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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” }

Slide 32

Slide 32 text

Types

Slide 33

Slide 33 text

Types • Value Types:

Slide 34

Slide 34 text

Types • Value Types: • Integers

Slide 35

Slide 35 text

Types • Value Types: • Integers • Floats

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

Tpes • System types:

Slide 40

Slide 40 text

Types • System types: • PIDs

Slide 41

Slide 41 text

Types • System types: • PIDs • Ports

Slide 42

Slide 42 text

Types • System types: • PIDs • Ports • References

Slide 43

Slide 43 text

Types • Collection types:

Slide 44

Slide 44 text

Types • Collection types: • Tuples

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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]

Slide 52

Slide 52 text

Types • Collection types: • Keyword Lists

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

Functions

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

Organizing code

Slide 66

Slide 66 text

Organizing code defmodule SomeName do end

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

Functions and Pattern Matching

Slide 70

Slide 70 text

Functions and Pattern Matching defmodule MySum do end

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

Guard Clauses

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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!

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

List comprehensions

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

Cond, if, case

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

Structs

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

Macros

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

Concurrency

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

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" }

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

Encapsulating state by processes

Slide 101

Slide 101 text

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

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

Elixir FTW!