Introducción a Elixir Lang
Publicado: 2015-02-27Una introducción al lenguaje de programación Elixir (y por qué me encanta)
Escribí un artículo hace unos meses presentándote a Golang, y por qué me encantó tanto. Si bien todavía me encanta, últimamente he estado jugando con un nuevo idioma; Elixir. Compré el libro Elixir de programación y lo he estado siguiendo. Ya he llegado a amar a Elixir y espero mostrarte por qué en este artículo.
Mientras trabajaba para Couchbase hace un par de años, me interesé mucho por Erlang y los sistemas distribuidos. Para mí, Erlang es confuso. Cuando vi Elixir, inmediatamente supe que estaba en algo bueno. Elixir se detalla como un lenguaje funcional y concurrente que se ejecuta sobre la VM de Erlang.
He escuchado muchas veces a personas que dicen que Elixir es 'Ruby para Erlang', etc. Esta teoría no es del todo incorrecta, pero de manera realista, es principalmente la sintaxis de Elixir la que está influenciada por Ruby, ya que no comparte muchas de las mismas construcciones de programación. Es, por supuesto, similar en formas a Erlang, ya que se construye sobre la VM de Erlang y nos brinda acceso directo a las primitivas de Erlang de forma nativa.
De todos modos, sin más vacilaciones, profundicemos y empecemos con un poco de Elixir.
Instalación
Si está ejecutando OSX, la instalación es tan fácil como usar Homebrew:
~ brew update
~ brew install erlang
~ brew install elixir
Una vez que hayas hecho esto, deberías poder ejecutar:
~ elixir -v
> Elixir 1.0.2
Ahora que Elixir está instalado correctamente, podemos abrir un Elixir interactivo y jugar con algunos tipos comunes básicos.
Tipos en Elixir
Inicie un Elixir interactivo REPL ingresando
> iex
Variables:
iex(1)> name = "rbin"
#=> "rbin"
Átomos:
En Elixir, un Átomo es una constante en la que su nombre es su propio valor.
iex(2)> :this_is_an_atom
#=> :this_is_an_atom
iex(3)> :my_atom == :atom
#=> false
Tuplas:
Usamos la notación Curly Brace para definir Tuplas. En Elixir, las tuplas se almacenan inmediatamente en la memoria, lo que significa que obtener el tamaño de una tupla o acceder a un elemento de tupla es rápido, pero actualizar o agregar elementos es costoso, ya que requiere copiar toda la tupla en la memoria.
iex(4)> tuple = {:hello, "world"}
#=> {:hello, "world"}
iex(5)> elem(tuple, 1)
#=> "world"
Liza:
En Elixir, las listas se almacenan en la memoria, como listas enlazadas. Podemos actualizar las listas de manera trivial anteponiendo elementos, pero agregar elementos es más costoso, ya que necesitamos recorrer toda la lista para calcular su tamaño.
iex(8)> list = [1, 2, :atom]
#=> [1, 2, :atom]
iex(9)> ["string"] ++ list
#=> ["string", 1, 2, :atom]
iex(10)> list ++ [31]
#=> [1, 2, :atom, 31]
Hay funciones incorporadas muy útiles para usar con listas, incluida la obtención de Head & Tail de una lista.
iex(11)> hd(list)
#=> 1
iex(12)> tl(list)
#=> [2, :atom]
Funciones anónimas:
En Elixir, las funciones son ciudadanos de primera clase, lo que significa que podemos pasar funciones como argumentos a otras funciones. A continuación, definiremos una variable llamada add que contiene una función, que luego pasaremos como argumento a la función is_function/1 .
iex(14)> add = fn a, b -> a + b end
#Function<12.90072148/2 in :erl_eval.expr/5>
iex(15)> add.(13, 31)
#=> 44
iex(16)> is_function(add)
#=> true
Organizando Nuestros Proyectos (Mix)
Elixir viene con una herramienta súper útil llamada Mix. Mix es una herramienta de construcción que nos permite generar, organizar, compilar y probar nuestros proyectos muy fácilmente. También nos facilita la gestión de dependencias. (¡Siempre es un tema delicado!) Para crear un nuevo proyecto con Mix, simplemente hacemos lo siguiente:
~ mix new myapp --module MyApp
Esto creará un directorio llamado myapp con algunos archivos dentro. También definirá un módulo MyApp dentro de lib/myapp.ex .
* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/myapp.ex
* creating test
* creating test/test_helper.exs
* creating test/myapp_test.exs
Your mix project was created successfully.
You can use mix to compile it, test it, and more:
cd myapp
mix test
Como podemos ver, obtenemos todos los archivos necesarios para una estructura de proyecto básica. Creo que esta es una de las mejores características disponibles que vienen con Elixir. Tener herramientas de gestión de proyectos es muy útil y ahorra mucho tiempo.
El archivo mix.exs es el archivo principal que se usa para configurar nuestro proyecto y administrar las dependencias, etc. Obtenemos una prueba/carpeta , en la que podemos escribir pruebas muy parecidas a Ruby para nuestro proyecto. Por supuesto, obtenemos una carpeta lib/ , que contiene los archivos fuente de nuestro proyecto. Si ejecutamos la prueba de mezcla en nuestra aplicación, obtenemos lo siguiente:
$ mix test
Compiled lib/myapp.ex
Generated myapp.app
.
Finished in 0.04 seconds (0.04s on load, 0.00s on tests)
1 tests, 0 failures
Randomized with seed 543313
concurrencia
Al igual que Erlang, Elixir usa el modelo 'Actor' para la concurrencia. Todo nuestro código se ejecuta dentro de Processes y estos procesos están aislados entre sí. Podemos hacer programas totalmente simultáneos en Elixir generando Procesos y enviando y recibiendo mensajes entre ellos.
En Elixir, iniciamos procesos usando la función de generación , que toma otra función como argumento.
iex(1)> spawn(fn -> IO.puts 1 + 1 end)
#=> 2
#PID<0.55.0>
Como puede ver, generamos un proceso que generó 1 + 1 y también devolvió su ID de proceso. Devolver este ID de proceso es útil, ya que podemos asignarlo a una variable y usarlo para enviar mensajes al proceso. Antes de hacer eso, necesitamos crear un mecanismo de recepción para obtener los mensajes que enviamos al proceso. (Podemos seguir adelante y hacer esto en nuestra sesión interactiva de Elixir , línea por línea).
Una vez que hayamos hecho eso, podemos crear un proceso que evalúe area_loop y asignarlo a pid .
pid = spawn(fn -> Geometry.area_loop() end)
#=> #PID<0.40.0>
Luego podemos enviar mensajes a pid en los que nuestro código predefinido coincidirá, dependiendo de si recibe el átomo :rectangle o el átomo :circle .
send pid, {:rectangle, 2, 3}
#=> Area = 6
# {:rectangle,2,3}
send pid, {:circle, 2}
#=> Area = 12.56000000000000049738
# {:circle,2}
Podemos verificar si los procesos aún se están ejecutando utilizando Process.alive? función.
Process.alive?(pid)
#=> false
Conclusión
Ni siquiera hemos arañado la superficie en este blog. Hay tantas características increíbles en Elixir, espero que continúes para comprobarlo por ti mismo. He enumerado algunos recursos de aprendizaje a continuación para ayudarlo en el camino, pero antes de comenzar y sumergirse, estas son algunas de mis cosas favoritas personales sobre Elixir:
- Era fácil de entender, con una sintaxis similar a la de un rubí y primitivas similares a las de Erlang.
- Tiene una comunidad fantástica detrás
- Su modelo de concurrencia me resulta familiar y muy poderoso.
- Mix es un regalo del cielo y ahorra MUCHO tiempo
- Elixir nos anima a documentarlo todo
- Hace que la creación de aplicaciones distribuidas sea un campo de batalla mucho menos confuso.
- Puedo ver a Elixir recorrer un largo camino.
Recursos
Algunos recursos que he encontrado muy útiles en mi corto tiempo aprendiendo Elixir:
- http://elixir-lang.org/getting-started/introduction.html
- https://pragprog.com/book/elixir/programming-elixir
- https://teamgaslight.com/blog/los-mejores-recursos-para-aprender-elixir
- http://ejercismo.io
* ¡Ve y bebe ese Elixir! – @rbin*