Elixir is special for high availability systems .
Functional
Dynamic
Inmutable
# Uses the match operator to give a true on function
name = “Han Solo”
# It creates a total new value for the new variable
name = “Luke Skywalker”
Concurrency
Reliability
Easy to read and write
Modules or classes ?
defmodule
HelloModule do def say_hi do IO.puts "Hello World !" end end
Structs
defmodule
Userdo
defstruct name: "John", roles: []
end
iex> %User{name: "Han", roles: [:pilot, :shooter]}
User{name: "Steve", roles: [:pilot, :shooter]}
Strings
Lenght.
iex> String.length "Walter White"
12
Replace
iex> String.replace("Seed","e","i")
"Siid"
Duplicate
iex> String.
duplicat("Hello",3)
"Hello Hello Hello "
Split
iex> String.
split("Hello, I'm Bond, James Bond", ",")
["Hello", " I'm Bond", " James Bond"]
Collections
List
iex> ["String", 12.3 , :atom]
["String", 12.3, :atom]
List Concatenation
iex> ["Luke", "Leia"] ++ ["Han"]
["Luke", "Leia", "Han"]
List Subtraction
iex> ["String", 12.3 , :atom] -- [:atom]
["String", 12.3]
Head / Tail
iex> hd ["Head", 222, :tail]
"Head"
iex> tl ["Head", 222, :tail]
[222, :tail]
Keyword Lists
iex> [foo: "bar", hello: "world"]
[foo: "bar", hello: "world"]
iex> list = [{:a, 1}, {:b, 2}]
[a: 1, b: 2]
iex> list ++ [{:c, 3}]
[a: 1, b: 2, c: 3]
Maps
iex> key = :one
iex> list = %{key => 1, :two => 2, "three" => 3, 4 => 4}
%{:one => 1, :two => 2, "three" => 3, 4 => 4}
# Get an specific value from a given key.
iex> Map.get(list, key)
1
# Add a tuple to the current list.
iex> Map.put(list, :five, 5)
%{:one => 1, :two => 2, "three" => 3, 4 => 4, :five => 5}
# Return the map on list format.
iex> Map.to_list(list)
[{4, 4}, {:atom, 1}, {:five, 5}, {:two, 2}, {"three", 3}]
Enum
All
iex> Enum.all?([1,2,3], fn(number) -> number < 5 end )
true
iex> Enum.all?([1,2,3], fn(number) -> number < 2 end )
false
Any
iex> Enum.any?([1,2,3], fn(number) -> number < 2 end )
true
iex> Enum.any?([1,2,3], fn(number) -> number == 5 end )
false
Chunk By
iex> Enum.chunk_by(["one", "two", "three", "four", "five"], fn(x) -> String.length(x) end)
[["one", "two"], ["three"], ["four", "five"]]
Each
iex> Enum.each(["one", "two", "three"], fn(x) -> IO.puts(x) end)
one
two
three
:ok
Map
iex> Enum.map(["one", "two"], fn(x) -> String.upcase(x) end)
["ONE", "TWO"]
Member
iex> Enum.member?(["one", "two", "three"], "three")
true
Reject
iex> Enum.reject([1,2,3,4,5,6], fn(x) -> Integer.is_even(x) end)
[1, 3, 5]
Sort
iex> Enum.sort([%{:val => 2}, %{:val => 3}, %{:val => 1}], fn(x, y) -> x[:val] > y[:val] end)
[%{val: 3}, %{val: 2}, %{val: 1}]
Unique By
iex> Enum.uniq([1, 2, 3, 2, 1])
[1, 2, 3]
Pipe Operator
The pipe operator
|>
passes the result of an expression as the first parameter of another expression.
Our problem:
# Return the final value of a product
formated_price(taxes(commision(product_value(), 0.01), 0.13))
Some OO solution:
prod_val = product_value()
prod_commision = commision(prod_val, 0.01)
prod_taxes = taxes(prod_commision, 0.13)
prod_final_value = formated_price(prod_taxes)
prod_final_value
Our Elixir Solution:
product_value()
|> commision(0.01)
|> taxes(0.13)
|> formated_price()
Pattern Matching. Isn’t it just assignment?
iex> x = 1
1
iex> 1 = x
1
iex> 2 = x
** (MatchError) no match of right hand side value: 1
Useful approaches
# We want to assign to match value with te number 2
iex> {:ok, value} = {:ok, 2}
{:ok, 2}
iex> value
2
# If the atom value :ok doesn't match It will return a fail
iex> {:ok, value} = {:none, 2}
** (MatchError) no match of right hand side value: {:none, 2}
defmodule Greet do
def say_hi(tuple) do
case tuple do
{:morning, name} ->
"Morning #{name} !"
{:evening, name} ->
"Good evening #{name} !"
_ ->
"Default Hi !!"
end
end
end
iex> Greet.say_hi({:morning, "Luke"})
"Morning Luke !"
iex> Greet.say_hi({:morning, "Han"})
"Morning Han !"
iex> Greet.say_hi({:defaut, "Nobody"})
"Default Hi !!"
defmodule Greet do
def say_hi(:morning, name) do
"Morning #{name} !"
end
def say_hi(:evening, name) do
"Good Evening #{name} !"
end
def say_hi(name) do
"Default Hi #{name} !"
end
end
iex> Greet.say_hi(:morning, "Luke")
"Morning Luke !"
iex> Greet.say_hi(:morning, "Han")
"Morning Han !"
iex> Greet.say_hi("Leila")
"Default Hi Leila !"
Conclusion
To me, having a Ruby on Rails background, Elixir seems pretty nice and I’m looking forward go deeper and deeper into this language. This entrance is part of an introduction We did in 4geeks, you can check the full video:
About 4Geeks
Founded in 2012 by Allan Porras, 4Geeks is a global software engineering and revenue growth consulting firm for Fortune 500, Global 2000 and fast-growing SMBs. Provides top solutions to multiple industries including Retail, Healthcare, Banking & Financial Services, B2B SaaS, Manufacturing and Education. HQ in the USA, and delivery centers across Latin America.