Sobre cómo me mudé de C # a Elixir / Phoenix

Una vez tuve que cambiar de trabajo. Antes de eso, solo trabajaba con lenguajes como Python, C ++, C # y un par más como ese. Y ahora tenía que comenzar a trabajar con un lenguaje funcional. Las primeras impresiones fueron "¿qué demonios es eso?" Sin embargo, logré adaptarme lo suficientemente rápido. A continuación, hablaré sobre los puntos principales a los que tuve que acostumbrarme o que tuve que entender para comenzar a escribir de manera rápida y adecuada.

1. Coincidencia de patrones

Esta es una de las principales características del lenguaje. Pero entenderlo completamente, hasta que realmente comience a escribir en el idioma, es un poco difícil. Lo primero que leí sobre la coincidencia de patrones es que, gracias a esto, simplemente puede extraer datos de estructuras y vincularlos a variables. Pero, de hecho, todo es algo más complicado. La coincidencia de patrones funciona en casi todas partes en un idioma determinado. Daré tres ejemplos que ilustran las principales aplicaciones que uso casi constantemente.

Ejemplo 1. Por definición:

{tuple_item_1, tuple_item_2} = tuple 

- divide una tupla de 2 elementos en dos variables, que luego se pueden usar.

 [head_item | tail_list] = list 

- divide la lista en el primer elemento de la lista y la lista sin el primer elemento.

Ejemplo 2. Comparación en caso:

 case get_elem(struct) do {:ok, elem} -> … {:error, reason} -> … end 

La función get_elem (struct) devuelve una tupla, y case le permite extraer datos de forma inmediata y seleccionar otra secuencia de acciones.

Ejemplo 3 Mapeo de características:

 def function_1(params, :ok) do end def function_1(params, :error) do end def function_1(params, _) do end 

Aquí, de hecho, se presenta la misma función que toma dos parámetros. La coincidencia de patrones le permite elegir qué función ejecutar.

Un poco sobre la coincidencia de patrones. La comparación es siempre "de arriba hacia abajo". En este ejemplo, al llamar a function_1 desde dos parámetros, primero verificará que el segundo parámetro sea : ok . Si la primera comprobación falla, se realiza una comprobación para : error . Y si no es así, en cualquier caso ingresaremos a la tercera versión del método. El guión bajo significa "cualquier dato", así como el hecho de que los datos recibidos no nos interesan, es decir, no los utilizaremos. Si function_1 (params, _) fuera el primero en la lista, el programa siempre lo seleccionaría y los otros dos métodos nunca funcionarían. Si no se encuentra el patrón deseado, se lanzará una excepción.

2. Tubería

Estas son construcciones de la siguiente forma:

 param_1 |> func_1() |> func_2(param_2) … 

A primera vista, parece que hay basura. Pero vale la pena recordar que Elixir es un lenguaje funcional. Y en un lenguaje funcional, es bastante normal hacer cálculos de función de función, sin variables intermedias. Pipeline es solo una entrada conveniente. El lenguaje en sí mismo pide claridad para comenzar la canalización con una variable o valor.

El ejemplo anterior se puede reescribir de la siguiente manera:

 func_2(func_1(param_1), param_2) 

En otras palabras, la canalización redirige el resultado de calcular la función anterior a la siguiente función con el primer argumento.

3. Falta de ciclos

No hay ciclos en Elixir. Este hecho causó la mayor conmoción en mí, y es el más difícil de entender. Luego viene mi opinión y visión, que pueden no coincidir con la realidad y la teoría.

Las raíces de este hecho están en el paradigma de programación funcional, uno de los cuales establece que el resultado de un programa es el trabajo de una función que puede llamar a otras funciones y el programa no implica almacenar estados intermedios. Los ciclos, a su vez, están diseñados para cambiar repetidamente el estado externo al ciclo.

Dos cosas sirven como reemplazo para los ciclos: métodos de recursión y biblioteca para trabajar con elementos enumerables del lenguaje.

Un poco más sobre las pequeñas cosas.

1. No hay clases en Elixir, pero hay contextos. En esencia, los contextos están reemplazando de alguna manera las clases. La descripción más cercana del contexto a través de los ojos de un s-sharper: los contextos son un cruce entre una clase y un espacio de nombres en sharpe, y el contexto está mucho más cerca del espacio de nombres.

2. Los átomos. En Elixir existe algo así como un átomo. Un átomo es esencialmente un tipo de "etiqueta". La forma más fácil de tratarlos es como líneas especiales. Los ejemplos en este artículo ya tenían dos átomos :: ok ,: error . Gracias a los átomos, la coincidencia de patrones y las construcciones lógicas complejas son mucho más fáciles. En esencia, estas son constantes cuyo valor es su nombre. Un átomo siempre tiene un ":" delante de un nombre.

3. Cómo leer los encabezados de los métodos correctamente. En Elixir, es costumbre designar los métodos de la siguiente manera (esto se ve especialmente a menudo en la documentación): & function / 2 . Se lee como un método con el nombre "función" y arity 2. Arity es el número de argumentos tomados.

Lo que me ayudó a integrarme en el idioma.

En primer lugar, este es un directorio en el Android "Elixir Tutorial". Es bueno porque cubre brevemente los puntos principales del lenguaje y su sintaxis, y se puede leer en el bus. Menos: está en inglés, por lo que no es adecuado para todos.

En segundo lugar, el libro "Introducción al Elixir", escrito por Senloren S., Eisenberg D ... Este libro muestra los métodos para trabajar con el lenguaje y los explica. Es fácil de leer y le permite mejorar significativamente su trabajo con el idioma. También se puede encontrar en ruso.

En tercer lugar, documentación oficial en línea. Está hecho convenientemente y le permite encontrar rápidamente las secciones / métodos necesarios, con una descripción detallada y ejemplos.

Eso es todo.

Lista de materiales:

1. Tutorial de elixir

2. Senloren S., Eisenberg D. Introducción al Elixir. Introducción a la programación funcional. - O'Reilly, 2017.

3. Documentación oficial.

Source: https://habr.com/ru/post/es435796/


All Articles