¿Por qué Elixir?

2020-12-05

Las razones por las que decidí especializarme en Elixir

Razones para usar un lenguaje de programación determinado son tan diversas como lenguajes en sí, pero una pregunta que recibo a menudo es, ¿por qué Elixir? aquí, intentaré delinear mis razones personales por las que decidí especializarme en él.

1. Es limpio

Desde que comencé a programar hace veinte años, la legibilidad ha sido mi principal preocupación—con los lenguajes que uso, el código que escribo, y las arquitecturas que diseño. Tampoco es una preocupación meramente estética; como Eric S. Raymond famosamente dijera,

Los programas feos son como puentes feos: tienen un riesgo mucho mayor de caer que los bonitos, porque la forma en que humanos (especialmente ingenieros) perciben la belleza está intimamente relacionada con la forma en que procesamos y comprendemos la complejidad. Un lenguaje que dificulta el escribir código elegante dificulta el escribir buen código.

— Eric S. Raymond, Why Python? (traducción propia)

Y en mi experiencia, ningún lenguaje es mejor en permitir crear código bello que Elixir. En gran medida ésto es porque deriva mucho tanto de la sintáxis bella de Ruby como el diseño elegante de Erlang, pero también tiene constructos interesantemente elegantes sobre ellos, como la sentenciawith:

def get_post(category, date, id) do
  with {:ok, date} <- Date.from_iso8601(date),
       {:ok, result} <- Xandra.execute(conn, get_query, [category, date, id]),
       {:ok, post} <- parse_post(result) do
    post
  end
end

Con ella y la comparación de patrones de Erlang, podemos lidiar elegantemente con el hecho que aceptamos un parámetro como String cuando nuestra librería espera una estructura Date. Pero, ¿qué sucede si alguno de los patrones falla? la expresión completa hace corto-circuito y retorna la tupla “problemática”, casi seguro de la forma {:error, reason}, la que es luego retornada por la función; todo de forma implícita, sin tener que lidiar manualmente con el error.

2. Es flexible con distintas filosofías

Otra razón por la que me gusta Elixir es porque siento que puedo escribir código en una variedad de estilos y filosofías distintas, sin perder mucho de su elegancia. ¿Han intentado alguna vez escribir LISP de forma procedural? ¿Código Orientado a Objetos en C puro? ¿Java en el estilo Funcional? es un ejercicio divertido y educativo, pero también deja claro por qué sería una decisión terrible para la mayoría de proyectos reales.

Elixir no es adecuado para todos los paradigmas posibles, tampoco, pero encuentro que es mucho más tolerante de pequeños faux pas ocasionales que otros lenguajes—y correspondientemente, que no fuerza sus propios paradigmas tanto, como el Modelo de Actores que forma la base detrás de GenServer y abstracciones superiores como Agent.

Pero incluso dejando de lado los grandes paradigmas, también es flexible en decisiones pequeñas como cuan estrictos ser con el chequeo de tipado. Por ejemplo, en el código de ejemplo de la sección anterior, podríamos haber hecho explícito que nuestros parámetros eran de tipo String agregando antes la siguiente línea:

@spec get_post(String.t, String.t, String.t) :: Post.t | {:error, String.t}

Algunos se sentirán inclinados, entonces, a usar specs en cada función que escriban y usar herramientas de análisis estático como credo para chequear su validez. Otros encontrarán que todo el tema es una molestia y los omitirán consistentemente, mientras que un tercer grupo puede, como yo, decidir usarlos solo en funciones donde los valores que espera o retorna no sean inmediatamente aparentes. Y Elixir soporta todas estas filosofías igualmente bien, sin sentir en algún punto que luchas contra el lenguaje para hacerlo.

3. Tiene un ecosistema fecundo

Para personas que vienen de lenguajes más populares como Ruby o Javascript, ésto sonará extraño a primeras. Pero para aquellos que nos gusta jugar con lenguajes más pequeños—comencé con Elixir hace cinco años ya—conveniencias tales como soporte de CI, bibliotecas para trabajar con bases de datos no-relacionales como Scylla, o incluso un número de usuarios suficientes para depurar un problema con Docker o Kubernetes sin entrar a ver el código fuente de las bibliotecas estándar son comunmente el precio que pagamos por las innovaciones que buscamos.

Eso no significa que haya dejado de usar Crystal u otros lenguajes más pequeños, por supuesto. Pero el punto aquí es uno de suficiencia: siento confianza en que al decidir especializarme en Elixir, seré capaz de usarlo en la mayoría de mis proyectos tanto personales como profesionales, sin necesitar volver a un lenguaje más tradicional de forma tan frecuente que pierda el punto de la especialización.

¿Otras razones?

Hay muchas más ventajas de Elixir, pero una ausencia notable de la lista previa es rendimiento. No porque Elixir rinda mal—benchmarks en distintos sitios muestran lo opuesto, de hecho. Pero he llegado a pensar que hay pocos problemas donde el rendimiento del lenguaje de programación mismo se convierta en el cuello de botella; usualmente entre novatos el problema está en la interfaz entre las capas de aplicación y persistencia, mientras que entre programadores más experimentados (y aquí me incluyo) tiende a ser en la optimización de la capa de persistencia misma. Incluso Ruby, infame por su pobre rendimiento, corre bastante bien y con uso de memoria limitado cuando la solución tiene una buena arquitectura, y se acopla a una base de datos bien indexada y bien consultada detrás. Pero ese es tema para otra oportunidad.