domingo, 11 de noviembre de 2012

Lo que amo de Scala: los tuples

Tengo una relación de amor y odio con los tuples. Los adoro cuando escribo código por primera vez y los odio cuando vuelvo a leer el código más tarde.  Son, por lejos, lo que me hace más difícil entender mi propio código.  Igual los uso a cada rato porque son demasiado prácticos.

En Scala, Java y cualquier lenguaje tipeado es fácil agregar un parámetro de entrada a un método.  Se define el nuevo parámetro y se deja el IDE o el compilador detectar todos los usos del método que fueron quebrados.  Los tuples me permiten exactamente lo mismo pero con el parámetro de salida.

Como ejemplo, 2 versiones de un método supuestamente complejo: evaluación de riesgo de un cliente  La primera versión solamente retorna un boolean que indica si el cliente es demasiado riesgoso
En la siguiente versión, el método calcula el riesgo usando varios criterios y se requiere retornar un mensaje que indica el porque.

Si no existiesen los tuples, tendría que definir una clase para contener el retorno.  A pesar que en Scala, crear un "case class" es rápido, tengo que por lo menos escoger un nombre para la clase.  Y, es en este preciso momento que adoro los tuples: cuando estoy pensando en un algoritmo no trivial mi capacidad creativa para nombrar las clases, objetos y variables tiende a cero.  Si tengo que detener mi pensamiento para nombrar correctamente la clase, evaluar si puedo re-utilizarla en otra situación, si debo hacerla más genérica, etc, pierdo completamente el hilo del algoritmo que estoy resolviendo.  Los tuples son una forma rápida de salirme del paso y enfocarme en la parte "matemática" del problema.

Los tuples son perfectos cuando uso el resultado del método localmente. Los problemas de mantenebilidad surgen cuando tengo que guardar los tuples en alguna colección y procesarla en otra parte del código. Cuando eso ocurre, tengo que hacer un refactoring y por eso los odio.


viernes, 2 de noviembre de 2012

Lo que amo de Scala: el poder (casi siempre) fácil de usar

Supongo que crear un lenguaje poderoso y al mismo tiempo fácil de usar, es una tarea compleja.  Cuando los creadores de Scala tienen que eligir, prefieren priorizar el poder.  Yo me alegro por eso.

Estoy consciente que la estrategia de Scala no es una necesariamente ganadora.   Se puede argumentar que parte del éxito de Java es debido a su simplicidad inicial.  Muchos competidores de Scala (como Ceylon y Kotlin), usan el argumento de "Scala es complejo" para tratar de ganarle terreno: básicamente, tratan de describir Scala como un lenguaje académico que contiene montones de ensayos que no se juntan perfectamente. Y Scala se ha ganado una imagen de elitista que primero busca satisfacer a los mejores programadores, como los creadores de framework, en detrimento del programador promedio.

Para mi no hay duda, yo prefiero el "poder" y estoy dispuesto a invertir un poco más de tiempo para manejarlo en forma responsable.  Voy a usar para argumentar, el "operator overloading", la implementación de la programación genérica y las conversiones implícitas.  Estas 3 técnicas son generalmente reconocidas como peligrosas o complejas.  Ademas puedo usar Java como referencia para argumentar.


Operator overloading

Java escogió no soportar "operator overloading".  El argumento inicial era que varias bibliotecas C++ (lenguaje donde existe esta capacidad) habían abusado tanto, que son responsables de fuentes que parecen una sopa de símbolos.  Java decidió proteger a los programadores de si mismo.

Yo siento que Java me trata como un bruto que, a pesar de estar informado de los potenciales riesgos, se va a dedicar generar código incomprehensible por el puro hecho que lo puede hacer.  Me parece que es mucho mejor permitir el "operator overloading" e implementar las bibliotecas básicas del lenguaje como una muestra de las buenas practicas.  Y Scala cumple con eso.

El primer ejemplo es la API colección, donde se usa "::" para agregar un elemento a una lista.  


El mismo ejemplo en Java



Otro ejemplo es la "combinator libary" que permite crear un DSL externo.

Una vez que uno se acostumbra a como funciona esta biblioteca, la interpretación de los símbolos "|", "~", "~>", "<~" y "^^" es inmediata y la sintaxis del DSL salta a la vista.

Entonces, ahora cuando veo un símbolo que no entiendo, yo se que no es el símbolo en si el problema, sino que me falta entender bien el concepto o la abstracción que representa.  Una vez que leí la documentación y luego de un poco de practica, el símbolo llega a ser casi invisible y me deja ver el código.  Al contrario, una palabra siempre atraerá la atención y ofuscara el código.  Entonces, luego de una pequeña curva de aprendizaje, el código queda mucho mas limpio y fácil de entender si se usan símbolos adecuadamente.

En este caso, el poder y la simplicidad de uso van de la mano: no hay ninguna razón para no incluir el operator overloading.

Nota: cabe señalar que Scala no tiene "operator overloading" en si, sino que es muy liberal en como nombrar las funciones y métodos.


Programación genérica y herencia

Java decidió no implementar la programación genérica hasta la versión 1.5.  No obstante tomo una decisión clave en su versión 1.0 con respecto a la herencia y los arreglos: si un String es un Object entonces, un arreglo de String es también un arreglo de Object.  Intuitivo pero incorrecto.


La implementaciòn de la programación genérica en Java desde la versión 1.5, no sigue el mismo patrón que los arreglos.  Una decisión que parecía intuitiva y simple, se transformo en una complicación: un arreglo es lógicamente una colección, pero en Java no lo es.

Scala en comparación decidió implementar los conceptos de covariance y contravariance.  Algunas veces, el compilador parece reclamar demasiado y prohibir código "correcto".   Hay que leer y entender la justificación de porque se comporta así, lo que hace el aprendizaje un poco más largo.

En mi caso, cuando me toco implementar un algoritmo de la teoría de los grafos donde los vértices y nodos eran genéricos, recupere el tiempo invertido.


Implicit conversion

Scala usa inplicit en varias partes.  Me voy a referir a las conversiones implícitas porque se parecen al autoboxing de Java el cual convierte un tipo primitivo a un objeto que lo encapsula, como por ejemplo un int a un Integer.


El poder de las conversiones implícitas de Scala no esta en duda.

No voy a olvidar cuando vi algo como el ejemplo anterior: primero pensé que Scala estaba imitando la sintaxis de Visual Basic.  No me gusto mucho la idea.  Luego descubrí que "to" en "0 to 10" es un método común y corriente pero no esta en la clase Scala.Int sino que en  la clase RichInt.  Este método retorna un rango sobre el cual itera la sintaxis "for".  Para que funcione, tiene que haber una conversión automática desde el Scala.Int 0 a RichInt.  Para eso, existen las conversiones implícitas 

Como en el autoboxing de Java, el peligro es que algo que se ve de un cierto tipo se comporta como otro al momento de ejecutar.

Ademas, Scala permite al programador definir sus propias conversiones implícitas.y obliga importar la definición del implicit para usarla.  Eso rompe muchas veces el "Google-copy-paste" porque es frecuente encontrar micro-ejemplos sin los import necesarios y copiar un código que no compila por una razón misteriosa.  Este ultimo problema se ha mitigado gracias a mejores mensajes del compilador (aunque a veces muy largos) y el mejor soporte en IDE.

Finalmente, para demostrar el super poder de las conversiones implícitas  es bueno mirar su uso en internal DSL como camel Scala DSL y compararlo con el camel Java DSL


Conclusión

En los tres casos mencionados anteriormente, el poder de Scala implica una curva de aprendizaje.  En caso de "operator overloading" se recupera inmediatamente y rápidamente con las conversiones implícitas, (basta usar una API diseñada como internal DSL),  En caso de la programación genérica me demando implementar un algoritmo no trivial para darme cuenta que Scala estaba en lo correcto.  Y fuera de estos 3 ejemplos, no he encontrado todavía alguna característica del lenguaje cuya curva de aprendizaje sea mayor al poder que otorga.

lunes, 15 de octubre de 2012

Lo que amo de Scala: las colecciones

Primera entrada en la serie de lo que me gusta de Scala.  Ojo que no pretendo escribir un tutorial, solamente explicar porque me gusta y que me permite hacer.  Ojo 2: no se cuales otros lenguajes permiten implementar lo mismo, solamente puedo comparar con Pascal, Fortran, C, C++, PL-SQL, Shell script, Javascript y Java.

El código fuente de las colecciones de Scala tiene la reputación de ser complejo.  Se supone que usan teorías algébricas esotéricas como Category Theory que no son para el común de los mortales.  Algún día me daré el tiempo de investigar más sobre el tema, pero mientras tanto, se que se puede hacer maravillas con ellas en forma simple.

Básicamente, son como tener el poder de SQL sin tener que ir y volver a la base de datos.  Los siguientes extractos comparan código Scala con SQL.


Ahora no dudo en llevar datos en memoria y procesarlos fuera de la BD.  Obtengo mejoras en rendimiento y mejoras en mantenibilidad usando un solo lenguaje y eliminando el código de ida a vuelta a la BD

Scala vs otros "next java"

Kotlin, Ceylon e Xtend son 3 lenguajes que están en la misma liga que Scala
  • basados en la JVM,
  • adoptan algo de programación funcional sin renunciar a la OOP,
  • tratan de evitar algunos errores de Java,
  • mantienen la programación genérica y el static typing.
El hecho que estos lenguajes existen demuestran que hay una necesidad.  Java se estanco y, si se destraba el avance de algunas JSR como el project lambda para Java 8, es probable que la sintaxis de Java termine muy compleja.

Una guerra de lenguajes siempre es entretenida, así que empece a mirarlos.  Me fue difícil intuir como serán cada lenguaje sin ver ejemplos avanzados y todos los micro ejemplos se ven bien.  Así que empece a evaluar primero los aspectos no técnicos, poniéndoles notas y publicando mis resultados en G+ y en ingles.  El resumen es:
El resumen del resumen es que estos lenguajes llegan muy tarde y tendrán que superar bastante a Scala para encontrarse un nicho.  Pueden superar a Scala de varias formas, siendo más simples y abordables por un programador Java promedio, con mejor soporte en IDE, creando una comunidad muy entusiasta, etc.

Al final, decidí no dedicar tiempo tratando de implementar una aplicación real con cada uno de ellos. Lo que si tengo pendiente, es listar lo que me gusta de Scala y lo que necesito que otros lenguajes igualen o superen.   Este tema me da para varias entradas en mi blog resucitado.

sábado, 13 de octubre de 2012

De la TI empresa a la TI para el consumidor

Ahora que re-anime este blog, aprovecho leer mis antiguos post y no puedo dejar de notar como ha cambiado mi visión del mercado de las TI.

Hace 2-3 años atrás, le daba mucha importancia al rol de los proveedores de la TI empresarial como Oracle, Sun, IBM, Adobe, Microsoft, jBoss y SpringSource.  Trataba de analizar el futuro de sus productos como ESB, bases de datos y servidores de aplicación.  Me gustaba predecir como evolucionaran sus tecnologías como JavaFx, Silverlight, Flash, XML, BPEL, SQL.

Ahora, estoy completamente convencido que si se quiere mirar el futuro de la TI, no hay que mirar a estos proveedores y sus tecnologías.  Básicamente porque cambio el negocio y se quedaron en el pasado.

Hace 30 años, la TI era para empresas y los usuarios de los sistemas eran los empleados de estas empresas.  Con la web, despego la TI para el consumidor final y nacieron empresas como Google, Amazon, eBay, Twitter y Facebook.  Con la llegada del móvil, la TI para consumidor final ahora supera la "vieja" TI para empresas.

Un ejemplo claro es Apple que casi muere en los 90 y ahora es la más valiosa en la bolsa.  La razón de ser de Apple nunca fue la TI empresarial y no pudo competir con IBM y Microsoft en los 90. Ahora, Apple esta en su zenit con sus iPhone e iPad.

Entonces, ahora miro que hace Twitter, Facebook, Google, Amazon y Apple.  A pesar que algunos no son proveedores de TI, son los que marcan el pulso de este mercado.



No, no comprare un tablet

Seamos realistas, vivo en Chile con un hijo en la universidad y otro por entrar pronto.  Simplemente, no tengo ingresos para renovar cada 2 años el smartphone, un tablet y un PC.  Hay que priorizar.

Yo necesito un PC para el trabajo. Cuando digo PC me refiero a un dispositivo con una pantalla grande, un teclado y un ratón.  No necesariamente tiene que usar un Desktop OS tipo Windows o KDE/Gnome.

Ya estoy adicto al smartphone.  Me resistí durante un tiempo comprar uno, porque pensaba que lo iba a perder o destruir como algunos de mis celulares anteriores.  No fue así y mi pequeño Android es realmente una buena forma de matar tiempo ocioso.  Pronto caduca el contrato con mi Telco y me comprare un smartphone top.

Tengo claro a que sirve un tablet.  Muchas veces, es una lata sentarse en un escritorio y esperar que se encienda el PC para revisar pocas paginas web y es incomodo llevar el notebook en todas partes.  Las pantallas de los smartphone son muy chicas para ver vídeos cómodamente o incluso para leer paginas web no optimizadas para este tamaño.  Claramente, es útil tener algo intermedio para el consumo rápido y en todas partes de contenidos.  Los tablet llenan esta necesidad.

Si no voy a comprar un tablet, necesito que el smartphone o el PC suplan algunos casos de uso.   Por el momento, no me sirven los PC/tablet híbridos ya que tienen pantallas muy enanas. Supongo que los proveedores de Windows 8 van a ser muy creativos, su sobrevivencia depende de eso, y que pronto habrán híbridos más grandes.

Me queda entonces ver como usar mi próximo smartphone como tablet.  Me parece que un smartphone no puede superar 5 pulgadas para que sea practico llevarlo en un bolsillo. Entonces, necesito que el smartphone sea capaz de usar monitores externos.  Miracast y algunos proveedores como Samsung o LG proveen esta capacidad.  Claro, no podre usar esta solución en el metro o en la playa, pero no son lugares donde usaría un tablet de todas formas.

Finalmente, la siguiente etapa sería usar el smartphone como PC también.  Hay equipos como el Motorola Atrix o el Nexphone que van en esta dirección.  Falta poco para que sean utilizables.




De vuelta al blog

Después de un paseo por las redes sociales, me parece que el blog sigue el mejor método para divagar sobre temas tecnológicos.

El año pasado, cerré mi cuenta de facebook porque esta compañía tiene practicas comerciales muy desagradables.  De todas formas, facebook nunca fue un buen lugar para postear temas de nerd.

Acabo de cerrar mi cuenta twitter donde seguía varios gurus del mundo de las TI, en particular los de la comunidad Scala.  Yo era seco para el re-tweet, pero el formato de 140 caracteres siempre me bloqueo para publicar algo inteligente.  Admiro los que son capaz de decir mucho en tan poco espacio.  Finalmente, Twitter es demasiado serio y, sobre todo, es bastante malo para armar conversaciones.

Luego de usar Google Buzz, me quedo con G+, básicamente como un reemplazo de un RSS Reader ya que varias revistas publican sus entradas.  Y, solamente con el "what's hot", justifico quedarme en G+ por lo menos por un año más.

En fin, aquí estoy de vuelta, bloggeando en español después de intentar masacrar el ingles con mis entradas sobre Scala vs Ceylan vs Kotlin en G+.