Novedades

Por qué F# es el mejor lenguaje empresarial

Para que quede claro, sólo voy a hablar del llamado "desarrollo empresarial". No estoy afirmando que F# sea el mejor para programación de sistemas, o desarrollo de juegos, o proyectos de pasatiempos. Lo que es apropiado para un tipo de objetivo de desarrollo puede ser inapropiado para otro. El desarrollo empresarial tiene sus propias limitaciones y exigencias, para las que creo que F# es particularmente adecuado.

Comenzaré con una importante advertencia, que es que no creo que el éxito o el fracaso de un proyecto dependa del uso de un lenguaje de programación en particular. Mucho más importantes son cosas como la buena comunicación, los requisitos claros, el cuidado de la experiencia del usuario, las expectativas realistas, y así sucesivamente. ¡Si el lenguaje de programación fuera realmente tan importante, entonces no habría compañías exitosas que usaran PHP, Visual Basic o JavaScript, y todos los trabajos requerirían habilidades de Haskell y Lisp!

Sin embargo, dicho esto, creo que la elección del lenguaje de programación tiene un efecto sobre la productividad, la mantenibilidad y la estabilidad, y de eso es de lo que voy a hablar en este post.

Las características del Desarrollo Empresarial

Entonces, ¿Cuáles son algunas de las características clave del desarrollo de software para empresas?

El desarrollo de software no es el foco del negocio

En una "empresa", el software se trata generalmente como una herramienta; un centro de coste en lugar de un centro de beneficio. No hay presión para tener la última tecnología, contratar a los mejores desarrolladores, o invertir en capacitación.

Esto significa que el ser una "empresa" no tiene nada que ver con el tamaño de la empresa. Por mi definición, Google no se dedica al desarrollo empresarial, mientras que una empresa B2B de 50 personas probablemente lo hace.

Esto también significa que las empresas que desarrollan software interno para obtener una ventaja competitiva, como las empresas de FinTech, tampoco cuentan como "empresas".

Los proyectos se centran en el negocio y no en la tecnología

El objetivo del desarrollo empresarial es, en general, apoyar los flujos de trabajo de las empresas en lugar de aplicar un conjunto específico de requisitos técnicos. En el nivel más básico, el software empresarial típico simplemente mueve los datos y los transforma. Esto suena trivial y a menudo se considera que no es una "programación real".

Pero los flujos de trabajo de los negocios involucran a los seres humanos, y cada vez que los seres humanos están involucrados, habrá complejidad. La implementación de un algoritmo eficiente de mapeo/reducción o la optimización de un sombreador de gráficos puede ser delicada, pero posiblemente no tan delicada como algunos flujos de trabajo de negocios! Esta cita de 30 años sobre COBOL lo resume muy bien:

El sesgo en contra del dominio de los problemas se establece explícitamente en[a] el manual del lenguaje de programación, que dice que COBOL tiene "una orientación hacia el procesamiento de datos comerciales... en el que los problemas son... algoritmos relativamente simples junto con un alto volumen de entrada-salida (por ejemplo, el cálculo de la nómina para una gran organización)".

Cualquiera que haya escrito un programa de nómina serio difícilmente lo caracterizaría como "relativamente simple". Creo que los informáticos simplemente no han estado expuestos a la complejidad de muchas tareas de procesamiento de datos empresariales. A los informáticos también les puede resultar difícil ofrecer teorías elegantes sobre las molestas y omnipresentes complejidades de muchas aplicaciones realistas de procesamiento de datos y, por lo tanto, rechazarlas. - Ben Shneiderman, 1985

Lamentablemente, el desarrollo empresarial nunca ha sido atractivo.

Los proyectos empresariales a menudo tienen una larga vida útil

No es exclusivo del desarrollo empresarial, por supuesto, pero es común que los proyectos de software empresarial vivan mucho tiempo (si sobreviven a la infancia). Muchos proyectos duran cinco años o más - estoy personalmente familiarizado con uno que comenzó en los años 70 - y durante su vida, muchos desarrolladores estarán involucrados. Esto tiene un par de corolarios: 

  • La mayor parte del ciclo de vida del proyecto se gasta en el llamado "mantenimiento", un término engañoso para lo que es básicamente una evolución a baja velocidad (con ocasional pánico a alta velocidad también).
  • Si eres un desarrollador que trabaja en un proyecto de larga duración, la mayor parte del código no habrá sido escrito por ti, ni siquiera por nadie de tu equipo.

Hay una charla muy interesante de Robert Smallshire en la que simula la generación de código para equipos de diferentes tamaños en diferentes periodos de tiempo. Así, por ejemplo, después de cinco años, el equipo actual generalmente sólo habrá contribuido con el 37% del código.

Para un equipo más grande durante un período más largo, el porcentaje de contribución puede caer aún más bajo.

Sí, estas son simulaciones, pero suenan ciertas en mi experiencia.

Los gerentes de proyectos empresariales tienen una baja tolerancia al riesgo

Como resultado de todos estos factores, los gerentes de proyecto tienden a ser reacios al riesgo y rara vez son los primeros en adoptarlos - ¿por qué romper algo que ya está funcionando?

Como dice el refrán "el proceso es el tejido cicatricial de las organizaciones". La estabilidad es más importante que la eficiencia.

Sin embargo, de vez en cuando surgen nuevas condiciones ambientales que obligan a cambiar incluso a las empresas más conservadoras. Por ejemplo, la nueva "intranet" e "internet" de los años 90 asustó a mucha gente y tuvo mucho que ver con el auge de Java y VisualBasic/ActiveX. Así es como se veía la publicidad en ese entonces:

  • 1996: "Como Netscape y Microsoft luchan por el dominio de Net, tanto Java como ActiveX son piezas clave en el tablero."
  • 1997: "Antes de Java, no había un lenguaje de programación de Internet."

Menos de 10 años después de la publicación de esos artículos, los lenguajes de programación empresariales dominantes habían cambiado a Java y C#.

Gracias a las aplicaciones móviles y al aumento de la nube, creo que estamos en medio de otra era como ésta, en la que las empresas están dispuestas a arriesgar nuevas tecnologías para no quedarse atrás. El reto, por supuesto, es cómo adoptar nuevas tecnologías sin grandes trastornos.

¿Qué es importante a la hora de elegir un idioma empresarial?

Entonces, ¿Cómo afecta todo esto a la elección de un lenguaje de programación y su ecosistema asociado, desde el punto de vista de un gestor de proyectos?

Debe ser amigable para la empresa.

Un director de proyecto no sólo elige un lenguaje de programación, sino que también se compromete con el ecosistema que rodea al lenguaje y con el soporte futuro para ese ecosistema. Como se ha señalado anteriormente, el desarrollo empresarial no se trata de estar en la vanguardia. Más bien, si el ecosistema tiene el apoyo de una empresa amiga de la empresa como Microsoft, Oracle o Google, eso es una gran ventaja.

Además, desde el punto de vista del administrador de la empresa, es fundamental que el lenguaje y su ecosistema tengan un soporte profundo para bases de datos empresariales (Oracle, Sql Server), servidores web empresariales, autenticación empresarial (AD, LDAP), formatos de datos empresariales (XML), etc. Es poco probable que el apoyo a la última moda sea su principal preocupación.

Debería estar preparado para el futuro.

Dada la longevidad de los proyectos empresariales, queremos asegurarnos de que el ecosistema y las herramientas sigan existiendo y reciban apoyo en, digamos, 10 años. Si aparecen nuevas plataformas, no deberías tener que tirar todo tu código.

Debe ser flexible

Dada la longevidad de los proyectos empresariales, queremos asegurarnos de que el ecosistema y las herramientas sigan existiendo y reciban apoyo en, digamos, 10 años. Si aparecen nuevas plataformas, no deberías tener que tirar todo tu código.

Debe ser flexible

Y si va a comprometerse con un ecosistema, lo ideal es que lo utilice en tantas situaciones como sea posible (por ejemplo, aplicaciones de escritorio, aplicaciones de servidor, aplicaciones web) y diferentes plataformas de destino (Windows, Mac, Linux, móviles, etc.).

Debe hacer que el mantenimiento sea fácil

Dado que los miembros del equipo probablemente rotarán durante la vida del proyecto, y la mayoría del código no será escrito por el equipo actual, las preocupaciones dominantes son cosas como:

  • Comprensión: ¿Qué tan fácil es entender el código que escribió un miembro anterior del equipo?
  • Productividad: ¿Podemos añadir nuevas funciones de forma rápida y segura?
  • Seguridad: Si se realiza un cambio o refactorización, ¿podemos estar seguros de que no romperá nada?
Elegir un idioma empresarial, parte 1

Con estos requisitos, podemos utilizarlos para reducir nuestras opciones de lenguaje.

  • Para facilitar el mantenimiento y la seguridad, la mayoría de la gente está de acuerdo en que se necesita un lenguaje estático. Cuando se tiene una gran base de código con 10 ó 100 personas trabajando en ella a lo largo de los años, los lenguajes de escritura estática soportan una mejor refactorización, y los errores en tiempo de compilación pueden ayudar a evitar que el código defectuoso entre en producción.
    Aquí está John Carmack sobre este tema: 
    • Las mejores intenciones no importan. Si algo puede ser ingresado sintácticamente de manera incorrecta, eventualmente lo será. Y esa es una de las razones por las que me he hecho muy grande en el análisis estático, me gustaría poder habilitar subconjuntos de lenguajes aún más restrictivos y restringir aún más a los programadores porque cometemos errores constantemente. - John Carmack, 2012
  • El desarrollo de software no es el foco del negocio, esto significa que el énfasis está en la estabilidad y la productividad, más que, por ejemplo, en el rendimiento. Esto implica que un lenguaje de programación empresarial no debe permitir acciones potencialmente peligrosas como el control de la memoria y la aritmética de punteros. Incluso si se puede hacer con seguridad, como en Rust y el moderno C++, el esfuerzo por exprimir el rendimiento extra, generalmente no vale la pena.
  • Debe ser amigable para la empresa, por lo que no es de extrañar que los favoritos lo sean:
    • Java (y lenguajes en la JVM que pueden aprovechar el ecosistema de Java).
    • C# (y otros lenguajes en el ecosistema .NET).
    • Go también obtiene algunos puntos aquí debido a que Google lo soporta, y puede estar seguro de que las bibliotecas críticas de la empresa estarán disponibles.

Hasta ahora, sin sorpresas. Hemos encontrado a los sospechosos habituales, Java y C#.

Si esto fuera 2008, habríamos terminado. Pero no lo es, y no lo somos. En la última década, ha habido una explosión de nuevos lenguajes que son fuertes aspirantes a ser mejores lenguajes empresariales que C# y Java. Veamos por qué.

El auge de la programación funcional

La programación funcional es el nuevo punto álgido en este momento, pero a pesar de las exageraciones, la mayoría de los lenguajes de programación modernos están introduciendo características amigables con FP (Functional Programming) que marcan una gran diferencia en la calidad del software:

  • Las funciones de orden superior sustituyen en muchos casos a las interfaces de peso pesado (las bibliotecas C# LINQ y Java streams no serían posibles sin ellas).
  • Diferentes valores predeterminados, como inmutabilidad por defecto y no nulos por defecto. Tenerlos como predeterminados hace que el mantenimiento y la comprensión del código sean mucho más fáciles, ya que las desviaciones de estos predeterminados se señalan explícitamente en el código.
  • La comunidad de programadores funcionales hace hincapié en la necesidad de explicitar los efectos. Esto incluye cosas como el tipo "Result" para el manejo de errores explícitos, y el desplazamiento de E/S y otras fuentes de impurezas en la aplicación (como se ve en los enfoques "Funcional core/imperative shell and Onion Architecture").
  • Finalmente, y lo más importante , los lenguajes influenciados por la FP tienen tipos de datos algebraicos. Es decir, no sólo registros/estructuras, sino también tipos "de elección" (también conocidos como tipos de suma o unioines discriminadas). En mi opinión, estos son esenciales para un modelado efectivo de dominios. Por supuesto, yo diría eso, ya que escribí un libro sobre el tema, pero no soy el único en este punto de vista.

Si nos fijamos en los lenguajes que soportan estas características, terminamos con los lenguajes estáticos de FP (Haskell, F#, OCaml) y los lenguajes más modernos influenciados por FP: Swift, Scala, Kotlin, Rust, TypeScript, etc.

Como he dicho antes, el auge de las nuevas tecnologías, como el no tener servidores, significa que las empresas estarán dispuestas a cambiar a estos lenguajes influenciados por FP si pueden proporcionar una ventaja competitiva (lo que creo que hacen) y si el cambio se puede hacer con una interrupción mínima (que depende de la elección del idioma).

El peligro de demasiada abstracción

Algunos lenguajes de FP (Haskell y Scala en particular) soportan algunas características que permiten altos niveles de abstracción.

"El propósito de la abstracción no es ser vago, sino crear un nuevo nivel semántico en el que uno pueda ser absolutamente preciso" - E.W. Dijkstra

Eso es genial, pero creo que en el contexto específico del desarrollo empresarial, demasiada abstracción puede causar problemas. Si se utiliza con demasiada libertad, requiere que todos los desarrolladores que trabajan en un proyecto tengan la misma comprensión del "nuevo nivel semántico", que es una carga para la formación y la empleabilidad. Todo lo que se necesita es que una persona se tome demasiado a pecho la teoría de categorías en el código, y el código se vuelve insostenible para todos los demás.

Es decir, de la misma manera que te puedes disparar a ti mismo en el pie con características de bajo nivel, también puedes hacerlo con características de alto nivel. En el caso de un lenguaje empresarial, debemos recortar el extremo superior de las capacidades lingüísticas, así como el extremo inferior, y fomentar un enfoque de "sólo una manera de hacerlo" en la medida de lo posible.**

Así que voy a penalizar a Haskell y Scala en este punto por ser demasiado fáciles de abusar.

** Una de las razones por las que Go o Elm son bien aceptados por la gente como lenguajes, es porque son restrictivos. Hay una manera estándar de hacer las cosas, lo que a su vez significa que leer y mantener el código de otra persona es sencillo.

Pero ¿Cuánta abstracción es demasiada?

¿Los genéricos son demasiado avanzados? Hace 15 años, quizás. Pero hoy en día está claro que es una característica de la corriente principal. (¡Los diseñadores de golang no están de acuerdo!)

¿Pero qué hay de las lambdas? ¿Qué tal las monads? Creo que la mayoría de los conceptos de FP están a punto de convertirse en una corriente dominante en la actualidad, y dentro de diez años serán comúnmente aceptados, por lo que es razonable tener un lenguaje que los apoye.

Para mí, en 2018, el nivel de abstracción "just-right" es el que se encuentra en lenguajes ML como OCaml y F#. En 10 años las cosas pueden ser diferentes, y podemos ser capaces de ajustar el nivel de abstracción aceptable.

Sin embargo, no estoy convencido de que una programación más abstracta y de estilo matemático (a la Idris, Coq) sea común en la empresa, debido a la variación en las habilidades de los empleados. Sí, esto podría resolverse con un mejor entrenamiento, o con una cualificación de ingeniero de software certificado, pero no me inquieta que suceda.

Elegir un idioma empresarial, parte 2

Si entonces filtramos estos nuevos lenguajes por el criterio "empresarial" arriba mencionado, terminamos con los lenguajes influenciados por FP que soportan .NET y JVM, a saber: 

  • F# en .NET
  • Kotlin en la JVM.
  • También voy a añadir TypeScript, ya que está muy bien soportado y cumple con los criterios de "empresarial".

Para resumir las objeciones de "por qué no el lenguaje X" de nuevo:

  • C# y Java - Están bien, pero F# y Kotlin respectivamente tienen mejores valores por defecto (inmutabilidad), mejor soporte para efectos y mejor soporte para tipos de datos algebraicos.
  • Swift - Está bien soportado dentro del ecosistema de Apple, pero no muestra signos de propagación en las empresas en general.
  • Ceylon - Kotlin tiene más impulso.
  • Haskell - Sí, Haskell hace cumplir la pureza rigurosamente, sería genial, pero ese no es el único componente de la programación. Y lo que es más importante, no hay una ruta de migración gradual a Haskell, sino que te metes de lleno en el fondo del asunto. Esto puede ser muy bueno para el aprendizaje de la FP, pero no es adecuado para las empresas.
  • Scala - Demasiadas maneras diferentes de hacer las cosas es una desventaja, me temo. Kotlin es más amigable con la empresa.
  • OCaml - Si no necesita soporte empresarial, OCaml es una excelente opción. Pero si lo haces, F# sería más aplicable.
  • Go - Excelente para algunas cosas, pero no se recomienda para empresas debido a la poca compatibilidad con el modelado de dominios con tipos.
  • Elm/Purescript - Front-end sólo por ahora.
  • Reason ML - Por ahora solo Front-End. Además, ¿por qué no usar OCaml?
  • C++/Rust - Si no necesita rendimiento, es más fácil trabajar con un lenguaje GC'd.
  • Erlang/Elixir - Ideal para un alto tiempo de actividad, pero no para empresas.
  • PHP/Python/Ruby/etc - Me gusta mucho Python, pero la mantenibilidad se pierde cuando tienes más de 10K LoC (Líneas de Código). Como he dicho antes, los lenguajes estáticos son la única forma de realizar proyectos de gran envergadura.
¿Qué hay de los tipos de mayor categoría? ¿Qué hay de las clases de mecanografía? ¿Qué hay de los GADTs?

Ninguno de los tres finalistas los apoya ahora mismo. Dejaré que usted juzgue si esto es un obstáculo para el desarrollo empresarial.

Elegir un favorito

Los tres idiomas que quedan (F#, Kotlin y TypeScript) son todas buenas opciones, todas de código abierto, plataformas cruzadas y amigables para la empresa.

Si ya está utilizando la JVM, entonces obviamente Kotlin proporciona la mejor ruta de migración. De forma similar, si está usando Nodo en el servidor, entonces TypeScript es bueno (aunque confiar en los paquetes npm puede ser un problema).

Pero si estás haciendo desarrollo "greenfield" (o si ya estás en .NET) creo que F# tiene la ventaja (y aquí es donde yo podría ser un poco parcial)

  • Tiene un excelente soporte para el modelado de dominios de ceremonias bajas.
  • Es funcional en primer lugar, prefiriendo las funciones y la composición como enfoque de desarrollo primario.
  • La inmutabilidad realmente está en todas partes - es el valor por defecto para los tipos y colecciones algebraicas.
  • Tiene una amplia gama de capacidades. Por ejemplo:
    • Puede crear microservicios que den soporte a millones de clientes. Así es como jet.com lo hizo.
    • Puede escribir JavaScript en F# con Fable. Por ejemplo, el plugin F# para VS Code, llamado Ionide, fue construido en F# y convertido a JS de esta manera.
    • Puedes desarrollar aplicaciones web completas (compartiendo el código entre el front end y el back end) con Safe Stack o WebSharper.
    • Puede crear aplicaciones móviles con la librería Fabulous utilizando un enfoque similar al de Elm.
    • Puedes crear aplicaciones de escritorio con XAML o WinForms o Avalonia.
    • Puede crear scripts ligeros, como construir y desplegar tuberías.
    • Otro buen uso de los scripts es la prueba de la interfaz del navegador.
    • Y, por supuesto, puedes hacer ciencia de datos.

Por supuesto, Kotlin puede hacer algunas de estas cosas y TypeScript algunas de las otras, pero creo que F# es el que tiene la mayor amplitud en general.

Traducción y fragmento de la nota de ScottW: https://fsharpforfunandprofit.com/posts/fsharp-is-the-best-enterprise-language/

Descubra cómo podemos ayudarle

Déjenos su solicitud, uno de nuestros comerciales lo contactará a la brevedad.