¿Por qué te cambiaste a Elm desde JavaScript?

Wow, gran pregunta!

La respuesta a su segunda pregunta es que he usado Angular y React profesionalmente, esta última durante más de un año. Hace poco decidí que quería cambiar a Elm a tiempo completo, así que me encantaría contarle sobre esa experiencia (también tenga en cuenta que estoy trabajando en una publicación de blog que entra en más detalles).

La verdadera respuesta es que JavaScript es tan agotador para mantenerse al día. No me malinterpreten, el ecosistema es insuperable y es realmente inspirador cuántas bibliotecas increíbles existen para JavaScript. El problema es que encontrar la combinación perfecta de bibliotecas es una búsqueda interminable. El hecho es que puedes obtener literalmente todo y más que Elm tiene con JavaScript y las herramientas y bibliotecas adecuadas. Sin embargo, tener ciertas características aplicadas a nivel de idioma hace que su vida sea mucho más fácil.

Una cosa que he visto al trabajar en una serie de proyectos profesionales y de código abierto es que donde quiera que vaya, las personas hacen las cosas de manera un poco diferente, o en el caso de JavaScript, pueden hacer las cosas de manera muy diferente. Con Elm, obtienes consistencia. Si aspira a ser un programador funcional, puede hacerlo con JavaScript y la mezcla correcta de bibliotecas, o puede comprar en un lenguaje como Elm que admita las mejores funciones funcionales de fábrica. Permítanme entrar en algunas de estas características a continuación y hablar sobre por qué son importantes.

Mecanografía Estática

    1. Por defecto, Elm tiene tipeo estático e inferencia de tipeo. Si no proviene de un lenguaje tipado estáticamente, es posible que no se dé cuenta de lo poderoso que es el tipeo estático. Muchas de las excepciones de tiempo de ejecución que ve en un lenguaje como JavaScript son causadas por el hecho de que sin tipos estáticos, el compilador no puede hacer un análisis estático de su código para determinar de antemano los errores de tiempo de ejecución que pueden ocurrir.
    2. Con Elm, tienes un poderoso sistema de tipo estático y un increíble compilador que capturará casi el 100% de las excepciones de tiempo de ejecución. Hay informes de que con Elm en producción, las excepciones de tiempo de ejecución se eliminan. ¿Imagina nunca tener que lidiar con la depuración de excepciones de tiempo de ejecución fatal? Eso es realmente poderoso y no es una característica que se pueda pasar por alto.
    3. Con JavaScript, puede usar ciertas bibliotecas (Flow y TypeScript) para agregar verificación de tipos estática a su flujo de trabajo. Hay dos problemas con este enfoque, el primero de los cuales ya he discutido, y es el hecho de que no hay garantías de que todas las empresas para las que trabaje permitan el uso de estas bibliotecas. En segundo lugar, tanto el flujo como el mecanografiado le permiten cerrar esencialmente la verificación de tipo de tiempo de compilación, lo que a veces puede dificultar la aplicación en un equipo. Tan pronto como tenga dificultades con el sistema de tipos, usted o sus compañeros de equipo simplemente lo apagarán para una parte de su aplicación, lo que elimina todos los beneficios.

Datos inmutables

    1. Por defecto, los registros (objetos) en Elm son inmutables. Por supuesto, puede obtener estructuras de datos inmutables en JavaScript con Immutable JS. Una vez más, el problema es que no hay garantías de que su equipo lo acepte y también puede trabajar con personas que no entienden completamente los beneficios.
    2. ¿Cuáles son los beneficios de los datos inmutables? Me alegra que lo hayas preguntado.
      1. Aunque las estructuras de datos inmutables suelen tener un menor rendimiento en comparación con las estructuras de datos mutables, puede utilizar técnicas de optimización del rendimiento para acelerarlas. Por ejemplo, puede usar la memorización para almacenar en caché los resultados de las funciones puras, lo que hace que el rendimiento general de la computación compleja sea mucho más eficiente cuando se realizan llamadas repetidas. Además, con React, puede habilitar ciertas optimizaciones que solo están disponibles cuando se usan datos inmutables. Un ejemplo de esto es el PureComponent (anteriormente pure-render-mixin), mediante el cual puede deshabilitar inteligentemente la re-renderización de componentes cuando no haya cambiado ningún dato. Vea mi artículo sobre el tema para más detalles.
      2. Además del rendimiento, los datos inmutables cuando se usan correctamente hacen que su aplicación sea mucho más fácil de razonar. Esto puede sonar un poco ruidoso, pero es cierto. Cuando desarrolle con React / Redux, podrá desarrollar funciones de forma aislada con la garantía de que cuando las conecte a su aplicación lo hará sin introducir errores de estado. Al combinar datos inmutables con funciones puras y administración de estado (ala redux o elm-architecture), de repente es simple crear una interfaz de usuario interactiva compleja (más abajo).

Arquitectura de olmo

Una de las sorprendentes revelaciones para mí fue que Redux está esencialmente habilitado por defecto en Elm. De hecho, Redux se inspiró mucho en la arquitectura Elm. Se recomienda que almacene su estado en un solo registro en Elm, que es esencialmente la Tienda Redux. Al igual que en Redux, para realizar mutaciones de estado, pasa el estado de su modelo a través de una función pura (función reductora) que devuelve el siguiente estado.

Permítame compartir un fragmento de código para demostrar las similitudes.

En Elm, utiliza una expresión de caso para activar un Tipo de unión para manejar cada tipo de acción. Devuelve el siguiente objeto de estado utilizando la inmutabilidad (habilitado de forma predeterminada con los registros de Elm y la sintaxis que se muestra a continuación).

caso mensaje de
Visibilidad de ChangeVisibility ->
{modelo | visibilidad = visibilidad}

Realmente me sorprendió cuando hice esta correlación. Con Redux, haces casi lo mismo. En lugar de activar un tipo de Unión, activa un tipo de acción am. Además, utiliza la sintaxis Object.assign más detallada (hay alternativas) para proporcionar inmutabilidad.

switch (action.type) {
caso ‘CHANGE_VISIBILITY’:
devolver Object.assign ({}, estado, {
visibilidad: action.visibility,
});
}

DOM virtual

Elm también utiliza la idea de un DOM virtual, lo que le permite renderizar declarativamente HTML a través de funciones puras.

Aunque la sintaxis no es tan hermosa como JSX, sigue siendo muy útil, especialmente si ha pasado algún tiempo trabajando con React. Una ventaja que tiene Elm Virtual Dom sobre React, al menos en este momento, es su velocidad. El compilador de olmos está increíblemente optimizado y esto se puede ver en los puntos de referencia de comparación. En resumen, expulsa a la competencia del agua en términos de rendimiento de renderizado.

NOTA: De hecho, hay una biblioteca Elm JSX llamada ElmX, pero todavía tengo que usarla.

Funciones puras

Elm habilita funciones puras por defecto, que es una característica muy agradable. Combinado con el auto curry y una sintaxis de aplicación de función muy expresiva (operador de tubería), Elm básicamente te obliga a pensar como un programador funcional.

La pregunta que a menudo me hacen las personas que sienten curiosidad por Elm es cómo hacer módulos reutilizables. La respuesta es realmente simple. ¡Un módulo reutilizable en Elm es solo una función! De hecho, se recomienda no pensar en términos de componentes en Elm. Al abrazar la idea de que los módulos están formados por funciones puras reutilizables, puede obtener los beneficios de la arquitectura orientada a componentes sin las complejidades que se ven en las aplicaciones React. Aunque realmente amo la arquitectura de componentes, también amo las cosas que hacen mi vida más fácil y esta es una de ellas.

Estructuras de datos monádicas

Elm presenta una serie de estructuras de datos monádicas útiles. Lo bueno del enfoque en Elm es que no los llama mónadas. Esto le permite obtener todos los buenos beneficios de las mónadas, sin tener que entender la teoría de categorías.

Déjame darte algunos ejemplos de esto. Por un lado, en JavaScript tienes promesas. Las promesas son muy similares a Futures / Tasks. Sin saber mucho acerca de las mónadas, uno puede usar Promesas para hacer que su código asincrónico sea más fácil de razonar. Otro ejemplo son los opcionales en idiomas como Swift y Scala, que son sorprendentemente similares a la Mónada tal vez y tratan de eliminar los molestos valores nulos.

El hecho es que las mónadas se pueden usar para encapsular el flujo de control de manera declarativa. Dicho esto, realmente no tiene que tener experiencia en programación funcional o teoría de categorías para obtener los beneficios de estas útiles estructuras de datos. Al pensar en ellos como características predeterminadas del idioma, se le da confianza en su utilidad. En Elm, las mónadas son solo otra característica del lenguaje y son extremadamente poderosas y divertidas para trabajar.

Con todo, Elm es un lenguaje encantador. Es muy divertido trabajar con él y es muy fácil de aprender. El hecho de que se compila directamente en HTML, CSS y JavaScript lo convierte en uno de los mejores idiomas disponibles para el desarrollo web front-end. En mi experiencia, casi no hay inconvenientes en abrazar a Elm. Obtiene todas las mejores funciones del ecosistema JavaScript habilitado de forma predeterminada, lo que facilita la creación de complejas interfaces de usuario web.

Intenté algunos ejemplos en Elm al cubrir los comentarios de Ryan C. Collins

  1. Inmutabilidad usando tipos de datos de Elm
  2. Manejo de posibles errores de tiempo de ejecución utilizando el tipo Quizás
  3. Arquitectura de olmo
  4. Llamada http de Elm y transformación de JSON a Elm y Elm a JSON utilizando codificación y decodificación JSON

Desarrolle un software mejor, juntos