Reflexiones sobre Scala
· 10 minutes readProgramming languagesScalaLlevo programando y pensando en Scala desde 2013. El lenguaje se publicó por primera vez en 2004 por lo que desde ese punto de vista no se me podría considerar un early adopter. Sin embargo, desde la perspectiva del software empresarial sí que puede admitirse que lo cogimos pronto cuando Java, ya en manos de Oracle, mostraba claros signos de estancamiento y falta de innovación.
La decisión no fue improvisada ni mucho menos. Hablé con bastante gente, incluido algunos analistas de Gartner, lo cual no garantiza nada pero ayuda a justificar las inversiones en tecnología, qué le vamos a hacer. En aquellas charlas, llegué a referirme a este camino por el que estaba discurriendo Java como cobolización (curiosamente el término gustó y fue usado en público por uno de estos analistas).
Por aquel entonces se me encargó la misión de construir una plataforma cloud nativa para el sector de la energía que fuera capaz de escalar, trabajar concurrentemente con mucha data, global, innovadora y todos los requerimientos técnicos que os podáis imaginar. El hype alrededor del Cloud y el Big Data era abrumador. El ecosistema Java está ahora muy bien servido en ese área con proyectos como Spring Boot, Micronaut o Quarkus, pero entonces no había muchas opciones atractivas en la JVM para hacer lo que luego se llamó microservicios, excepto Akka.
No queríamos abandonar la JVM y de hecho Akka ofrecía también un API para Java pero el proyecto tenía un bias claro hacia Scala, el lenguaje con el que se había escrito. Algunos gigantes de Internet estaban ya usando y promoviendo Scala como LinkedIn, Twitter o Foursquare, probablemente al principio como un mejor Java. No estábamos solos. ¿Por qué no podíamos hacerlo nosotros?.
Dificultades y lecciones #
No fue fácil, para qué nos vamos a engañar. Scala tiene fama de ser un lenguaje complejo y, en fin, lo es. Los que opinan que no es más complejo que otros, digamos Python, aducen que la dificultad no proviene del lenguaje en sí sino del cambio de paradigma que supone pasar de la mentalidad imperativa y orientada a objetos a la programación funcional y declarativa. No estoy de acuerdo. La dificultad proviene de la absoluta ausencia de dogmatismo que se traduce en mil maneras distintas de hacer las cosas.
En su momento traté de corroborar esta tesis con un par de experimentos. En el primero de ellos recurrí a la fuente y me propuse aprender el lenguaje funcional puro y sin mácula por excelencia: Haskell. Dejando a un lado la jerga de la teoría de categorías, que bueno, se las trae pero te acostumbras una vez aprendes a introducir letras griegas desde el teclado, me pareció mucho más accesible y simple. Y lo es porque todo el lenguaje pivota en torno a premisas incontestables, dogmas que toda la comunidad de Haskell sigue con verdadera devoción. Inmutabilidad, transparencia referencial, type classes, no subtipado, declaratividad, brevedad, monads, etc. Cada libro, cada ejemplo, cada artículo refuerza una y otra vez estas verdades absolutas que no se cuestionan generando un ecosistema unificado cuyo único peligro es caer en la autocomplacencia.
Para el segundo experimento me propuse desarrollar una aplicación en Python pero abandonando de forma deliberada los dogmas del pythonismo. Traté de no usar variables mutables, nada de bucles, muchos generators, data classes, diseño reactivo, lambdas, etc. En esta prueba descubrí dos cosas importantes. La primera es que echaba mucho de menos el tipado estático de Haskell y Scala. La segunda es que Python es un lenguaje muy rico en características con el que se puede hacer programación funcional pero, al contrario que lo que ocurrió con Haskell, todo el ecosistema te empujaba a aplicar exactamente la mentalidad opuesta, es decir, mutabilidad, herencia, verbosidad, etc. La respuesta habitual solía ser, ¿por qué lo quieres hacer de otra manera?, ¿por qué te complicas la vida?. Aquí no lo hacemos así.
Guerras de fe #
Es evidente que la programación moderna está cada vez más guiada por sus usuarios, y cada vez menos por sus creadores, sean comités, empresas o dictadores benevolentes. La evolución de los lenguajes es permeable al medio y se nutre continuamente de su ecosistema que se manifiesta en forma de librerías open source, artículos, entradas en Stack Overflow o Reddit, conferencias, tutoriales, etc. Ya muy pocos se adentran en un nuevo lenguaje con el libro, si lo hay, y la especificación, si la hay, bajo el brazo. Uno se hace un MOOC en Coursera, estudia unos cuantos tutoriales y a programar se ha dicho. Ya iremos solucionando los problemas tal y como vayan llegando.
En un contexto así, los dogmas se materializan en estructuras idiomáticas que ayudan a mantener la simplicidad, la unidad y la homogeneidad. El código resultará más legible porque encuentras los mismos principios aplicados una y otra vez. Sencillamente, el código resulta familiar y eso se traduce en ahorro de horas en la actividad más habitual del programador: mantener el código de otros o el de tu yo del pasado. Sí, ése que siempre es peor que el de tu yo de ahora. Pero, ¿qué pasa cuando las opciones son virtualmente ilimitadas?.
Cuando no hay dogmas, resulta que los individuos se los crean organizándose en subcomunidades o tribus. Echad un vistazo a JavaScript y sus incontables frameworks, Angular, React, Vue.js, etc, cada uno de ellos configurando sus propias comunidades, con sus principios y cultura propias. JavaScript, que nació siendo un modesto lenguaje para dotar de algo de interactividad a las torpes webs de los noventa, se ha convertido en una especie de lingua franca del desarrollo front estirándose como un chicle y reinventándose a sí mismo una y otra vez mientras defiende su reinado frente a sus nuevos competidores, como TypeScript, Elm o Dart.
Scala, más académico y formal, enraizado en el mundo de la investigación y empujado por postdocs cuya máxima aspiración era que el resultado de sus tesis acabara en master, presenta sin embargo síntomas similares. Plantearse el diseño de un lenguaje desde la óptica de hibridar la orientación a objetos y la programación funcional, es cuanto menos ambicioso y muy osado, teniendo en cuenta que ya existen comunidades bien establecidas en ambos lados que estarán dispuestas a defender ardorosamente sus postulados y que se reconocerán como antagonistas. A priori, la convivencia en esta suerte de franja de Gaza parece complicada. Y efectivamente eso es lo que hemos visto.
Las guerras de fe entre distintas tribus han sido continuas en Scalaland llegando incluso a personificarse. Por un lado, la EPFL defendiendo su proposición de valor que resulta de la combinación de objetos, programación funcional e interoperabilidad con Java. Por otro, los haskellers que encontraron una oportunidad de monetizar sus inversiones intelectuales con un lenguaje que, dándole algunos martillazos, permitía programar à la Haskell y que te pagaran por ello. En medio, los programadores rasos no radicalizados que en sus contextos corporativos sólo querían hacer el trabajo y se apoyaban en Akka y Spark principalmente.
Liderazgo y gobierno #
No he conocido ninguna comunidad de programación que cuestione tanto su liderazgo como la Scala community. Es cierto que incluso Guido ha terminado por tirar la toalla cansado de tener que aguantar carros y carretas por defender sus postulados, pero lo que ha tenido que soportar Odersky todos estos años ha estado a la altura de Simón del desierto. Como colofón, recientemente tuvo que enfrentar la cancelación de uno de los miembros más valorados de la comunidad por supuestas conductas inapropiadas en su ámbito privado, todo ello a una semana del anuncio de la primera release de Scala 3 con el consiguiente eclipse informativo. Un nuevo compilador en el que ha invertido ocho años de su vida y la de su equipo. De traca.
Por supuesto con esto no quiero decir que no se pueda discrepar del dictador benevolente, sobre todo cuando existen los mecanismos para ello, como foros de discusión y grupos de trabajo, pero creo que también es justo respetar que alguien quiera llevar a cabo su plan y materializar sus ideas apoyándose en personas y organizaciones afines. Pero efectivamente, en estos tiempos de lo políticamente correcto, parece cada vez más difícil construir algo con independencia y criterios puramente técnicos. Quizá por ello lenguajes más jóvenes están optando por modelos de gobierno más abiertos como el caso de Rust o Unison.
Scala ahora #
Con todo, Scala me ha devuelto con creces todo lo que he invertido en él y lo recomendaría como la mejor manera de hacer back-end generalista ahora. Una vez has encontrado tu manera de expresarte con el lenguaje, las abstracciones e idioms adecuados para tu dominio, y construido un equipo que comparte objetivos y formas de hacer, no hay vuelta atrás.
Resulta refrescante poder empezar un proyecto con su método main y tirar adelante con vanilla Scala sin pensar en frameworks ni recetas. Por supuesto seguro que necesitas librerías, pero las vas añadiendo poco a poco sin que condicionen excesivamente tu estilo de programación, sólo como utilidades. Las ideas que incorporas de la programación funcional y declarativa te guiarán hacia un código más libre de bugs, más fácilmente testeable, muchas veces sin necesidad de mocks. Si la mayor parte de tu código está libre de side effects es testeable tal cual, es composicional y podrás hacer lego programming, construyendo estructuras complejas a partir de las otras más simples. Vivirás esos momentos de gratificación extrema cuando, tras programar durante varias horas y compilar, tu código funciona a la primera. Si compila funciona, ¿verdad?.
Scala no es perfecto, pero es uno de los pocos lenguajes que ha llevado el concepto de declaratividad al programador medio que trabaja en problemas reales del día a día. Bien orientados, tus programas se acercan mucho más a descripciones de la lógica de negocio que tratan de resolver y menos a los detalles de infraestructura y ejecución. Hablamos de programación de alto nivel claro está. ¡No lo uses para escribir drivers de Linux!.
No te quiero engañar. Si vienes de la programación imperativa y orientada a objetos te va a costar. Tendrás que aprender muchas cosas nuevas y pasará algo de tiempo hasta que encuentres tu propia voz pero el viaje merecerá la pena. Empezarás a pensar en la programación de otra manera, más desde los fundamentos y menos desde las herramientas que han construido otros. Te convertirás en un programador activo y creativo que cuestiona sus propias decisiones y busca la mejora continua del código. No querrás volver a lo de antes. No querrás volver a tener que leer cientos de líneas para entender lo que hace un función y dónde demonios se actualiza la variable que te está generando ese bug en producción.
Scala 3 culmina un ciclo marcado por la innovación y sienta las bases para un progreso más estable centrado en la compatibilidad y el mantenimiento de las inversiones, tanto en conocimiento como en la base de código. Con la incorporación del nuevo framework de metaprogramación, basado en quotations, se termina en mi opinión de establecer los puentes entre la tradición de Lisp y la orientación de objetos, uniendo la academia con la industria.
Es cierto que Java, y antes C# con LINQ, están adaptándose progresivamente hacia un modelo de programación más declarativo. Una programación más del qué, que del cómo. Pero Scala parece estar siempre un paso por delante, atrayendo a usuarios y organizaciones que quieren estar en la cresta de la ola y no tener que esperar años para poder experimentar con características que les hagan más competitivos.
El hype sobre Scala ha pasado y probablemente su legacy no le permita innovar tanto como los lenguajes que vienen desde el futuro. Pero tras mejorar en herramientas, construir un ecosistema de librerías rico, propias y heredadas de Java, y conseguir la compatibilidad binaria, Scala está preparado para el mainstream. El momento es ahora.
- Previous: El modelo relacional