-
Add Repository:
wget https://packages.erlang-solutions.com/erlang-solutions_2.0_all.deb && sudo dpkg -i erlang-solutions_2.0_all.deb
-
Update:
sudo apt-get update
-
Install the Erlang/OTP platform and all of its applications:
sudo apt-get install esl-erlang
It is highly recommended to add Elixir’s bin path to your PATH environment variable to ease development:
It’s an ordered collection
book = {"Programming Elixir", "Dave Thomas", 25.00}
Retrieving data from a Tuple:
elem(book, 2)
25.0
Adding to a Tuple: put_elem(book, 2, 48.00)
Note
|
IN ELIXIR DATA IS INMUTABLE |
Dos tipos de archivo: ex (compilado, se carga a disco) y exs (scripts)
Ejecutar/Cargar un modulo en exs:
iex "name_of_file.exs"
Reload a file(module); This will give us a warning that we are redifining a module; inside iex type: >r(ModuleName)
Execute a function; Inside iex type: >ModuleName.function_name
Import a module (import itself is a function): import NAME_MODULE import IO
Best practices when importing Module is to limit the functions we are going to use: import MODULE_NAME, <OPTION:> [<FUNCTION_NAME>, <#>] import IO, only: [puts: 1]
Kernel is imported into every module (CompileError:imported Kernel.inspect/1 conflicts with local function), we have a function with the same name that a function already imported in module Kernel
We can import a module, EXCEPT some fucntions: import Kernel, except: [inspect: 1]
IMPORT A FILE: >import_file("name_file.exs")
CREATE AN ALIAS FOR A MODULE: alias NAME.OF.THE.MODULE.NAME
NAME.function_used This create an alias withouth especifying a custom alias
ESPECIFYING A CUSTOM ALIAS: alias NAME.OF.THE.MODULE.NAME, as: MyCustomAlias
DIRECTIVE 'required': USED TO BRING A MACRO Example of error at compile time: "warning: you must require Integer before invoking the macro Integer.is_even/1" SOLUTION: add the reuire directive: require Integer
DIRECTIVES(import, alias, require) can be Module scope or Function Scope
DEFINE A MODULE: defmodule Sample.Enum do #Your tasks here! end
In functions Elixir return the last evaluated expresion:
FUNCTION ARITY: Number of parameters
_Defining a function def first(list) do hd(list) end
_ARITY first/1 {function name} / {number of parameters}
_Example of pattern matching
def some_func(quantity, {_, _, price}) do quantity * price end
def some_func(quantity, book) do quantity * elem(book, 2) end
_Both Functions perform the same operations, but first one is more legible.
_GUARD CLAUSES _It’s a kind of precondition validation for method invocation
defmodule Sample.Calendar do def is_leap_year(year) when rem(year, 400) == 0, do: true def is leap_year(year) when rem(year, 100) == 0, do: true def is_leap_year(year) when rem(year, 4) == 0, do:true def is_leap_year(year), do: false
end
_ERROR: iex(8)> r(Sample.Calendar) ** (ArgumentError) could not load nor find module: Sample.Calendar _SOLUTION: _CARGAR EL ARCHIVO EN IEX: iex ("file_name.exs")
_Errores de Sintaxys evitan que se cargue el archivo ** (SyntaxError) calendar.exs:5: keyword argument must be followed by space after: do:
_DEFAULT_PARAMETERS _We can specify default values for parameters, if user don’t provide a value for that parameter, default value will be used
_SYNTAX: We use '\\' near to the variable name, to define a default value _EXAMPLE:
def add(list, val \\ 0) do [val | list] end
_Multiple clauses with deafult values should define a function head with the deafult values:
def first(list, val \\ nil) #This is the head function defining the default value for first/2 function
def first([head | _], _), do: head def first([], val), do: val
_PRIVATE_FUNCTIONS _SYNTAX: We use 'defp' to define a private function
_FUNCTIONS AS FIRST CLASS CITIZENS Supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables
#We pass the square function to map function Enum.map(list, &Sample.Utils.square/1)
_The amperson operator '&' is the capture operator, is a reference to the function, we especify the Arity of the function, this tells Elixir wich version of the function to use.
_ANONYMOUS FUNCTION
_Syntax: #Everything between > and end is the value’s function fn(x) → x*x end
_Example: Enum.map(list, fn(x) → x*x end)
#Tha anonymous function can take multiple parameters: fn(x, acc) → acc + x end
_Example: Enum.reduce(list, 0, fn(x, acc) → acc + x end)
_Syntax usgin the capture syntax: #&1 refers to first parameter Enum.map(list, &(&1 * &1))
#&1 refers to first parameter, &2 refers to second parameter Enum.reduce(list, 0, &(&1 + &2))
_To compile in Elixir c("name_of_file.exs")
Sample.Utils.custom_func(1, fn(x) → IO.puts(x) end)1
CONTROL FLOW
Branching logic If Cond Case
Iterating Over Data Elixit doesn’t have Loops (for, while, etc.) Elixir uses RECURSION
IF statement:
Example: def first(list) do if(length(list) == 0) do nil else hd[list] end end
Cond Operator: Example:
def day_abrevation(day) do
cond do
day == :Monday -> "M"
day == :Tuesday -> "Tu"
day == :Wednesday -> "W"
day == :Thursday -> "Th"
day == :Friday -> "F"
#To avoid error: 'no cond clause evaluated to a true'
true -> "Invalid day"
end
end
Case statement:
Examples:
def day_abbreviation_case(day) do
case day do
:Monday -> "M"
:Tuesday -> "Tu"
:Wednesday -> "W"
:Thursday -> "Th"
:Friday -> "Fr"
_ -> "Invalid Day"
end
end
def describe_date(date) do
#case using pattern matching:
case date do
{1, _, _} -> "Brand new month!"
{25, 12, _} -> "Merry Christmas"
{25, month, _} -> "Only #{12 - month} more"
{31, 10, 1517} -> "The refomration is starting"
{31, 10, _} -> "Happy Halloween"
#Using 'Guard clause' to let the last case be reached
{_, month, _} when month <= 12 -> "Just an average day"
{_, _, _} -> "Invalid month"
end
end
def send_tweet(path) do
case File.read(path) do
{:ok, data} -> Twwet.send(data)
{:error, error} -> IO.puts "Could not be loaded"
end
end
RECURSION To understand what recursion is, you must first understand recursion.
TAIL RECURSION: Tail Recursion only happens when the last operation a function performs is recursion. Tail Recursion avoid overflowing the stack
BODY RECURSION:
mix deps.get
El operador pipe |> pasa el resultado de una expresión como el primer parámetro de otra expresión.
def get_strings_to_tweet(path) do
File.read!(path)
|> String.split("\n") #Pipe Operator |>
|> Enum.map(&String.trim/1)
|> Enum.filter(&String.length(&1) <= 140)
#|> Enum.filter(fn str -> String.length(str) <= 140 end)
end