Slide 1

Slide 1 text

Elixir Joseph Wilk

Slide 2

Slide 2 text

Erlang VM

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Blocks Syntax Signals Concurrency

Slide 5

Slide 5 text

OTP Pattern Matching Macros

Slide 6

Slide 6 text

Macros Destructing Pattern Matching

Slide 7

Slide 7 text

Pattern Matching |> (Pipe operator) DCGs / Monad

Slide 8

Slide 8 text

Elixir Erlang VM BEAM byte code compiles

Slide 9

Slide 9 text

Elixir Erlang VM BEAM byte code compiles Invoke Erlang 0 runtime cost and visa-versa

Slide 10

Slide 10 text

Interop :erlang.make_tuple(10, []) -module(bstring). -export([downcase/1]). downcase(Bin) -> 'Elixir.String':downcase(Bin). Erlang in Elixir Elixir in Erlang

Slide 11

Slide 11 text

Install $ brew install elixir iex, mix, elixir $ wget http://bit.ly/1aN4Ftt Erlang, version R16B https://www.erlang-solutions.com/downloads/download-erlang-otp $ brew tap homebrew/versions $ brew link erlang-r16 Elixir

Slide 12

Slide 12 text

$ brew install elixir iex, mix, elixir $ wget http://bit.ly/1aN4Ftt Erlang, version R16B https://www.erlang-solutions.com/downloads/download-erlang-otp Elixir $ brew tap homebrew/versions $ brew link erlang-r16 Install iex, mix, elixir

Slide 13

Slide 13 text

Anti Pattern OO Object Orientated Programming

Slide 14

Slide 14 text

No Objects No Classes No Inheritance defmodule Yes do use Amrita.Sweet import Support end

Slide 15

Slide 15 text

Everything is an Expressions https://github.com/joearms/erl2

Slide 16

Slide 16 text

defmodule A do def ping do "pong" end IO.puts "ping" end defmodule B do def ping do A.ping end end defmodule C do def ping do B.ping end end

Slide 17

Slide 17 text

Modules Pattern matching Polymorphism > protocols Records Macros

Slide 18

Slide 18 text

{ x, y, _ } = { 10, 2, 3 } IO.inspect x #=> 10 IO.inspect y #=> 2 Pattern Matching

Slide 19

Slide 19 text

if is_list(thing) && !Enum.empty?(thing) do IO.puts "matches" else IO.puts "no match" end case thing do [_] -> IO.puts "matches" _ -> IO.puts "no match" end Pattern Matching

Slide 20

Slide 20 text

Pattern Matching defmodule Eating do def meeting([head| tail]) do [rules(head) | meeting(tail)] end def meeting([]) do [] end def rules({ :lion, :cat }), do: "lion eats cat" def rules({ :lion, :shark }), do: "shark eats lion" def rules({ :rabbit, other }), do: "rabbit eats #{other}" def rules({ a, b }), do: "#{a} eats #{b}" def rules({ a }), do: "#{a} eats itself" def rules(_), do: "nothing gets eaten" end Eating.meeting([{:lion, :cat}, {:lion, :shark}])

Slide 21

Slide 21 text

Protocols defprotocol Enumerable do def reduce(item) #... end end defimpl Enumerable, for: Set do def reduce(set, acc, fun), do: Set.reduce(set, acc, fun) end Enum.reduce HashSet.new, [], fn element, accum -> List.concat(element, accum) end

Slide 22

Slide 22 text

Records compile time pattern defrecord ExUnit.Test, [:name, :case, :failure, :time] do @moduledoc """ A record that keeps information about the test. It is received by formatters and also accessible in the metadata under the key `:test`. """ end def handle_cast({:test_finished, ExUnit.Test[failure: nil] = test}, config) do if config.trace do IO.puts success(trace_test_result(test)) else IO.write success(".") end { :noreply, config.update_tests_counter(&1 + 1) } end

Slide 23

Slide 23 text

Macros defmacro hello do end

Slide 24

Slide 24 text

Controlling resolution of scope Domain specific language (or something-fast something-slow) 10 |> IO.puts

Slide 25

Slide 25 text

{ name, meta, args } [...] :atoms ints/strings

Slide 26

Slide 26 text

{ :+, [line: 1], [1,2] } 1 + 2

Slide 27

Slide 27 text

{ _, _, _ } defmacro hello do end Macro tuples { _, _, _ } tuples

Slide 28

Slide 28 text

Amrita https://github.com/josephwilk/amrita A polite, well mannered and thoroughly upstanding testing framework for Elixir fact "about factorial" do factorial(0) |> ! 0 factorial(0) |> 1 list_of_factorials = Enum.map 0..3, fn n -> factorial(n) end list_of_factorials |> contains 1 list_of_factorials |> !contains 2 list_of_factorials |> [ _, 1, _, 6 ] end

Slide 29

Slide 29 text

fact "mock with a _ wildcard" do provided [MocksTest.Funk.hip?(_) |> false] Funk.hip?(:yes) |> falsey Funk.hip?(:whatever) |> falsey end end

Slide 30

Slide 30 text

fact "mock with a _ wildcard" do provided [MocksTest.Funk.hip?(_) |> false] Funk.hip?(:yes) |> falsey Funk.hip?(:whatever) |> falsey end end |>(MocksTest.Funk.hip?(_), false)

Slide 31

Slide 31 text

fact "mock with a _ wildcard" do provided [MocksTest.Funk.hip?(_) |> false] Funk.hip?(:yes) |> falsey Funk.hip?(:whatever) |> falsey end end [{ :|>, [line: 2], [ , false] }] { {:., [line: 2], } , [line: 2], [:_] } [ { :__aliases__, [line: 2], [:MocksTest, :Funk] }, :hip? ] |>(MocksTest.Funk.hip?(_), false)

Slide 32

Slide 32 text

defmodule Provided.Parse do defexception Error, form: [] do def message(exception) do "Amrita could not understand your `provided`:\n" <> " " <> Macro.to_string(exception.form) <> "\n" <> " Make sure it uses this format: [Module.fun |> :return_value]" end end def prerequisites(forms) do prerequisites = Enum.map(forms, fn form -> extract(form) end) Provided.Prerequisites.new(prerequisites) end defp extract({:|>, _, [{fun, _, args}, value]}) do { module_name, function_name } = extract(fun) { module_name, function_name, args, value } end defp extract({:., _, [ns, method_name]}) do { extract(ns), method_name } end defp extract({:__aliases__, _, ns}) do Module.concat ns end defp extract(form) do raise Error.new(form: form) end end

Slide 33

Slide 33 text

defmodule Provided.Parse do defexception Error, form: [] do def message(exception) do "Amrita could not understand your `provided`:\n" <> " " <> Macro.to_string(exception.form) <> "\n" <> " Make sure it uses this format: [Module.fun |> :return_value]" end end def prerequisites(forms) do prerequisites = Enum.map(forms, fn form -> extract(form) end) Provided.Prerequisites.new(prerequisites) end defp extract({:|>, _, [{fun, _, args}, value]}) do { module_name, function_name } = extract(fun) { module_name, function_name, args, value } end defp extract({:., _, [ns, method_name]}) do { extract(ns), method_name } end defp extract({:__aliases__, _, ns}) do Module.concat ns end defp extract(form) do raise Error.new(form: form) end end

Slide 34

Slide 34 text

iex> quote do: IO.puts iex> quote do fn(x) -> x end end

Slide 35

Slide 35 text

Immutability “Elixir assignments are compiled down to Static Single Assignment.” defmodule Immutable do def mutation do x = 1 # => v0 = 1 x = 2 # => v1 = 2 x = 3 # => v2 = 3 end end

Slide 36

Slide 36 text

Performance

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

Thanks