sábado, 12 de enero de 2013

Lo que me agrada de Scala: de NPE a Option

Sigo poblando mi lista de lo que me gusta del lenguaje Scala.  La motivación es poder comparar con otros lenguajes parecidos que están llegando para la JVM como Ceylon/Kotlin/Xtend y tener claro lo que tienen que ofrecer estos lenguajes para que valga la pena mirarlos con un poco más de detalle.  En este contexto, cabe mencionar esta encuesta de Infoq donde hay una lista de lenguajes potenciales y donde Scala y Clojure están bien posicionados.

Los títulos anteriores de mis entradas sobre el mismo tema empezaban con "Lo que amo de Scala".  Ahora voy a hablar de algo que solamente me agrada.

Donde Scala se contagia de Java

NullPointerException o NPE existen porque cualquier objeto en la JVM puede tener el valor null.  No hay forma en Java garantizar que un objeto es distinto de null excepto validandolo antes de referenciarlo.  Si se valida en forma paranoica todos los parámetros de entrada  y retornos de los métodos, se agrega mucho código bastante inútil.  La otra solución es no validar nada y capturar la NPE lo más inteligentemente posible. Si se opta por no validar, en algún momento aparecerá el NPE en algún log y ojala antes de entrar en producción.

Scala corre sobre la JVM e necesita interoperar con código Java.  Sigue existiendo el valor null y la posibilidad de NPE incluso en código 100% Scala.


Valores opcionales

Java no permite hacer la distinción entre un objeto que es nulo por error o intencionalmente sin valor.  Un objeto puede estar sin valor:
  • porque es naturalmente opcional, como el calculo de un valor máximo sobre una colección vacía o el retorno de una consulta por una primary key que no existe.
  • porque no conocemos aun su valor:
    • hay que rescatarlo con algún proceso largo, 
    • es un valor externo que debemos rescatar de parámetros de ambiente, archivos de configuración o preguntar al usuario.
En Java se puede manejar estas situaciones con objetos nulos o lanzando excepciones.  En SQL se puede definir un campo como "NULL" o "NOT NULL".  Scala soluciona este caso con el tipo Option y los subtipos None y Some.

Ejemplo de un atributo que es opcional y cuyo valor se conoce al runtime.


Un caso frecuente en mis aplicaciones es durante la inicialización de actores con el framework Akka.  Generalmente, los actores se crean en unos pocos thread y si su inicialización es larga (por ejemplo, porque tienen que rescatar algo de una base de datos) el arranque de la aplicación akka es lenta.  Entonces, el arranque del actor se hace en 2 pasos: la creación del actor mismo y luego su inicialización procesando un mensaje de "arranque".  Entre estos 2 pasos hay atributos del actor que no están conocidos aun.


Algunos comentarios finales

Entonces, porque solamente me agradan los Option y no los adoro:
  • Habría sido espectacular eliminar el valor nulo y la NPE por completo.  Pero prefiero mil veces mantener la interoperabilidad con Java, la cual si adoro.
  • Ceylon y Kotlin tienen una sintaxis especial para manejar los nulos la cual permite código más corto y más legible.  Scala no usa sintaxis especial, sino la capacidad de su type system.  El mismo type system permite implementar tipos equivalentes como los Box/Full/Empty/Failure del framework Liftweb .
En resumen, Scala mejora Java sin erradicar por completo el problema.  

No hay comentarios: