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/

    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/

    jueves, 16 de marzo de 2017

    Empezando con Elixir 2


    Vamos a seguir aprendiendo Elixir porque me gustan estos, post continuados. 

    Elixir tiene varios tipos de colecciones: List, tuples, keywords, maps. Empecemos con listas o list en ingles.

    Las listas son colecciones simples de datos que pueden ser de diferente tipo. Y puede contener valores repetidos:

    iex> [3.14, :pie, "Apple"]
    [3.14, :pie, "Apple"]

    Elixir implementa las listas como listas linkeadas. Por esa razón llegar al elemento n tiene complejidad o(n) . Pero es muy eficiente cuando se agregan datos:

    iex> list = [3.14, :pie, "Apple"]
    [3.14, :pie, "Apple"]
    iex> ["π"] ++ list
    ["π", 3.14, :pie, "Apple"]
    iex> list ++ ["Cherry"]
    [3.14, :pie, "Apple", "Cherry"]

    Si queremos concatenar 2 listas debemos usar el operador ++

    iex> [1, 2] ++ [3, 4, 1]
    [1, 2, 3, 4, 1]

    Podemos quitar elementos o sustraerlos con el operador -- 

    iex> [1,2,2,3,2,3] -- [1,2,3,2]
    [2, 3]

    Con la función hd (head) podemos conocer el comienzo de la lista y con tl (tail) podemos conocer el resto de la lista: 

     iex> hd [3.14, :pie, "Apple"]
    3.14
    iex> tl [3.14, :pie, "Apple"]
    [:pie, "Apple"]

    A la vez podemos utilizar pattern matching  y el operador | nos permite asignar los valores: 

    iex> [h|t] = [3.14, :pie, "Apple"]
    [3.14, :pie, "Apple"]
    iex> h
    3.14
    iex> t
    [:pie, "Apple"]

    Las tuplas son similares a las listas pero esta estructura se guarda secuencial en memoria por lo que es más rápida a la hora de acceder pero muy lenta cuando queremos insertar un elemento en el medio. 

    iex> {3.14, :pie, "Apple"}
    {3.14, :pie, "Apple"}

    Esto se utiliza mucho cuando necesitamos que una función retorne muchos datos. 

    iex> File.read("path/to/existing/file")
    {:ok, "... contents ..."}
    iex> File.read("path/to/unknown/file")
    {:error, :enoent}

    Las listas clave/valor y mapas están asociados a las colecciones, es decir listas clave/valor son un tipo de tuplas y esto mejora la performance: 

    iex> [foo: "bar", hello: "world"]
    [foo: "bar", hello: "world"]
    iex> [{:foo, "bar"}, {:hello, "world"}]
    [foo: "bar", hello: "world"]

    Hay tres características a tener en cuenta: 
    • Las claves son atómicas
    • No se pueden repetir 
    • Y están ordenadas
    Por estas razones, las listas clave/valor se utilizan con más frecuencia para pasar opciones a funciones.

    Los mapas son un tanto diferentes a las listas clave/valor. En los mapas se puede tener claves de cualquier tipo y las claves no están ordenadas. Para construir un mapa utilizamos %{}

    iex> map = %{:foo => "bar", "hello" => :world}
    %{:foo => "bar", "hello" => :world}
    iex> map[:foo]
    "bar"
    iex> map["hello"]
    :world

    En Elixir 1.2 las variables pueden ser claves:

    iex> key = "hello"
    "hello"
    iex> %{key => "world"}
    %{"hello" => "world"}

    Si se duplica una clave pisa el valor anterior:

    iex> %{:foo => "bar", :foo => "hello world"}
    %{foo: "hello world"}

    Como podemos ver en la salida anterior, existe una sintaxis especial para mapas que contienen sólo claves atómicas:

    iex> %{foo: "bar", hello: "world"}
    %{foo: "bar", hello: "world"}

    iex> %{foo: "bar", hello: "world"} == %{:foo => "bar", :hello => "world"}
    true

    Otra propiedad interesante de los mapas es que proporcionan su propia sintaxis para actualizar y acceder a las claves atómicas:

    iex> map = %{foo: "bar", hello: "world"}
    %{foo: "bar", hello: "world"}
    iex> %{map | foo: "baz"}
    %{foo: "baz", hello: "world"}
    iex> map.hello
    "world"

    Dejo link: https://elixirschool.com/lessons/basics/collections/



    jueves, 30 de marzo de 2023

    Primeros pasos con Phoenix parte 5


    Cuando su navegador accede a http://localhost:4000/, envía una solicitud HTTP a cualquier servicio que se esté ejecutando en esa dirección, en este caso, nuestra aplicación Phoenix. La solicitud HTTP se compone de un verbo y una ruta. Por ejemplo, las siguientes solicitudes del navegador se traducen en:

    BROWSER ADDRESS             VERBO PATH

    http://localhost:4000/                 GET /

    http://localhost:4000/hello         GET /hello

    http://localhost:4000/hello/world GET /hello/world


    Hay otros verbos HTTP. Por ejemplo, enviar un formulario generalmente usa el verbo POST.

    Las aplicaciones web generalmente manejan las solicitudes asignando cada par de verbo/ruta a una parte específica de su código y esto lo hace el router. Por ejemplo, podemos asignar "/artículos" a una parte de nuestra aplicación que muestra todos los artículos. Por lo tanto, para agregar esto, nuestra primera tarea es agregar una nueva ruta.

    El router asigna pares únicos de verbo/ruta HTTP a pares de controlador/acción que los manejarán. Los controladores en Phoenix son simplemente módulos Elixir. Las acciones son funciones que se definen dentro de estos controladores.

    Phoenix genera un archivo de router para nosotros en lib/hello_web/router.ex. 

    La ruta de nuestro "¡Bienvenido a Phoenix!"  tiene este aspecto.


        get "/", PageController, :home


    Si ponemos  en el browser http://localhost:4000/ estamos llamando a / con el metodo GET por lo tanto será manejada por la función home en el módulo HelloWeb.PageController definido en lib/hello_web/controllers/page_controller.ex.

    La página que vamos a construir dirá "¡Hola mundo, desde Phoenix!" cuando apuntamos nuestro navegador a http://localhost:4000/hello.

    Lo primero que debemos hacer es crear la ruta de la página para una nueva página. Abramos lib/hello_web/router.ex en un editor de texto. 

    Agreguemos una nueva ruta al enrutador que asigna una solicitud GET para /hello a la acción de índice de un HelloWeb.HelloController que se creará próximamente dentro del bloque do scope "/" del enrutador:


    scope "/", HelloWeb do
      pipe_through :browser

      get "/", PageController, :home
      get "/hello", HelloController, :index
    end


    Los controladores son módulos de Elixir y las acciones son funciones de Elixir definidas en ellos. El propósito de las acciones es recopilar los datos y realizar las tareas necesarias para la representación. Nuestra ruta especifica que necesitamos un módulo HelloWeb.HelloController con una función index/2.

    Para hacer que suceda la acción de índice, creemos un nuevo archivo lib/hello_web/controllers/hello_controller.ex y hagamos que tenga el siguiente aspecto:

    defmodule HelloWorldWeb.HelloController do
      use HelloWorldWeb, :controller

      def index(conn, _params) do
        render(conn, :index)
      end
    end


    Todas las acciones del controlador toman dos argumentos. El primero es conn, una estructura que contiene una gran cantidad de datos sobre la solicitud. El segundo es params, que son los parámetros de solicitud. .

    El núcleo de esta acción es render(conn, :index). Le dice a Phoenix que renderice la plantilla de índice. Los módulos responsables de renderizar se denominan vistas. De forma predeterminada, las vistas de Phoenix llevan el nombre del controlador (HelloController) y el formato (HTML en este caso), por lo que Phoenix espera que exista un HelloWeb.HelloHTML y defina una función index/1.

    Las vistas de Phoenix actúan como capa de presentación. Por ejemplo, esperamos que el resultado del índice de representación sea una página HTML completa. Para hacernos la vida más fácil, a menudo usamos plantillas para crear esas páginas HTML.

    Vamos a crear una nueva vista. Cree lib/hello_web/controllers/hello_html.ex y haga que se vea así:

    defmodule HelloWorldWeb.HelloHTML do
      use HelloWorldWeb, :html
    end

    Para agregar plantillas a esta vista, podemos definirlas como componentes de función en el módulo o en archivos separados.

    Comencemos definiendo un componente de función:

    defmodule HelloWorldWeb.HelloHTML do
      use HelloWorldWeb, :html

      def index(assigns) do
        ~H"""
        Hello!
        """
      end
    end

    Definimos una función que recibe asignaciones como argumentos y usamos el sigilo ~H para poner los contenidos que queremos representar. Dentro del sigilo ~H, usamos un lenguaje de plantillas llamado HEEx, que significa "HTML+EEx". EEx es una biblioteca para incrustar Elixir que se distribuye como parte del propio Elixir. "HTML+EEx" es una extensión Phoenix de EEx compatible con HTML, con soporte para validación HTML. Este último lo protege de vulnerabilidades de seguridad como Cross-Site-Scripting sin trabajo adicional de su parte.

    Un archivo de plantilla funciona de la misma manera. Los componentes de función son excelentes para plantillas más pequeñas y los archivos separados son una buena opción cuando tiene mucho marcado o sus funciones comienzan a parecer inmanejables.

    Probémoslo definiendo una plantilla en su propio archivo. Primero elimine nuestra función def index(assigns) de arriba y reemplácela con una declaración embed_templates:

    defmodule HelloWorldWeb.HelloHTML do
      use HelloWorldWeb, :html

      embed_templates "hello_html/*"
    end


    Aquí le estamos diciendo a Phoenix.Component que incruste todas las plantillas .heex que se encuentran en el directorio hermano hello_html en nuestro módulo como definiciones de funciones.

    A continuación, debemos agregar archivos al directorio lib/hello_web/controllers/hello_html.

    Tenga en cuenta que el nombre del controlador (HelloController), el nombre de la vista (HelloHTML) y el directorio de la plantilla (hello_html) siguen la misma convención de nomenclatura y se nombran uno tras otro. También se colocan juntos en el árbol de directorios:


    lib/hello_web
    ├── controllers
    │   ├── hello_controller.ex
    │   ├── hello_html.ex
    │   ├── hello_html
     |         ├── index.html.heex

    Un archivo de plantilla tiene la siguiente estructura: NOMBRE.FORMATO.TEMPLATING_LANGUAGE. En nuestro caso, creemos un archivo index.html.heex en lib/hello_web/controllers/hello_html/index.html.heex:

    <section>
      <h2>Hello World, from Phoenix!</h2>
    </section>

    Los archivos de plantilla se compilan en el módulo como componentes de función en sí mismos, no hay diferencia de tiempo de ejecución o rendimiento entre los dos estilos.

    Ahora que tenemos la ruta, el controlador, la vista y la plantilla, deberíamos poder dirigir nuestros navegadores a http://localhost:4000/hello.

    Para reiniciar el server hacemos : 

    mix phx.server