All About ELIXIR

Think in small functions that you string together. Async is out of the gate. Async.async.async!

I am learning Elixir and Phoenix.

Open the Shell

$ iex

Get the shell to remember your stuff

Install this… works great. I also had to use sudo make install

https://zen.id.au/how-to-make-the-elixir-shell-iex-save-history/

This will be interesting stuff about Elixir… maybe. The Pipe takes the result of your function and pushes that result into the next function. Very important.

|> is known as the pipe

Types

Check the type of a variable

i(variable)

is_atom(:hello)
is_list([1, 2, 3])
is_map(%{
  name: "Dan",
  derp: "Me"
}) # => true

Integers

42
1_000_000

Floats

42.01
1_000_000.05

:atom

nil, true, false
ModuleName

string?

"hello"
<<104, 101, 108, 108, 111>>

Map

episode = %{
  name: "Data types",
  author: "Daniel Berkompas"
}

episode.name # => "Data types"
episode[:author] # => "Daniel Berkompas"

Structs (Very similar to a map [High Level Type])

Shorthand notation

%Episode{
  title: "Data Types",
  author: "Daniel Berkompas"
}

Tuples

me = {"Daniel", 24}
{:ok, "The customer was created."}

elem(me, 0) # => "Daniel"
elem(me, 1) # => 24

Update a Tuple

put_elem(me, 1, 25) # => {"Daniel", 25}

Lists

Prepending is fast and SAFE, Appending can be VERY SLOW

list1 = [1, 2, 3, 4]
list2 = [0, list1]

Inserting into lists can also be SLOW (it will have to copy the entire beginning of the list prior to where you insert, however, the end of the tail will not need to be copied up and down)

list1 = [1, 3, 4]
list2 = List.insert_at(list1, 1, 2) # insert 2 at the second position

Character Lists

[104, 101, 108, 108, 111] # => 'hello'

Shorthand notation

'hello'

Unless calling an erlang function – stick to double quotes

Functions

add = fn(a, b) ->
  a + b
end

add.(1, 2) #=> 3

Keyword Lists (Looks very similar to maps, but under the hood they are work like a List)

[{:dick, "penis"}, {:fuck, "me"}]

List Comprehension… maybe a loop?

for c <- 'jumble', do: c

Ranges

0..100

Under the hood

%Range{first: 0, last: 100}

Regular Expressions

String.match?("hel", ~r/he/)

Pick a random Element in a list

Enum.random([1, 2, 3, 4])
Enum.random(1..100)

THE MATCH OPERATOR – VERY IMPORTANT =

name = “Daniel” age = 24

{name, age} = {“Daniel”, 24}

{name, _} = {"Daniel", 24}
# anything that starts with an _ is ignored
# _age
{name, _age} = {"Ash", 30}

{:ok, contents} = File.read(“file.txt”) # => File.read returns a tupil, and the left side returns :ok, it won’t match if there is an error, so it will stop the code if there is a problem.

All Elixir types can be matched

Matching maps

%{name: name, age: age} = %{name: “Daniel”, age: 28}

Matching structs

%Author{} = %Author{name: “daniel”, age: 24}

Matching binaries (Big topic)

“Hello, ” <> word = “Hello, World!” word # => “World!”

Math Operators

+, -, /, * , ==, !=, ===, !==, >, >=, <, <=, (=== will return false 1 === 1.0)

Modulus

rem(15, 5) # => 0 rem(5, 2) # => 1

List Operators

[1, 2, 3] ++ [4] [1, 2, 3] – [1, 3] # => [2]

Pry continue

respawn

Use pry within elixir

require IEx
IEx.pry # where you want to stop

Erlang is a pattern matching language, so functions can be defined multiple times with multiple arguments

def pick(tiles, word), do: pick(tiles, word, '')
def pick(tiles, word, int) when tiles == '' or word == '' do
  int
end
def pick(tiles, [char | chars], int) do
  cond do
    Enum.member? tiles, char ->
      pick(tiles -- [char], chars, int ++ [char])
    true ->
      pick(tiles, chars, int)
    end
  end
end

Recursion… no loops in elixir

Recursion is when a function calls itself

When writing recursion it’s

defmodule MyList do
  def length(list) do

  end
end

Tail Call Optimization

When running a recursive function over a list, Elixir will optimize when the last thing that’s called is itself. When doing recursion, ensure the last thing called is the function that’s running.

With recursion, it is common to make private functions prefixed with do_.

Examples

defmodule MyList do
  def sum(list) do
    sum(list, 0)
  end

  def sum([h|t], sum) do
    sum(t, sum + h)
  end

  def sum([], sum) do
    sum
  end
end

MyList.sum([2, 3, 4])
=> 9

defmodule MyList do
  def reverse(list) do
    reverse(list, [])
  end

  def reverse([h|t], reversed_list) do
    # make the last element the first
    reverse(t, [h|reversed_list])
  end
  def reverse([], reversed_list) do
    reversed_list
  end
end

MyList.reverse([1,2,3])
=> [3, 2, 1]


defmodule MyList do
  def length(list) do
    length(list, 0)
  end

  defp length([], count) do
    count
  end

  defp length([_|t], count) do
    length(t, count + 1)
  end

  def each([], _fun) do
    :ok
  end

  def each([h|t], fun) do
    fun.(h)
    each(t, fun)
  end

  def map(list, fun) do
    do_map(list, fun, [])
  end

  def do_map([], _fun, acc) do
    :lists.reverse(acc)
  end

  def do_map([h|t], fun, acc) do
    result = fun.(h)
    acc = [result | acc]
    do_map(t, fun, acc)
  end
end

MyList.length([1,3, 5, "shit"])
MyList.each([1,2,3], fn(n) -> IO.puts(n) end)
MyList.map([{"Daniel", 24}, {"Ash", 32}], fn({name, _age}) -> name end)

Pattern Matching

List

[h | t] = [1, 2, 3, 4]

h
=> 1

t
=> 2, 3, 4

Post Content