sábado, 5 de julio de 2008

Primer proyecto con Scala

Ya estoy usando Scala para un proyecto real. Se me dio la ocasión tan esperada de probarlo, gracias a varios factores:
  • la aplicación tenia que generar mucho XML, o más concretamente, mucho KML (el lenguaje para describir capas georeferenciadas de G.Earth). Como yo sospechaba que Scala se destaca en eso, era el momento de probarlo,
  • tenia que hacer una maqueta rápida para fijar las expectativas del proyecto. Había que comprobar que tan ágil es el lenguaje y el framework Liftweb
  • el proyecto esta clasificado como "innovación tecnológica" por el cliente. Si bien la innovación esta relacionada con el uso de GIS, es también la ocasión de innovar en otros temas.
  • desde el año pasado estoy leyendo tutoriales, blogs y artículos sobre este lenguaje y lo encuentro realmente interesante. Me picaban las manos por usarlo.
Sabia que iba a tener que acostumbrarme a varios temas:
  • la sintaxis. Scala es un lenguaje que mezcla programación orientada al objeto y programación funcional. No soy computín de formación y nunca me enseñaron lenguajes como LISP.
  • el uso de nuevas API's, Scala tiene la reputación de tener un sistema de tipo de datos (type system) mejor hecho que Java, había que probarlo.
  • un nuevo entorno de programación: editor, compilador, utilidad make, debugger, profiler. Scala no esta todavía completamente integrado con los IDE's de Java (Eclipse, Netbeans)
  • aprender a usar frameworks hechos para Scala:
    • web (el equivalente de Struts, JSF, Wicket en Java),
    • ORM (el equivalente de JPA, Toplink, Hibernate en Java).
  • integración con Java: si el cliente me rechaza el uso de Scala para la implementación final, tengo que poder revertir a Java rápidamente. Idealmente, la lógica más coimpleja tenia que estar codificada en java.

Tema sintaxis

Fue más fácil de lo que había previsto. Sin lugar a duda, ayuda bastante que Scala sea de tipo "Strong Typing" y que el compilador captura muchos errores. También, ayuda bastante la capacidad de "syntax highlighting" del editor: sin eso, sería penoso reconocer el XML dentro del código Scala.

Tuve algunas sorpresas con el "type inference" cuando se usa junto con "implicit parameters": yo esperaba transformaciones de tipo que nunca ocurrían, el compilador no arrojaba errores y la aplicación fallaba durante la ejecución. La solución entonces fue explicitar el tipo de datos que yo esperaba.

Todavía me quedaron algunos metodos usando el estilo imperativo (algunos loops "for"), pero no encontré tan difícil usar closure, listas, (con flatMap(), foldLeft), case class y pattern matching

Ahora, empezó a leer código de terceros y no lo encuentro marciano. Eso es un buen signo.


Uso de nuevas API's

Eso no es difícil pero es demoroso. El hecho de no tener un IDE con "code completion" no ayuda porque hay que bucear en los scaladocs. Tampoco me ayudo el hecho que muchos ejemplos (en particular los de Liftweb) son fragmentos del archivo fuente y no muestran los import necesarios. Menos mal que existe "San Google" para encontrar el código fuente donde estaban los métodos que ya veía en los ejemplos.


Nuevo entorno de programación

Volví a usar jEdit usando este plug-in. Lo encontré más completo que la solución para Eclipse y Netbeans. Ya dije que eche de menos el "code completion" y gracias al hecho que conozco bien jEdit, pude arreglármela con la ausencia de "refactoring". No he tenido que depurar o hacer profiling.

Para LiftWeb tuve que usar Maven. Ya lo había usado antes con Magnolia y Alfresco (dos CMS's hechos en Java). ¡No deja de asombrarme que cada vez que se ejecuta por primera vez, parece que descarga la internet entera! Tuve algunos problemas para referenciar bibliotecas de Oracle (el driver JDBC y TopLink), al final, las instale a mano en el repositorio local de maven.



Reemplazar frameworks de Java

La decisión es rápida porque no hay muchos. El único framework web es LiftWeb.

También es un ORM pero:
  • no me gusto. No se explicar porque.
  • quería mantener la lógica de negocio en Java, entonces era más fácil mantener también el modelo de dominio en Java.
  • es muy fácil usar JPA dentro de un IDE Java.
  • hay buena documentación para integrar JPA con LiftWeb
La implementación de RESt en LiftWeb es espectacular y eso me ayudo bastante para retornar KML vía HTTP para el cliente G.Earth.

LiftWeb es como el framework Wicket de Java, no hay posibilidad de lógica Scala dentro del código XHtml. Pero, es fácil que código XHtml se inscruste dentro del código Scala. Por ejemplo, para desplegar un maestro/detalle de 3 niveles (maestro -> detalle1 -> detalle2) recibiendo el id del maestro como parámetro de la pagina, tuve que dejar el XHtml del detalle1 y detalle2 dentro del código Scala. No es tan grave, gracias al hecho que Scala soporta tan bien XML, pero no es elegante (no hay separación total entre el diseño web y la programación).

Finalmente, el uso de LiftWeb me hizo descubrir unas bibliotecas Javascript muy buenas: jQuery y Flot. Se nota que es una comunidad muy entusiasta y muy al tanto de las últimas novedades.


Integración con Java

Ya mencione que uso JPA para mis clases de dominio. Uso Netbeans para crearlas e interactuar con la BD. Como costumbre dejo que TopLink, la implementación JPA de Oracle presente en Netbeans, cree las tablas/indices y poblo las tablas usando test unitarios. Cada vez, veo menos SQL.

La documentación para integrar JPA con Scala es muy util. Menciona las conversiones entre colecciones de Java hacia listas de Scala. Lo que no menciona es la necesidad de convertir objetos nulos (por ejemplo una búsqueda por id que no retorna nada) a objetos tipo Option[Entidad] en Scala. Para facilitar todo eso, deje en un solo objeto Scala (Model.scala) la responsabilidad de conectarse con JPA y retornar listas y objetos más fáciles de usar en Scala: es una capa DAO muy común en Java.

Todo funciona bien, pero echo de menos:
  • un refactoring iniciado en Java que gatilla cambios en Scala (obvio, tenia el código Java en Netbeans y Scala en jEdit),
  • un procedimiento de recompilación más limpio: mi procedimiento usa el soporte ant de Netbeans, luego sube el jar a repositorio local de Maven y finalmente ejecuta Maven para compilar Scala. Supongo que puedo mejorar eso, pero no es una prioridad.

Otras consideraciones

Porque Scala es un lenguaje compilado, existe todavía un tiempo entre editar el fuente y ver el resultado en el browser. En un lenguaje más dinamico (tipo Ruby, PHP, Python), el turn-around es más corto: se guarda el fuente y se refresca la página. Es evidentemente una ventaja de estos lenguajes, pero:
  • quizás algún día Resin soportará Scala y nos dará el Zero Turn Around que siempre nos ha dado con Java, JSP y recientemente con PHP,
  • otros servidores de aplicación JEE, consientes de esta ventaja de estos lenguajes, también mejoran el tiempo necesario para refrescar las aplicaciones y para rebootearse por completo. Por ejemplo, el proyecto Glassfish esta muy preocupado de este tema
  • JavaRebel regala su producto para desarrolladores Scala,
  • mientras tanto, prefiero mil veces esperar que el compilador trabaje por mi antes de buscar errores muy extraños al momento de ejecutar. Estimo que perdí en total 2 horas esperando ant, javac, maven, scalac y el rebooteo de Tomcat. Creo que habría perdido días resolviendo algunos errores oscuros de tipeo.

Se puede usar un editor de archivo (como notepad o vi) para desarrollar en Scala y Liftweb. Eso es una buena medición de lo simple que es. En comparación un proyecto EJB 2.1 requiere generar código intermedio y mantener archivos de configuración XML demoniacos: sin un IDE es realmente una pesadilla.


Conclusión

Scala y LiftWeb simplican el desarollo web y en particular el tema de XML (fácil, era tan horrible...). Es muy temprano para saber si mi inversión en aprenderlos valió la pena: va a depender cuantos clientes estan dispuestos en innovar. La interoperabilidad con Java (y también con :Net) es fundamental para romper la barrera de adopción.

Le vendría bien un soporte de excelencia en los mejores IDE del mercado. El plug-in para Netbeans estaría fuera de beta en Agosto, no hay mucho que esperar.

No hay comentarios: