Skip to content

Latest commit

 

History

History
351 lines (258 loc) · 7.79 KB

README.adoc

File metadata and controls

351 lines (258 loc) · 7.79 KB

Elixir

Installing Elixier

  1. Add Repository:

wget https://packages.erlang-solutions.com/erlang-solutions_2.0_all.deb && sudo dpkg -i erlang-solutions_2.0_all.deb
  1. Update:

sudo apt-get update
  1. 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:

Data Types

STRINGS

Interpolacion:

handle = "taylor"
"My Twitter is @#{handle}"

one = 1
"Test: #{one}"

TUPLES

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

PATTERN MATCHING

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:

ELIXIR ECOSYSTEM

MIX

Build tool

HEX

Package manager

Mix command to see help: mix help

MIX CREATE AN APPLICATION

mix new application_tweet --sup

To get dependencies

mix deps.get

PASOS PARA EJECUTAR UNA FUNCION DE LA APLICACION

Compila y realiza las tareas necesarias para poder ejecutar el programa iex -S mix

cd ("lib/application_name")

Para volver a cargar un modulo: r(ModuleName.Name)

Operador Pipe

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