Slide 1

Slide 1 text

Mix it Up With Elixir Approachable Functional Programming Andrew Bredow @andrewbredow

Slide 2

Slide 2 text

Goals • Understand Elixir's history • Explore Elixir's syntax and conventions • Walk through a real world app • Learn more about the ecosystem • Get excited!

Slide 3

Slide 3 text

Elixir - History • Version 1.0 - Fall, 2014 • First appeared in early 2012 • Started development in 2011 • Built on top of Erlang VM • Traces back to 1986, open sourced in 1998

Slide 4

Slide 4 text

Why Erlang? If somebody came to me and wanted to pay me a lot of money to build a large scale message handling system that really had to be up all the time, could never afford to go down for years at a time, I would unhesitatingly choose Erlang to build it in. - Tim Bray

Slide 5

Slide 5 text

Why Erlang? WebScale™ before The Web

Slide 6

Slide 6 text

WAT Erlang?

Slide 7

Slide 7 text

Why Elixir? • All features of Erlang • Scalable • Fault Tolerant • Functional • Immutable • OTP • Fun!

Slide 8

Slide 8 text

Where to Use? EVERYWHERE! (almost)

Slide 9

Slide 9 text

Installing Elixir From source! kiex, kerl

Slide 10

Slide 10 text

• Scripts: my_script.exs • Compiled: my_executable.ex Naming Files

Slide 11

Slide 11 text

Running Code $ iex
 iex> import_file "some_file.ex" 
 $ elixir "my_file.exs"

Slide 12

Slide 12 text

Running Your Code

Slide 13

Slide 13 text

Building Something

Slide 14

Slide 14 text

Voting App • 1 vote per entry • Vote for unlimited entries • Vote must be cast from Grand Rapids • Users can see the current winner

Slide 15

Slide 15 text

Building Blocks integer 42, 1_000_000, 0b1010, 0xcafe, 0o765 float 1.0, 0.125, .314159e1, 314159e-5 range 1..10, 5..-25, 42.906554..43.01148 boolean true, false atom :success, :is_string?, :"grand rapids" string "test", "hellõ" pid #PID<0.64.0> port #Port<0.3766> Basic/System Types

Slide 16

Slide 16 text

Building Blocks list ["A", "B", "C"], [false, 56, :boo] tuple {:ok, 42}, {"a", "b", "c"} keyword list [name: "Andrew", destination: "LAX"] map %{"MI" => "Michigan", "CA" => "California"} binary << 1, 2 >> Collection Types

Slide 17

Slide 17 text

Getting Started

Slide 18

Slide 18 text

Start A Project • Mix • 1 Project Format to Rule Them All • Walk through the project to see what we have

Slide 19

Slide 19 text

Building Blocks Pattern Matching x = 5
 person = %{
 name: "Andrew",
 occupation: %{ field: "Computer", title: "Software Developer"}
 }
 %{name: my_name, occupation: %{field: _, title: my_title}} = person 
 my_name # "Andrew" 
 my_title # "Software Developer"

Slide 20

Slide 20 text

Building Blocks Functions add = fn a, b -> a + b end
 defmodule Greeter
 def say_hello(name \\ "Friend") do
 "Hello, #{name}"
 end
 end 
 add = &(&1 + &2) 
 puts = &IO.puts/1

Slide 21

Slide 21 text

Basic Voting

Slide 22

Slide 22 text

Guard Clauses defmodule Greeter
 def say_hello(name) when is_string(name) do
 "Hello, #{name}"
 end
 
 def say_hello(name) when is_integer(name) do
 42 + name end
 end Pattern Matching On Steroids

Slide 23

Slide 23 text

Restrict Location

Slide 24

Slide 24 text

Processes • Foundational to maintaining state in Elixir • 2 Foundations: • spawn/1 • receive/1

Slide 25

Slide 25 text

Run As Server Process

Slide 26

Slide 26 text

Program Flow IO.puts(multiply(add(round_down(12), 45), 10)) 
 first_value = round_down(12)
 second_value = add(first_value, 45)
 third_value = multiply(second_value, 10)
 IO.puts(third_value) 
 12
 |> round_down
 |> add(45)
 |> multiply(10)
 |> IO.puts

Slide 27

Slide 27 text

Tail Recursion [head|tail] = ["A", "B", "C", "D"]
 #head: "A", tail: ["B", "C", "D"] 
 ["A"|["B","C","D"]]
 #["A", "B", "C", "D"] 
 def count_list([head|tail]) do
 1 + count_list(tail)
 end
 def count_list([]), do: 0 
 def downcase_list([head|tail]) do
 [String.downcase(head)|downcase_list(tail)]
 end
 def downcase_list([]), do: []


Slide 28

Slide 28 text

Calculate Winner

Slide 29

Slide 29 text

Tests • ExUnit • DocTests

Slide 30

Slide 30 text

Testing

Slide 31

Slide 31 text

Major Leagues • Distribution • OTP / Genserver • Supervision trees • Hot deploys • Elixir allows you to harness years of advancements

Slide 32

Slide 32 text

Testing

Slide 33

Slide 33 text

What Else is There?

Slide 34

Slide 34 text

Structs defmodule User do
 defstruct id: nil,
 name: nil
 
 def valid?(user) do
 String.length(user.name) > 0
 end
 end 
 me = %User{id: 1, name: "Andrew Bredouw"} 
 me = %{ me | name: "Andrew Bredow" }

Slide 35

Slide 35 text

Types defmodule User do
 defstruct id: nil,
 name: nil
 @type t :: %User{id: integer, name: String.t}
 
 def valid?(user)
 String.length(user.name) > 0
 end
 end 
 me = %User{user_id: 1, name: "Andrew Bredouw"} 
 me = %{ me | name: "Andrew Bredow" }

Slide 36

Slide 36 text

Protocols defprotocol URI do
 def to_query(params)
 end 
 URI.to_query(%{bar: "foo", event: "baz"}) # ** (UndefinedFunctionError) undefined function: URI.to_query/1 Achieving polymorphism

Slide 37

Slide 37 text

Protocols defimpl URI, for: Map do
 def to_query(params) do
 Enum.map(params, fn {first, second} ->
 "#{first}=#{second}" end)
 |> Enum.join("&")
 end
 end 
 URI.to_query(%{bar: "foo", event: "baz"}) # "bar=foo&event=baz" Achieving Polymorphism

Slide 38

Slide 38 text

More... • Metaprogramming • Comprehensions • Streams • OTP

Slide 39

Slide 39 text

The Ecosystem • Hex - http://hex.pm • GitHub • Ecto • Phoenix

Slide 40

Slide 40 text

Learning Resources #elixir-lang Elixir Source Code!

Slide 41

Slide 41 text

Summary @andrewbredow