Translate

Mostrando las entradas para la consulta elixir ordenadas por relevancia. Ordenar por fecha Mostrar todas las entradas
Mostrando las entradas para la consulta elixir ordenadas por relevancia. Ordenar por fecha Mostrar todas las entradas

lunes, 5 de febrero de 2018

Empezando con Elixir 11

Sigils

Elixir proporciona una sintaxis alternativa para representar y trabajar con literales. Un Sigils comenzará con una tilde ~ seguido de un carácter. El núcleo Elixir nos proporciona algunos Sigils integrados, sin embargo, es posible crear el nuestros propios Sigils  cuando necesitamos extender el lenguaje.

Los Sigils disponibles son:

~ C Genera una lista de caracteres sin escape ni interpolación
~ c Genera una lista de caracteres con escape e interpolación
~ R Genera una expresión regular sin escape ni interpolación
~ r Genera una expresión regular con escape e interpolación
~ S Genera una cadena sin escape ni interpolación
~ s Genera una cadena con escape e interpolación
~ W Genera una lista de palabras sin escape ni interpolación
~ w Genera una lista de palabras con escape e interpolación
~ N genera una estructura NaiveDateTime

Una lista de delimitadores incluye:

<...> Un par de signos menor/mayor
{...} Un par de llaves
[...] Un par de corchetes
(...) Un par de paréntesis
| ... | Un par de barras verticales
/.../ Un par de barras diagonales
"..." Un par de comillas dobles
'...' Un par de comillas simples

Lista de caracteres

~c y ~C generan una lista de caracteres:

iex> ~c/2 + 7 = #{2 + 7}/
'2 + 7 = 9'

iex> ~C/2 + 7 = #{2 + 7}/

'2 + 7 = \#{2 + 7}'

Podemos ver que la minúscula ~c interpola el cálculo, mientras que la mayúscula ~C no. Veremos que esta propiedad de mayúsculas o minúsculas es común en todos los sigils.

Expresiones regulares

~ r y ~ R se usan para representar expresiones regulares. Los podemos crear justo en el momento de utilizarlo o para usar dentro de las funciones de Regex. Por ejemplo:

iex> re = ~r/elixir/
~r/elixir/

iex> "Elixir" =~ re
false

iex> "elixir" =~ re
true

Podemos ver que en la primera prueba de igualdad, no coincide con la expresión regular. Esto se debe a que está en mayúscula. Debido a que Elixir admite expresiones regulares compatibles con Perl (PCRE), podemos agregar i al final para desactivar la distinción entre mayúsculas y minúsculas.

iex> re = ~r/elixir/i
~r/elixir/i

iex> "Elixir" =~ re
true

iex> "elixir" =~ re
true

Además, Elixir proporciona la API de expresiones regulares que está construida sobre la biblioteca de expresiones regulares de Erlang. Es decir que podemos utilizarlos en funciones, veamos un ejemplo:

iex> string = "100_000_000"
"100_000_000"

iex> Regex.split(~r/_/, string)
["100", "000", "000"]

String

~s y ~S se utilizan para generar cadenas. Por ejemplo:

iex> ~s/the cat in the hat on the mat/
"the cat in the hat on the mat"

iex> ~S/the cat in the hat on the mat/
"the cat in the hat on the mat"

¿Cuál es la diferencia? La diferencia es similar a los otros sigils que vimos. La respuesta es la interpolación y el uso de secuencias de escape. Si tomamos otro ejemplo:

iex> ~s/welcome to elixir #{String.downcase "school"}/
"welcome to elixir school"

iex> ~S/welcome to elixir #{String.downcase "school"}/
"welcome to elixir \#{String.downcase \"school\"}"

Word List

La lista de palabras puede ser útil de vez en cuando. Puede ahorrar tiempo, pulsaciones de teclas y posiblemente reducir la complejidad dentro del código. Por ejemplo:

iex> ~w/i love elixir school/
["i", "love", "elixir", "school"]

iex> ~W/i love elixir school/
["i", "love", "elixir", "school"]

Podemos ver que el delimitador es espacio en blanco. Sin embargo, no hay diferencia entre estos dos ejemplos. De nuevo, la diferencia viene con las secuencias de interpolación y escape. Por ejemplo:

iex> ~w/i love #{'e'}lixir school/
["i", "love", "elixir", "school"]

iex> ~W/i love #{'e'}lixir school/
["i", "love", "\#{'e'}lixir", "school"]

NaiveDateTime

Un NaiveDateTime puede ser útil para crear rápidamente una estructura para representar un DateTime sin una zona horaria.

En su mayor parte, deberíamos evitar crear una estructura NaiveDateTime directamente. Sin embargo, es muy útil para la coincidencia de patrones. Por ejemplo:

iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07") == {:ok, ~N[2015-01-23 23:50:07]}

Crear un Sigils

Uno de los objetivos de Elixir es ser un lenguaje de programación extensible. No debería sorprender entonces que pueda crear fácilmente sus propios sigils personalizados. En este ejemplo, crearemos un sigils para convertir una cadena en mayúscula. Como ya existe una función para esto en Elixir Core (String.upcase/1), envolveremos nuestro sigils alrededor de esa función.

iex> defmodule MySigils do
...>   def sigil_u(string, []), do: String.upcase(string)
...> end

iex> import MySigils
nil

iex> ~u/elixir school/
ELIXIR SCHOOL

Primero definimos un módulo llamado MySigils y dentro de ese módulo, creamos una función llamada sigil_u. Como no existe un sigilo en el espacio de sigilo existente, lo usaremos. El _u indica que deseamos usar u como el carácter después de ~ . La definición de la función debe tomar dos argumentos, una entrada y una lista.


domingo, 5 de marzo de 2023

Primeros pasos con Phoenix


Antes de empezar de manera muy rápida aclaremos que Phoenix es un framework web o para hacer API en Elixir. 

Phoenix está escrito en Elixir, y nuestro código de aplicación también estará escrito en Elixir. Por ende el primer paso es instalar Elixir , en mi caso lo voy a instalar con asdf

asdf plugin-add elixir https://github.com/asdf-vm/asdf-elixir.git

asdf install elixir 1.14.3-otp-25

El código de Elixir se compila en el código de bytes de Erlang para ejecutarse en la máquina virtual de Erlang. Sin Erlang, el código de Elixir no tiene una máquina virtual para ejecutarse, por lo que también debemos instalar Erlang. 

asdf plugin add erlang https://github.com/asdf-vm/asdf-erlang.git

asdf install erlang 25.0.3

Y ahora vamos a setear las versiones: 

asdf global erlang 25.0.3

asdf global elixir 1.14.3-otp-25

Pero pueden ver como instalar en su equipo en el siguiente link : https://elixir-lang.org/install.html

Cuando instalamos Elixir siguiendo las instrucciones de la página de instalación de Elixir, normalmente también obtendremos Erlang. Para checkear esto hacemos : 

emanuel@crespo:~$ elixir --version

Erlang/OTP 25 [erts-13.1.5] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]


Elixir 1.14.3 (compiled with Erlang/OTP 25)


También podemos escribir erl que es el comando para la relp de Erlang. 

Si acabamos de instalar Elixir por primera vez, también necesitaremos instalar el administrador de paquetes Hex. Hex es necesario para ejecutar una aplicación de Phoenix (mediante la instalación de dependencias) y para instalar cualquier dependencia adicional que podamos necesitar en el camino. En mi caso es : 

mix local.hex


Ahora debemos instalar phoenix, en mi caso voy a instalar la ultima versión

mix archive.install hex phx_new 

Por lo visto, ya esta todo instalado, ahora vamos a crear nuestro primer proyecto: 

mix phx.new hello_world --module HelloWorld

Y si todo salio bien vamos a ejecutarlo: 

cd hello_world/
mix phx.server

Si vamos a http://localhost:4000/ nos aparecerá una pagina. 

Van a ver que tira como 5000 errores porque no configuramos la base de datos, pero eso lo vamos hacer en el proximo post. 

Dejo link; https://www.phoenixframework.org/

viernes, 2 de mayo de 2014

Elixir



José Valim decidió crear un lenguaje para aumentar la productividad en la plataforma Erlang y lo consiguió. El nombre de este lenguaje es Elixir

Elixir es lenguaje de programación de propósito general, concurrente; este lenguaje es funcional. Además esta construido sobre la máquina virtual de Erlang. Se trata de un lenguaje dinámico con una sintaxis flexible y apoyado en macros; que aprovecha las capacidades de Erlang para construir aplicaciones concurrentes y distribuidas, tolerables a fallos, con actualizaciones de código en caliente.

Elixir también soporta pattern matching, el polimorfismo a través de protocolos (similar a Clojure), alias y estructuras de datos asociativos (generalmente conocido como hashes en otros lenguajes de programación).

Por útimo, Elixir y Erlang comparten el mismo byte code. Esto significa que puede invocar código Erlang de Elixir (y viceversa) sin ningún tipo de transformación o impacto en el rendimiento. Esto permite a los desarrolladores mezclar la expresividad de Elixir con la robustez y el rendimiento de Erlang.

Veamos un ejemplo, es bueno comenzar con un "hola mundo" pero para hacerlo más interesante vamos a hacerlo dentro de un modulo:

defmodule Hello do
  IO.puts "Defining the function world"

  def world do
    IO.puts "Hello World"
  end

  IO.puts "Function world defined"
end


Hello.world


Los módulos son simplemente una forma lógica de organizar el código, no se debe confundir con una clase, ya que no tiene propiedades.


Este código retorna:


Defining the function world
Function world define

Hello World

Si queremos probar el ejemplo solo debemos guardar el ejemplo como Hello.ex y luego debemos compilar, para eso ejecutamos el relp de Elixir y compilamos de la siguiente manera:


Interactive Elixir
iex> c("Hello.ex")
[Hello]
iex> Hello.hello
Defining the function world
Function world define
Hello World
:ok

Elixir tiene varias características que lo hacen un muy buen lenguaje para programar, como por ejemplo tiene pattern matching, veamos un ejemplo:


def serve_drinks({ User, name, age }) when age < 21 do
  raise "No way #{name}!"
end

def serve_drinks({ User, name, age }) do
  # Code that serves drinks!
end

serve_drinks User.get("John")
#=> Raises "No way John!" if John is under 21

Otra característica interesante es que la documentación es muy importante para elixir. Por lo que provee mecanismos que facilitan documentar nuestro código, veamos un ejemplo:

defmodule MyModule do
  @moduledoc """
  Documentation for my module. With **formatting**.
  """

  @doc "Hello"
  def world do
    "World"
  end
end

Y como es de esperar, Elixir provee herramientas que facilitan el acceso a la documentación.


iex> h MyModule
# MyModule

Documentation for my module. With **formatting**.

Elixir es un lenguaje que nació para facilitar el desarrollo en la plataforma Erlang y vaya que lo logro!

Dejo link:
http://elixir-lang.org/


miércoles, 8 de marzo de 2017

Empezando con Elixir


Antes que nada tenemos que instalarlo, eso es fácil y más fácil si se utiliza linux, les dejo la guía de instalación: http://elixir-lang.org/install.html

Ojo antes que antes a leer un poco: http://emanuelpeg.blogspot.com.ar/search/label/Elixir

Si lo instalamos bien al escribir lo siguiente, veremos la versión:

% elixir -v
Erlang/OTP 19 [erts-8.0.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Elixir 1.4.0

Empesemos utilizando el modo interactivo, como para amigarnos con el lenguaje. Para acceder a esto debemos tipear iex en la consola:

 ~ $ iex
Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:6:6] [async-threads:10] [kernel-poll:false]

Interactive Elixir (1.1.0-dev) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>

Y el cursor quedara en espera de comandos y nosotros podemos empezar a jugar!!!

Vamos a probar cosas básicas del lenguaje:

iex> 2+3
5
iex> 2+3 == 5
true
iex> String.length("The quick brown fox jumps over the lazy dog")
43

Veamos los datos básicos:

Integers

iex> 255
255

Podemos usar octales, binarios o hexadecimales:

iex> 0b0110
6
iex> 0o644
420
iex> 0x1F
31

Floats
En Elixir, el número flotante requiere un decimal antes/después del punto y permite usar la notación exponencial.

iex> 3.14
3.14
iex> .14
** (SyntaxError) iex:2: syntax error before: '.'
iex> 1.0e-10
1.0e-10

Booleans
Elixir soporta los valores True y False. Y todo es verdadero excepto false y nil

iex> true
true
iex> false
false

Atoms
Un átomo es una constante cuyo nombre es su valor. Si está familiarizado con Ruby, estos son sinónimos de Símbolos:

iex> :foo
:foo
iex> :foo == :bar
false
Los booleanos verdadero y falso son también los átomos: true y: false respectivamente.

iex> true |> is_atom
true
iex> :true |> is_boolean
true
iex> :true === true
true

Los nombres de los módulos en Elixir son también átomos. MyApp.MyModule es un átomo válido, incluso si aún no se ha declarado dicho módulo.

iex> is_atom(MyApp.MyModule)
true
Los átomos también se utilizan para referenciar módulos de las bibliotecas Erlang, incluidas las importadas.

iex> :crypto.rand_bytes 3
<<23, 104, 108>>

Strings o cadenas.
Las cadenas en Elixir tienen codificación UTF-8 y están envueltas entre comillas dobles:

iex> "Hello"
"Hello"
iex> "dziękuję"
"dziękuję"
Los String soportan espacios en blancos y enters, etc:

iex> "foo
...> bar"
"foo\nbar"
iex> "foo\nbar"
"foo\nbar"

Elixir incluye más tipos de datos complejos.

Operación.

Elixir soporta los operadores básicos como : +, -, *, y "/" .

iex> 2 + 2
4
iex> 2 - 1
1
iex> 2 * 5
10
iex> 10 / 5
2.0

Si necesita división entera o el resto de división, Elixir viene con dos funciones útiles para lograr esto:

iex> div(10, 5)
2
iex> rem(10, 3)
1

Boolean
Elixir provee operadores booleanos: ||, &&, y !

iex> -20 || true
-20
iex> false || 42
42

iex> 42 && true
true
iex> 42 && nil
nil

iex> !42
false
iex> !false
true

Hay tres operadores adicionales cuyo primer argumento debe ser un booleano (verdadero o falso):

iex> true and 42
42
iex> false or true
true
iex> not false
true
iex> 42 and true
** (ArgumentError) argument error: 42
iex> not 42
** (ArgumentError) argument error

Comparación
Elixir provee los operadores para comparar como otros lenguajes:

iex> 1 > 2
false
iex> 1 != 2
true
iex> 2 == 2
true
iex> 2 <= 3
true
Además provee la comparación estricta:  ===:

iex> 2 == 2.0
true
iex> 2 === 2.0
false

Una característica importante de Elixir es que cualquier dos tipos pueden ser comparados; Esto es particularmente útil en la clasificación. No necesitamos memorizar el orden de clasificación, pero es importante estar consciente de el

number < atom < reference < function < port < pid < tuple < map < list < bitstring
Esto puede llevar a algunas comparaciones interesantes, pero válidas, que no puede encontrar en otros Lenguajes:

iex> :hello > 999
true
iex> {:hello, :world} > [1, 2, 3]
false

String Interpolation
Si has usado Ruby o Scala, string interpolation en Elixir te va sonar familiar:

iex> name = "Sean"
iex> "Hello #{name}"
"Hello Sean"

String Concatenation
Para concatenar 2 cadenas utilizamos el operador <> :

iex> name = "Sean"
iex> "Hello " <> name
"Hello Sean"

Este es el primer post de algunos más que nos acerquen a este lenguaje.

Dejo link:



martes, 21 de febrero de 2017

Try Elixir

Codeschool nos regala otro curto al modo de try como ya lo conocemos, sin más:

Try Elixir

Begin learning the basics of Elixir and take your first steps into the world of functional programming.
 Coming Soon - We'll remind you.

Course Overview

  1. Level 1 on Try Elixir

    LEVEL 1 FREE LEVEL 1 Video | 4 Challenges
    Modules & Functions

    Get started in the world of functional programming with Elixir by learning how to work with named functions.
  2. Level 2 on Try Elixir

    LEVEL 2 FREE LEVEL 1 Video | 2 Challenges
    The Pipe Operator

    Learn how to refactor nested function calls into an easier syntax, using the pipe operator.
  3. Level 3 on Try Elixir

    LEVEL 3 FREE LEVEL 1 Video | 4 Challenges
    Pattern Matching

    Explore how pattern matching works and how we can use it to remove if statements from our programs.
Try Elixir
COMPLETE THESE LEVELS TO UNLOCK

Course Completion Badge

Begin learning the basics of Elixir and take your first steps into the world of functional programming.

Supplemental Learning



    Dejo link:
    https://www.codeschool.com/courses/try-elixir?utm_source=facebook&utm_medium=social

    domingo, 5 de marzo de 2017

    Pipe Operator de Elixir



    Hice el curso try Elixir de codescholl y quede asombrado sobre el operador pipe o |> como les guste llamarlo.

    Vamos por parte, si no conocen Elixir te recomiendo:
    y si queres saber más sobre Elixir: http://emanuelpeg.blogspot.com.ar/search/label/Elixir

    En programación funcional y en otros paradigmas también, es común que una función reciba como parámetros el resultado de otra función y así sucesivamente. Lo que nos queda:

    foo(bar(baz(new_function(other_function(2)))))

    Como pueden ver no es muy legible para estos casos tenemos el operador |> que funciona igual al operador pipe de linux, es decir permite que el resultado de una función sea el primer parámetro de una segunda función.

    Por lo tanto nuestro ejemplo nos queda:

    other_function(2) |> new_function() |> baz() |> bar() |> foo()

    Veamos unos ejemplos: 

    iex> "Elixir rocks" |> String.split
    ["Elixir", "rocks"]


    iex> "Elixir rocks" |> String.upcase |> String.split
    ["ELIXIR", "ROCKS"]


    iex> "elixir" |> String.ends_with?("ixir")
    true

    Dejo link: 

    domingo, 25 de octubre de 2015

    Elixir 1.1, trae nuevas APIs y mejora en performace


    A un año de Elixir 1.0 tenemos la versión 1.1, esta trae nuevas APIs y mejora en performace.

    Elixir 1.1 nos trae como 40 nuevas funcionalidades, incluyendo nueva APIs para Enum, Task, y String modules. Además, un nuevo tipo de datos fueron agregados, MapSet.

    También se ha mejorado de herramientas. Marco de pruebas unitarias de Elixir, ExUnit, tiene nuevas opciones que le permiten saltar las pruebas a través de las etiquetas e imprimir capturado mensajes de registro, incluso en caso de fallos. Mix, herramienta de construcción de Elixir, ofrece ahora un mejor rendimiento mediante la separación en tiempo de compilación dependencias y dependencias en tiempo de ejecución y volver a compilar un archivo sólo si alguna de sus dependencias en tiempo de compilación se han cambiado.

    Dejo link:
    https://github.com/elixir-lang/elixir/tree/v1.1.0
    http://elixir-lang.org/blog/2015/09/28/elixir-v1-1-0-released/


    domingo, 17 de septiembre de 2017

    Elixir 1.5 fue liberado!

    Elixir 1.5 trae muchas mejoras a la experiencia y calidad de vida del desarrollador. Es decir esta versión se centro que mejorar la interactividad con el desarrollador.

    Entre las mejoras que tenemos podemos nombrar:

    UTF-8 para atoms, nombres de funciones y variables, por ejemplo :

    test "こんにちは世界" do
      assert :こんにちは世界
    end

    o

    saudação = "Bom dia!"

    Elixir 1.5 es más accesible a otros idiomas y comunidades. Los identificadores deben seguir siendo una secuencia de letras, seguida de dígitos y combinar marcas. Esto significa que los símbolos, como las notaciones matemáticas y emojis, no están permitidos en los identificadores.

    IEx obtuvo muchas mejoras en la experiencia del desarrollador. En primer lugar, el sistema de autocompletado es ahora capaz de autocompletar variables y imports.

    IEx también obtuvo nuevas funciones, como listar todas las funciones y macros en un módulo.

    Por último, IEx también cuenta con un sistema de punto de interrupción para la depuración de código cuando se ejecuta en Erlang / OTP 20

    Exception.blame/3 es una nueva función de Elixir que es capaz de adjuntar información de depuración a ciertas excepciones. Actualmente se utiliza para aumentar FunctionClauseErrors con un resumen de todas las cláusulas y qué partes de la cláusula coinciden y cuáles no.

    Elixir v1.5 simplifica la forma en que los supervisores se definen y utilizan en Elixir. Elixir ahora permite especificaciones hijas, que especifican cómo se supervisará un proceso hijo, que se definirá en módulos.

    Esta versión incluye muchas mejoras en funciones de calendario, como Date.range/2 y la posibilidad de convertir entre diferentes calendarios.

    Estas son algunas mejoras que vienen en esta nueva versión.

    Dejo link: https://elixir-lang.org/blog/2017/07/25/elixir-v1-5-0-released/

    miércoles, 6 de noviembre de 2024

    Supervisores y Árboles de Supervisión en Elixir


    La concurrencia es uno de los puntos fuertes de Elixir, y el modelo de supervisión es fundamental para construir aplicaciones resilientes. 

    El modelo de concurrencia en Elixir está basado en procesos ligeros y aislados que se comunican entre sí enviándose mensajes, siguiendo el paradigma del modelo de actor. Estos procesos no comparten memoria, lo que reduce los riesgos de condiciones de carrera y hace que el sistema sea más seguro.

    Supervisores son procesos especiales en Elixir que gestionan y supervisan otros procesos, reiniciándolos si fallan. Esto asegura que la aplicación siga funcionando incluso cuando ocurren errores.

    Elixir provee módulos como Supervisor y Task.Supervisor para gestionar procesos de manera eficiente. Vamos a crear un simple supervisor que inicie y supervise un proceso Worker.


    Primero, definimos el proceso Worker usando GenServer:


    defmodule Worker do

      use GenServer


      def start_link(initial_state) do

        GenServer.start_link(__MODULE__, initial_state, name: __MODULE__)

      end


      def init(state), do: {:ok, state}


      def handle_cast(:do_work, state) do

        # Simulamos un trabajo que puede fallar

        if :rand.uniform() > 0.5 do

          {:stop, :error, state}

        else

          IO.puts("Trabajo completado exitosamente")

          {:noreply, state}

        end

      end

    end


    Ahora, creamos un supervisor que inicie y supervise nuestro proceso Worker:


    defmodule MySupervisor do

      use Supervisor


      def start_link(_opts) do

        Supervisor.start_link(__MODULE__, :ok, name: __MODULE__)

      end


      def init(:ok) do

        children = [

          {Worker, :some_initial_state}

        ]


        Supervisor.init(children, strategy: :one_for_one)

      end

    end


    Elixir ofrece varias estrategias de supervisión que permiten diferentes enfoques de recuperación en caso de fallo:


    • :one_for_one: Solo reinicia el proceso que falló.
    • :one_for_all: Reinicia todos los procesos supervisados si uno falla.
    • :rest_for_one: Reinicia el proceso que falló y todos los procesos que fueron iniciados después de este.
    • :simple_one_for_one: Útil para supervisar un número dinámico de procesos que comparten el mismo tipo de inicialización.


    En el ejemplo anterior, usamos :one_for_one, que reiniciará únicamente el proceso Worker si falla.

    Los árboles de supervisión permiten organizar supervisores en una jerarquía. Esto es ideal para sistemas complejos que necesitan distintos niveles de supervisión.

    Por ejemplo, podríamos tener un supervisor principal que supervise varios supervisores secundarios, cada uno a cargo de procesos específicos. Aquí hay una estructura básica:


    defmodule MainSupervisor do

      use Supervisor


      def start_link(_opts) do

        Supervisor.start_link(__MODULE__, :ok, name: __MODULE__)

      end


      def init(:ok) do

        children = [

          MySupervisor, # Supervisor de workers

          AnotherSupervisor # Otro supervisor

        ]


        Supervisor.init(children, strategy: :one_for_all)

      end

    end


    En esta configuración:

    • MainSupervisor es el supervisor principal.
    • MySupervisor y AnotherSupervisor son supervisores secundarios.
    • Si cualquiera de los supervisores secundarios falla, MainSupervisor los reiniciará junto con sus respectivos procesos.


    Los supervisores y árboles de supervisión en Elixir son una herramienta poderosa para construir sistemas concurrentes y resilientes. Siguiendo estos patrones, puedes crear aplicaciones que se recuperen automáticamente de fallos sin necesidad de intervención manual. Esto convierte a Elixir en una excelente opción para aplicaciones que requieren alta disponibilidad.

    martes, 21 de mayo de 2013

    Elixir un lenguaje que corre en la vm de Erlang



    Elixir es un meta-lenguaje de programación, es funcional construido sobre la máquina virtual de Erlang. Se trata de un lenguaje dinámico con una sintaxis flexible y apoyado en macros; que aprovecha las capacidades de Erlang para construir aplicaciones concurrentes y distribuidas, tolerables a fallos, con actualizaciones de código en caliente.

    Elixir también soporta pattern matching, el polimorfismo a través de protocolos (similar a Clojure), alias y estructuras de datos asociativos (generalmente conocido como hashes en otros lenguajes de programación).

    Por último, Elixir y Erlang comparten el mismo código de bytes y de datos. Esto significa que puede invocar código Erlang de Elixir (y viceversa) sin ningún tipo de transformación o impacto en el rendimiento. Esto permite a los desarrolladores mezclar la expresividad de Elixir con la robustez y el rendimiento de Erlang.

    Dejo links:
    http://elixir-lang.org/
    http://en.wikipedia.org/wiki/Elixir_(programming_language)

    martes, 3 de noviembre de 2020

    Elixir School


    Elixir School es el primer destino para personas que buscan aprender y dominar el lenguaje de programación Elixir

    Ya seas un veterano experimentado o esta es tu primera vez, vas a encontrar lo que necesitas en las lecciones y en los recursos auxiliares

    Mediante el trabajo duro de voluntarios Elixir School ha sido traducido a muchos idiomas. Algunas de estas traducciones incluyen: Việt ngữ, 简体中文, 繁體中文, English, Slovenčina, 日本語, Polski, Português, Русском, Bahasa Indonesia, Bahasa Melayu, Українською, 한국어, Italiano, Deutsch, বাংলা, Türkçe, y ภาษาไทย.

    Te damos la bienvenida y te motivamos a continuar haciendo Elixir School grandioso involucrándote en elixirschool/elixirschool!

    De esta manera se presenta Elixir school que es un excelente sitio para comenzar con Elixir. 

    Y sin más dejo link: https://elixirschool.com/es/

    domingo, 19 de enero de 2025

    Diferencias entre Hilos y Procesos en Elixir


    Elixir, gracias a la BEAM VM, utiliza procesos livianos que se diferencian fundamentalmente de los hilos tradicionales:  

    1. Aislamiento Completo  

    • Los procesos en Elixir no comparten memoria. Esto evita condiciones de carrera, simplificando el manejo de la concurrencia.  
    • En contraste, los hilos suelen compartir memoria, requiriendo mecanismos como locks y semáforos para sincronización.  


    2. Ligereza y Escalabilidad  

    • Cada proceso en Elixir consume muy pocos recursos, permitiendo que millones coexistan.  
    • Los hilos son más pesados y su número está limitado por el sistema operativo.  


    3. Comunicación por Mensajes  

    • Los procesos en Elixir se comunican mediante mensajes asíncronos, usando send y receive.  
    • Los hilos comparten datos directamente, lo que puede complicar la concurrencia.  

    4. Tolerancia a Fallos  

    • Elixir sigue la filosofía "Let it crash", donde los supervisores reinician procesos fallidos.  
    • Los hilos carecen de un sistema equivalente nativo de supervisión.  


    Veamos un ejemplo rápido: 


    spawn(fn -> receive do

      msg -> IO.puts("Mensaje recibido: #{msg}")

    end end)

    |> send("¡Hola, proceso!")


    Elixir muestra cómo un enfoque basado en procesos simplifica y fortalece la concurrencia, ideal para sistemas distribuidos y resilientes.  


    sábado, 13 de enero de 2018

    Empezando con Elixir 10

    Mix

    Antes de que podamos sumergirnos en las aguas más profundas de Elixir, primero tenemos que aprender Mix. Si está familiarizado con Ruby, Mix es Bundler, RubyGems y Rake combinados. Es una parte crucial de cualquier proyecto de Elixir y en esta lección vamos a explorar solo algunas de sus excelentes características.


    Hasta ahora hemos estado trabajando exclusivamente dentro de iex, que tiene limitaciones. Para construir algo sustancial necesitamos dividir nuestro código en muchos archivos para administrarlo efectivamente; Mix nos permite hacer eso con proyectos.

    Proyectos

    Para hacer un nuevo proyecto debemos hacer :

    $ mix new example

    De la salida podemos ver que Mix ha creado nuestro directorio y una serie de archivos:

    * creating README.md
    * creating .gitignore
    * creating mix.exs
    * creating config
    * creating config/config.exs
    * creating lib
    * creating lib/example.ex
    * creating test
    * creating test/test_helper.exs
    * creating test/example_test.exs

    Vamos a centrarnos mix.exs. Aquí configuramos nuestra aplicación, dependencias, entorno y versión. Vamos abrir este archivo :

    defmodule Example.Mixfile do
      use Mix.Project

      def project do
        [app: :example,
         version: "0.0.1",
         elixir: "~> 1.1-dev",
         build_embedded: Mix.env == :prod,
         start_permanent: Mix.env == :prod,
         deps: deps]
      end

      # Configuration for the OTP application
      #
      # Type `mix help compile.app` for more information
      def application do
        [applications: [:logger]]
      end

      # Dependencies can be Hex packages:
      #
      #   {:mydep, "~> 0.3.0"}
      #
      # Or git/path repositories:
      #
      #   {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
      #
      # Type `mix help deps` for more examples and options
      defp deps do
        []
      end
    end

    La primera sección es project. Aquí definimos el nombre de nuestra aplicación (app), especificamos nuestra versión (version), versión de Elixir (elixir) y finalmente nuestras dependencias (deps).

    En application configuramos settings que se usa durante la generación de nuestro archivo de aplicación.

    Interactivo

    Puede ser necesario usar iex dentro del contexto de nuestra aplicación. Afortunadamente para nosotros, Mix lo hace fácil. Podemos comenzar una nueva sesión iex:

    $ iex -S mix

    Iniciar iex de esta manera cargará la aplicación y dependencias en el tiempo de ejecución.

    Compilacion

    Mix es inteligente y compilará los cambios cuando sea necesario. Para compilar de forma manual un proyecto Mix solo necesitamos ejecutar la compilación de Mix en nuestro directorio base:

    $ mix compile

    si se compilo con exito retornará :

    Compiled lib/example.ex
    Generated example app

    Cuando compilamos un proyecto Mix crea un directorio _build para nuestros artefactos. Si miramos dentro de _build veremos nuestra aplicación compilada: example.app.

    Administrar dependencias

    Nuestro proyecto no tiene dependencias, pero lo hará en breve, así que seguiremos adelante y cubriremos las dependencias definitorias y las buscaremos.

    Para agregar una nueva dependencia, primero debemos agregarla a nuestra mix.exs en la sección deps. Nuestra lista de dependencias se compone de tuplas con dos valores obligatorios y uno opcional: el nombre del paquete como un átomo, la cadena de versión y opciones.

    Para este ejemplo, veamos un proyecto con dependencias, con phoenix_slim:

    def deps do
      [
        {:phoenix, "~> 1.1 or ~> 1.2"},
        {:phoenix_html, "~> 2.3"},
        {:cowboy, "~> 1.0", only: [:dev, :test]},
        {:slime, "~> 0.14"}
      ]
    end

    La dependencia cowboy solo es necesaria durante el desarrollo y la prueba.

    Una vez que hemos definido nuestras dependencias, hay un último paso: obtenerlas. Esto es análogo a la instalación del paquete:

    $ mix deps.get

    Hemos definido y buscado nuestras dependencias de proyectos. 

    Entornos

    Mix, al igual que Bundler, admite diferentes entornos. Mix funciona con tres entornos:
    • :dev - El entorno predeterminado.
    • :test - Usado por la prueba de mezcla. Cubierto más en nuestra próxima lección.
    • :prod - se usa cuando enviamos nuestra aplicación a producción.

    Se puede acceder al entorno actual utilizando Mix.env. Como se esperaba, el entorno se puede cambiar a través de la variable de entorno MIX_ENV:

    $ MIX_ENV=prod mix compile



    miércoles, 6 de enero de 2016

    Elixir 1.2 se viene con muchas mejoras!!


    José Valim ha anunciado la versión 1.2 de Elixir, el lenguaje funcional dinámico que corre en la plataforma Erlang.

    Elixir 1.2 trae mejoras, bug fixing y mejoras en la performance y necesita la versión 18 de Erlang o superior.

    Entre las mejorar podemos nombrar:
    Se agrega nuevas formas para lo aliases/imports/require, ahora podemos hacer multiples alias por ejemplo:  alias MyApp.{Foo, Bar, Baz}
    Se agrego nuevo soporte para matas
    Además, las variables también se pueden utilizar como patrones con el operador pin.
    Elixir v1.2 introduce el operador "with" que permite resolver patter matching de forma más resumida.

    Dejo link:
    http://elixir-lang.org/blog/2016/01/03/elixir-v1-2-0-released/

    lunes, 16 de mayo de 2016

    Empezando con Elixir


    Quiero recomendarles este post sobre Elixir. En este post se revisan cosas básicas desde como instalar Elixir a hacer un primer programa.

    Les recuerdo que Elixir es un lenguaje moderno que corre en la maquina virtual de Erlang. Es muy moderno y sus conceptos son innovadores.

    Dejo link: https://www.toptal.com/elixir/getting-started-elixir-programming-language

    lunes, 25 de julio de 2016

    Elixir 1.3



    Que tarde, que tarde!! Se me repaso, la nueva versión de Elixir, que trae cosas interesantes.

    Como los seguidores más atentos del blog recordaran Elixir es un lenguaje funcional que corre sobre la maquina virtual de Erlang, y tiene como objetivo hacer más fácil el desarrollo en la tecnología de Erlang.

    Elixir 1.3, fue anunciado por José Valim. La nueva versión depreca (se dice así?) tareas imperativas y añade nuevos tipos y métodos de acceso, mejora su herramienta de Mixing y mejora el framework de pruebas unitarias ExUnit.

    Para mayor información dejo el release note: https://github.com/elixir-lang/elixir/releases/tag/v1.3.0

    lunes, 18 de noviembre de 2024

    Elixir: Concurrencia Hecha Sencilla


    Elixir, basado en la máquina virtual de Erlang (BEAM), utiliza el modelo de actores como su paradigma de concurrencia. Este modelo permite manejar múltiples procesos de manera eficiente y segura, lo que lo hace ideal para sistemas distribuidos y concurrentes.

    El modelo de actores es un paradigma de concurrencia en el que las entidades llamadas actores:

    • Son unidades independientes de ejecución.
    • Tienen su propio estado y no comparten memoria con otros actores.
    • Se comunican mediante el envío de mensajes.

    En Elixir, los procesos son implementaciones del modelo de actores y son extremadamente ligeros gracias a la eficiencia de la VM de Erlang.

    En Elixir, los actores se implementan utilizando módulos como GenServer. Vamos a crear un ejemplo básico de un contador que incrementa su valor en respuesta a mensajes.

       defmodule Counter do

         use GenServer


         # Inicio del actor con un estado inicial

         def start_link(initial_value) do

           GenServer.start_link(__MODULE__, initial_value, name: __MODULE__)

         end


         # Callbacks

         def init(initial_value) do

           {:ok, initial_value}

         end


         # Manejar el mensaje para incrementar el contador

         def handle_call(:increment, _from, state) do

           {:reply, state + 1, state + 1}

         end


         def handle_call(:get, _from, state) do

           {:reply, state, state}

         end

       end


       # Iniciar el actor con un valor inicial de 0

       {:ok, _pid} = Counter.start_link(0)


       # Incrementar el contador

       Counter.call(:increment) # Devuelve 1

       Counter.call(:increment) # Devuelve 2


       # Obtener el valor actual

       Counter.call(:get) # Devuelve 2


    Ahora crearemos múltiples actores que se comuniquen entre sí. Supongamos que tenemos un sistema donde un actor recopila datos y otro los procesa.


       defmodule DataCollector do

         use GenServer


         def start_link(processor_pid) do

           GenServer.start_link(__MODULE__, processor_pid, name: __MODULE__)

         end


         def init(processor_pid) do

           {:ok, processor_pid}

         end


         def handle_cast({:collect, data}, processor_pid) do

           send(processor_pid, {:process, data})

           {:noreply, processor_pid}

         end

       end

     

       defmodule DataProcessor do

         use GenServer


         def start_link(_) do

           GenServer.start_link(__MODULE__, [], name: __MODULE__)

         end


         def init(_) do

           {:ok, []}

         end


         def handle_info({:process, data}, state) do

           IO.puts("Procesando: #{data}")

           {:noreply, [data | state]}

         end

       end


       {:ok, processor_pid} = DataProcessor.start_link([])

       {:ok, collector_pid} = DataCollector.start_link(processor_pid)


       GenServer.cast(collector_pid, {:collect, "dato1"})

       GenServer.cast(collector_pid, {:collect, "dato2"})


    DataCollector recopila datos y los envía a DataProcessor. DataProcessor procesa los datos recibidos y los guarda en su estado.


    Como ventaja del modelo de actores tenemos:

    Aislamiento Total: Los actores no comparten memoria, eliminando condiciones de carrera.

    Escalabilidad: Los procesos son livianos y se ejecutan de manera concurrente.

    Resiliencia: Si un actor falla, el sistema no se detiene; los supervisores pueden reiniciarlo.


    El modelo de actores de Elixir proporciona una forma poderosa, segura y eficiente de manejar concurrencia. Al entender cómo implementar actores y supervisarlos, puedes construir sistemas robustos que escalen sin problemas.

    martes, 6 de junio de 2017

    Empezando con Elixir 4

    Pattern Matching

    Pattern Matching es una parte importante y poderosa de elixir. Esto permite machear valores simples, estructura de datos e incluso funciones. Veamos como trabaja:

    El operador Match
    En elixir el operador = es un operador de macheo. Elixir espera que coincida los valores de la mano izquierda con los valores de la mano derecha. Si coinciden, devuelve el valor de la ecuación. De lo contrario, se produce un error. Vamos a ver un ejemplo:

    iex> x = 1
    1

    Ahora vamos a probar el macheo:

    iex> 1 = x
    1
    iex> 2 = x
    ** (MatchError) no match of right hand side value: 1

    Ahora veamos ejemplos con varias estructuras:

    # Lists
    iex> list = [1, 2, 3]
    iex> [1, 2, 3] = list
    [1, 2, 3]
    iex> [] = list
    ** (MatchError) no match of right hand side value: [1, 2, 3]

    iex> [1 | tail] = list
    [1, 2, 3]
    iex> tail
    [2, 3]
    iex> [2 | _] = list
    ** (MatchError) no match of right hand side value: [1, 2, 3]

    # Tuples
    iex> {:ok, value} = {:ok, "Successful!"}
    {:ok, "Successful!"}
    iex> value
    "Successful!"
    iex> {:ok, value} = {:error}
    ** (MatchError) no match of right hand side value: {:error}

    Operador Pin

    El operador de = realiza la asignación cuando el lado izquierdo de la coincidencia incluye una variable. En algunos casos, este comportamiento no es deseable. Para estas situaciones tenemos el operador pin: ^.

    Veamos un ejemplo:

    iex> x = 1
    1
    iex> ^x = 2
    ** (MatchError) no match of right hand side value: 2
    iex> {x, ^x} = {2, 1}
    {2, 1}
    iex> x
    2


    iex> key = "hello"
    "hello"
    iex> %{^key => value} = %{"hello" => "world"}
    %{"hello" => "world"}
    iex> value
    "world"
    iex> %{^key => value} = %{:hello => "world"}
    ** (MatchError) no match of right hand side value: %{hello: "world"}

    En Elixir 1.2 se agrega soporte para que el pin funcione en mapas o funciones.

    iex> key = "hello"
    "hello"
    iex> %{^key => value} = %{"hello" => "world"}
    %{"hello" => "world"}
    iex> value
    "world"
    iex> %{^key => value} = %{:hello => "world"}
    ** (MatchError) no match of right hand side value: %{hello: "world"}

    Veamos un ejemplo con funciones:

    iex> greeting = "Hello"
    "Hello"
    iex> greet = fn
    ...>   (^greeting, name) -> "Hi #{name}"
    ...>   (greeting, name) -> "#{greeting}, #{name}"
    ...> end
    #Function<12.54118792/2 in :erl_eval.expr/5>
    iex> greet.("Hello", "Sean")
    "Hi Sean"
    iex> greet.("Mornin'", "Sean")
    "Mornin', Sean"

    Dejo link: https://elixirschool.com/lessons/basics/pattern-matching/

    sábado, 4 de enero de 2025

    Actores en Elixir


    Elixir, construido sobre la Máquina Virtual de Erlang (BEAM), es conocido por su capacidad para manejar concurrencia y tolerancia a fallos de manera elegante. Una de las piezas clave detrás de esta potencia es el modelo de actores.

    El modelo de actores es un paradigma de concurrencia donde las entidades llamadas actores:

    • Reciben mensajes.
    • Procesan esos mensajes.
    • Pueden responder, enviar mensajes a otros actores o crear nuevos actores.

    En Elixir, los actores se implementan como procesos ligeros gestionados por la BEAM, lo que permite manejar miles o incluso millones de ellos simultáneamente. Las caracteristicas más importantes son: 

    1. Aislamiento completo: Cada actor tiene su propio estado y no comparte memoria con otros actores.
    2. Comunicación mediante mensajes: Los mensajes entre a ctores son asíncronos y pasan a través de colas de mensajes.
    3. Tolerancia a fallos: Si un actor falla, su supervisor puede reiniciarlo, manteniendo la estabilidad del sistema.

    En Elixir, los procesos se crean con spawn, y se comunican usando send para enviar mensajes y receive para manejarlos. Veamos un ejemplo: 


    defmodule ActorExample do

      def start do

        spawn(fn -> listen() end)

      end


      defp listen do

        receive do

          {:greet, name} ->

            IO.puts("¡Hola, #{name}!")

            listen()

          :stop ->

            IO.puts("Proceso detenido.")

          _ ->

            IO.puts("Mensaje no reconocido.")

            listen()

        end

      end

    end


    # Crear el actor

    pid = ActorExample.start()


    # Enviar mensajes al actor

    send(pid, {:greet, "Mundo"})

    send(pid, :stop)


    Elixir hereda de Erlang una rica tradición de más de tres décadas en sistemas concurrentes y distribuidos. Esto lo convierte en una elección ideal para aplicaciones modernas como:

    • Sistemas distribuidos.
    • Aplicaciones web con alta concurrencia.
    • Sistemas en tiempo real.


    domingo, 1 de diciembre de 2024

    Creación de pruebas en Elixir con ExUnit


    ExUnit es el framework de pruebas integrado en Elixir, diseñado para ayudarte a escribir pruebas claras y efectivas. Desde pruebas unitarias hasta pruebas más complejas, ExUnit ofrece las herramientas necesarias para asegurar que tu código funcione como esperas.

    ExUnit viene incluido con Elixir, por lo que no necesitas instalar dependencias adicionales. Solo asegúrate de que tu entorno de desarrollo esté configurado para ejecutarlas.


    ExUnit.start()


    Los archivos de pruebas suelen estar en el directorio test/ y deben tener el sufijo _test.exs.


    Veamos un ejemplo: 


    defmodule MiApp.MiModuloTest do

      use ExUnit.Case


      test "una prueba simple" do

        assert 1 + 1 == 2

      end

    end


    Para ejecutar las pruebas, utiliza:


    mix test


    Las aserciones son fundamentales para comprobar el comportamiento esperado. ExUnit ofrece varias:


    - assert: Verifica que una condición sea verdadera.

    - refute: Verifica que una condición sea falsa.

    - assert_raise: Verifica que se lance una excepción específica.


    Veamos algunos ejemplos: 


    assert String.length("Hola") == 4

    refute String.contains?("Hola", "mundo")

    assert_raise ArgumentError, fn -> String.to_integer("no_numero") end


    ExUnit permite convertir ejemplos en la documentación en pruebas automáticas.


    defmodule MiModulo do

      @doc """

      Duplica un número.


      ## Ejemplo


          iex> MiModulo.duplicar(2)

          4


      """

      def duplicar(n), do: n * 2

    end


    defmodule MiModuloTest do

      use ExUnit.Case

      doctest MiModulo

    end


    Para organizar tus pruebas, podemos usar describe:


    defmodule MiApp.MiModuloTest do

      use ExUnit.Case


      describe "función suma/2" do

        test "suma números positivos" do

          assert MiApp.MiModulo.suma(2, 3) == 5

        end


        test "suma números negativos" do

          assert MiApp.MiModulo.suma(-2, -3) == -5

        end

      end

    end


    Y podemos usar setup para definir configuraciones comunes:


    defmodule MiApp.MiModuloTest do

      use ExUnit.Case


      setup do

        {:ok, numero: 42}

      end


      test "usa datos de setup", %{numero: numero} do

        assert numero == 42

      end

    end


    Elixir soporta pruebas concurrentes por defecto. Si necesitas pruebas asincrónicas, podemos indícarlo:


    defmodule MiApp.AsyncTest do

      use ExUnit.Case, async: true


      test "prueba concurrente" do

        Task.async(fn -> :ok end)

        |> Task.await()

        |> assert == :ok

      end

    end


    ExUnit facilita capturar salidas a consola y logs:


    import ExUnit.CaptureIO


    test "captura salida de IO.puts" do

      salida = capture_io(fn -> IO.puts("Hola, mundo!") end)

      assert salida == "Hola, mundo!\n"

    end


    import ExUnit.CaptureLog


    test "captura logs" do

      salida = capture_log(fn -> Logger.info("Esto es un log") end)

      assert salida =~ "Esto es un log"

    end


    Para ejecutar pruebas individuales, podemos usar:


    mix test test/mi_modulo_test.exs:10


    ExUnit es una herramienta flexible y poderosa para escribir pruebas en Elixir. Desde las pruebas más básicas hasta configuraciones avanzadas, te ayuda a mantener un código confiable y fácil de mantener.