martes, 28 de septiembre de 2010

Scala vs y Clojure (Round 1)

Un lenguaje escalable: tanta complejidad como necesites.


Una ventaja de que por la península vayamos retrasados en esto de lo tecnológico es que sea mas difícil que un post como este pueda iniciar un guerra. Pero por si acaso quiero aclarar que aunque mi lenguaje preferido en la intimidad sea Clojure, también aprecio Scala, al menos en lo que ha acercado a la JVM elementos de lenguajes como Haskell y la familia de los ML.
Ambos lenguajes comparten ciertos aspectos pero difieren lo suficiente como para no ser excluyentes dentro de los nuevos lenguajes funcionales que corren sobre la JVM. El mismo creador de Scala, Martin Odersky defendía esta postura en esta entrevista: para que "gane" uno de ellos no tiene porque perder el otro.
Y la diferencia fundamental esta en las razones que ambos surgieran y en su misma filosofía, antes incluso de las diferencias técnica. Esa diferencia se traduce también en sus respectivas comunidades, en lo que te exige como programador y aprendiz y en lo te puede dar.
En general estoy convencido que un lenguaje no es absolutamente mejor a cualquier otro sino mejor o mas adecuado a un contexto determinado, incluido java o cobol.

Scala desde sus orígenes ha querido ser "un mejor java", algo así como un java++. Y aunque ultimamente no es la imagen mas popular, efectivamente lo es. Eso supone que desde su creación se ha caracterizado por tener una sintaxis similar a la de java y unas construcciones parecidas pero mejoradas en cuanto a ser orientado a objetos de una forma mas consistente y expresiva que java. Incluso ha integrado en el lenguaje varios de los patrones de diseño que ya se han establecido casi como norma en java, de una forma sencilla y expresiva.

Como ejemplo podemos echarle un vistazo a este código que declara una típica clase de una aplicación empresarial:



No tiene nada de mala pinta para un programador en java que se acerca al lenguaje.

Por otro lado desde el origen Scala ha tomado como ejemplos lenguajes populares en el ámbito universitario de la "ciencia computacional": Ocaml y Haskell. Tal vez tenga algo que ver que tanto Odersky como Scala están fuertemente asociados a la Escuela Politécnica de Lausanne. Estos lenguajes (incluido el mismo Scala) están en la vanguardia de la investigación en los lenguajes de programación lo que ahora mismo es equivalente a decir que profundizan en el paradigma funcional unido a sistemas de tipado basados en su inferencia. Abstracciones como las Monadas o los Funtores son poderosas y atractivas intelectualmente, incluso tienen su aplicación real aunque tal vez no sea evidente a primera vista. Sin embargo su uso en Scala requiere cierta formación teórica y un conocimiento mas profundo de su sintaxis. Un código es Scala que hace un uso intensivo de estos elementos puede parecer tal que así:



Viendo este código el mismo programador que antes asentía pondrá los ojos en blanco.

Scala es un híbrido y su filosofía es darle todas las opciones posibles al programador aunque suponga hacer el lenguaje mas grande y complejo. Puedes programar orientado a objetos de forma imperativa o funcional, usando datos inmutables o no, usar la evaluación perezosa o no. Es por esto que lo han comparado a c++ ya que parece que también este lenguaje nació un poco con esa filosofía. Odersky tuvo que defender a su lenguaje de esa fama de complejo pero sin negar que lo fuera, sino defendiendo esa complejidad interna y la "escabilidad" del lenguaje, ya que cada uno puede usar Scala a su manera en cada momento y solo usar la parte mas compleja cuando se necesite construcciones mas poderosas. También es verdad que el mismo hecho de aglutinar paradigmas y opciones tan diferentes y el ser "escalable" y flexible añade su propia dosis de complejidad en el computo global sea el uso que sea el que le quieras dar.

El problema de muchos programadores provenientes de java con Scala me parece que es que llegan enganchados al cebo de su sintaxis y semántica básica parecida y su ligera curva de aprendizaje inicial pero cuando quieren dar un paso mas allá y usar las partes mas avanzadas el nivel de exigencia y de dificultad aumenta de forma exponencial, al menos en una segunda fase. Después de todo si te has cambiado de lenguaje es porque se quería usar algo diferente. Hay que ser pacientes y usar poco a poco esas características si no se tiene experiencia anterior o un solida base teórica en lenguajes funcionales tipados. Esa frustación aparece como una de las causas que Scala no se haya hecho mas popular, y se haya agravada por el hecho de que los miembros mas influyentes de su comunidad escriban sobre el lenguaje desde el punto de vista de su parte funcional y sobre el uso mas sofisticado de su sistema de tipado y que establecen casi de facto que ese uso del lenguaje es el estándar.

Según mi forma de ver Scala puede ser un lenguaje apropiado para entornos de programadores java con ganas de aprender pero que quieren empezar con una sintaxis y unas construcciones cercanas y añadir progresivamente elementos mas poderosos cogidos del paradigma funcional. También es una buena opción si se quiere un lenguaje que te permite usar un sistema de tipado estático sofisticado y que gracias a su inferencia te ahorra el tener que escribir muchas de las anotaciones de tipos. La gente que no se encuentren cómodos con los lenguajes dinámicos y echen de menos la velocidad de ejecución que te proporcionan los tipos (Scala es al menos tan rápido como java puro) o la posibilidad de validar/documentar tu programa de forma logica con los tipos, valoraran mas el sistema de tipado de Scala. Mas todavía si tenemos en cuenta que este sistema es mas flexible, rico y breve en código que el de java.

Clojure parte desde un punto de vista totalmente diferente que veremos en la entrada siguiente del blog, pero podemos adelantar que aunque la sintaxis sea totalmente ajena a los lenguajes derivados de Algol (c,c++,java,Scala,etc,etc) y suponga para muchos un handicap inicial casi insalvable en realidad es mucho mas sencillo que Scala, tanto en la sintaxis como en la semántica al centrarse y casi obligar a adoptar desde un principio a las característica funcionales casi puras: inmutabilidad de los datos, separación entre estos y los algoritmos que los tratan, evaluación perezosa, separación entre el valor (inmutable) de un dato y las referencias que nos permiten modificarlo en el tiempo de forma segura en lo que respecta a la concurrencia, etc. La curva de aprendizaje es inversa a la de Scala, muy empinada al principio pero mas leve en cuanto se ha comprendido los principios fundamentales del paradigma funcional y se ha acostumbrado uno a los benditos paréntesis. Pero no hay marcha atras una vez que entras en los paréntesis, mmm, ¿o tal vez sí?

((TO BE CONTINUED))