Exoditus en Python

En varios posts anteriores creo haber mencionado (a veces al pasar, y a veces no tanto), al generador de código que usamos en el laburo en los desarrollos .NET, a quien su autor, Darío, denominó Exodus. No, el nombre no es arbitrario... pero en todo caso le tocará a Darío algún día escribir sobre ello en su propio blog... :)

Sin entrar en detalles (je! a ver si avivamos giles y perdemos la ventaja competitiva que nos da!), digamos que es una herramienta mediante la cual se define el "dominio" de una aplicación, generalmente haciendo algo de introspección sobre el modelo de datos (o sea, sobre la base de datos a usar), y genera automáticamente un montón de código boilerplate: el mapeo entre el ORM y la base de datos, "finders" para recuperar datos, consultas y ABMs estándares (al estilo de las que genera por ejemplo Django), las fachadas y business delegates (en el laburo, a pesar de usar .NET, usamos muchos de los patrones arquitectónicos de J2EE) y un sinfín de cosas más.

La herramienta es fantástica, e imprescindible: Creo que sería imposible desarrollar sistemas del tamaño de los que estamos generando, si tuviéramos que escribir todo eso a mano, cada vez (y si cada vez que tocáramos el modelo de datos, tuviéramos que ir manualmente a reajustar TODOS los lugares en los que pega). A pesar de todo, desde el comienzo que hay algo que me "molesta" (muy entre comillas, porque en definitiva, FUNCIONA, y bien), y es que internamente, el core de Exodus no deja de ser un template engine, que toma una descripción del dominio de la aplicación, y una serie de plantillas, y escupe código (o más académicamente hablando, "text artifacts" (¿ahí les gusta más?)). Y el problema es que usa un template engine custom, y peor, ese template engine usa un lenguaje scripting custom, que tiene varias limitaciones (se han tenido que hacer cosas "raras" en las plantillas, y en el código generado, por limitaciones en los tipos de datos que maneja este lenguaje, por ejemplo). Y sobre todo, es LENTO. Esto hasta ahora no era un problema, pero en el proyecto en el que estoy trabajando desde hace varios meses, que es MUY MUY grande, regenerar código lleva más de 10 minutos.

Ninguna de las dos cosas constituyen una limitación "insalvable". De nuevo, funciona, funciona ok, el código no se regenera a cada rato, no todos los proyectos son tan grandes, y cada vez que nos topamos con alguna limitación a nivel de templates... Darío encontró un workarround.

Pero la cuestión es que a mí el tema me seguía dando vueltas en la cabeza... y siempre tenía en la cabeza una vocesita diciendo "que bien que vendría Python y alguno de los tantos templates engines que tiene acá..."  Encima, Exodus desde hace un tiempo atrás tiene embebida una consola de IronPython, que sirve para levantar "on-the-fly" el modelo antes de generar código, y jugar un poquito. Todavía no le hemos dado mucho vuelo... pero es cool :)

Hace unos meses atrás, mejorando el esquema de remoting estándar que usan nuestras aplicaciones, se presentó un problema "recursivo": Ciertos Business Delegates dependían del código escrito por nosotros (no del auto-generado), con lo cual en principio no se podían generar con Exodus... y ahí nació "Exoditus", que no es más que un hook de post-compilación de parte del proyecto que levanta el core de Exodus, levanta el assembly recién compilado con la lógica de negocios, mediante reflection extrae algunas propiedades, genera código adicional, y sigue compilando. Nice.

Este fin de semana, decidí poner manos a la obra, y ver si podía, como experimento y prueba de concepto, re-escribir Exoditus en IronPython. Elegí Exoditus porque es lo más fácil de reemplazar. Hoy por hoy, aunque la idea funcione, reescribir todos los templates y modificar Exodus para que "dialogue" con este esquema ya no es tan trivial (aunque tampoco lo veo como algo muy complejo). En cambio Exoditus bien puede no depender para nada de Exodus; es un paso intermedio en la compilación. Nada más. Y solo UN template.

Bueno, el experimento funcionó. La parte más compleja, fue encontrar un template engine que funcionara BIEN en IronPyhon. Los template engines que hay suelen (todos) hacer uso de mucha magia negra y de features de CPython que aún no funcionan en IronPython. Luego de algunas pruebas, y con la ayuda de Google, el candidato elegido fue Cheetah. Buenísimo. Quizás no sea el ciudadano más ilustre por estos días, con todo el buzz alrededor de Django, TurboGears y cía., y los template engines orientados al desarrollo web. Pero es un producto maduro, estable, en producción, rápido... y MUY poderoso.

Así que prueba superada: pyExoditus se compone de +/-90 líneas de código, de los cuales el 70% se va en dos métodos que realizan introspección sobre un assembly que recibe como parámetro, para extraer nombres de clases y métodos que cumplen ciertos patrones, un template, Cheetah, y unos 32 módulos de la stdlib de Python (me tomé el laburo de identificar uno a uno cuales eran, para poder armar un "paquete" autocontenido con todo lo necesario que no requiera tener CPython instalado para andar). La buena noticia: No solo anda, sino que anda sensiblemente más rápido :)

No se si terminará metido o no en nuestro estándar de desarrollo... pero en cualquier caso, fue divertido y productivo. Y si termina metido, quizás sea el primer paso para apuntar a otro objetivo: Darío está en estos momentos escribiendo la versión 2.0 de Exodus, con muchas mejoras y cambios estructurales... quizás... solo quizás, Exodus 2.0 podría usar como template engine a Cheetah, y como scripting language a Python...

Oído al pasar...

Hoy un compañero de trabajo (a quien no pienso deschabar...) me hizo el siguiente comentario por GTalk:

Miré un texto en un papel, hice foco en un textbox, y apreté CTRL-V esperando que pegue... estoy limadísimo

Sí. Muy. Definitivamente.

Aprendiendo erlang

Hace un par de semanas atrás, empecé a leer un poco documentación y tutorials de erlang. Instalé en mi laptop la implementación open source, y estuve practicando.

Nada fancy, nada útil per-se. Estoy apenas escarbando la superficie, para ver algo concreto de programación funcional (algo que tenía pendiente hace rato). Y elegí erlang porque dentro de los otros lenguajes funcionales (o pseudo-funcionales) que miré encontré que tiene una sintaxis clara. Y tiene algunos pythonismos:

  • tiene un intérprete interactivo (tener un intérprete interactivo es LO MAS!)
  • tipado dinámico
  • evaluación estricta
  • asignación única (esto para mí era importante, porque realmente quiero probar como es programar SIN depender de cambios de estado para expresar la lógica (creo que es el click-mental más costoso para pasar a hacer algo funcional...))

Por otro lado, si bien es relativamente "viejo" (si se puede decir viejo sobre un lenguaje de programación...), últimamente viene ganando terreno. Quizás porque algunas singularidades son más útiles o fáciles de explotar ahora. Y esas singularidades de erlang también ayudaron a que terminara siendo "el elegido" para esta prueba: El lenguaje incorpora en sí mismo todo lo necesario para programación concurrente, ejecución en paralelo, ejecución distribuida, pasaje de mensajes, rule matching, de una manera sumamente simple y completamente integrada al core del lenguaje.

Hasta ahora me viene resultando un experimento interesante, sobretodo porque acostumbrado a lenguajes procedurales y orientados a objetos, es un desafío a veces expresar las cosas más sencillas cuando el paradigma es funcional.

Con todo esto ni quiero decir que me vaya a dedicar a desarrollar en erlang ni mucho menos... pasa que la "pata" de paradigma funcional me está faltando, y me parece que la mejor forma de incorporarla es jugar un rato con un lenguaje 100% funcional. Después, es más fácil volver a otros lenguajes y aplicar esas "lecciones aprendidas" a la resolución de los problemas, aún en casos en que el lenguaje en sí no soporte el paradigma. Se trata solamente de poder incorporar otro enfoque, otro punto de vista, que a veces es más eficiente / útil.

Y calculo que una vez que tenga más en la cabeza estas cosas a partir de elrang, va a ser más fácil echarle una mirada a otras opciones (como por ejemplo, Haskell) de las que huí despavorido por su horripilante sintaxis (ok, no le puse mucho esfuerzo de mi parte en darle una oportunidad, pero... ¿para qué el masoquismo, teniendo erlang?)

Algunos links que me resultaron útiles al principio:

ISO votó en contra del reconocimiento de Open XML como estándar internacional

A Microsoft se le viene complicando desde hace rato, sobretodo en Europa, el tema de sus formatos "opacos" de datos para documentos.

Hace varios años atrás, con el respaldo de Oasis, se definió un estándar internacional: OpenDocument.

Mientras tanto, Microsoft diseñó un nuevo formato, basado en XML, que se llama "Open XML". Sí, es XML. Sí, es texto. Sí, el nombre tiene el substring "open", pero muchas personas que analizaron a fondo la especificación notaron que:

  • Es INSANAMENTE grande (más de 6000 páginas (no, no le pifié a un cero));
  • Deja un montón de puertas abiertas para que, por más que sea un XML, se siga dependiendo de herramientas propietarias de Microsoft para trabajar con los archivos;

Microsoft alega que OpenDocument es insuficiente y tiene falencias... pero bueno, en lugar de trabajar para mejorar ese estándar, siguió impulsando OpenXML. Pero resulta que entonces apareció otro problema: OpenDocument está considerado un estándar internacional, y ha sido recomendado por más de un organismo gubernamental (de nuevo, en Europa, donde el marketing es un poquito menos descarnado...). Y OpenXML no. Así que Microsoft decidió pedirle a ISO que considere OpenXML como un estándar...

... pero siguiendo lo que se denomina "fast-track", que básicamente significa, no miremos en detalle la especificación (recuerden: más de 6000 páginas), primero definamos que es un estándar, y DESPUES, veamos que hay que arreglar. Mágicamente, varios países y organismos miembros de ISO que NO tenían poder de voto en esta decisión, solicitaron a último momento el "upgrade" de su status dentro de ISO para poder votar (¿lobby?). Así y todo, ganó la cordura. Por ahora, OpenXML no es un estándar.

Más info sobre la votación, en Ars Technica.

Alguien podría decir, y con razón, "y quien sos vos para opinar, ¿acaso leíste las especificaciones?" No, claro que no. Ni siquiera la de OpenDocument, que es mucho más chica. Pero lo que yo digo es: NO necesitamos DOS estándares para documentos. Necesitamos UNO, y que sea bueno y completo. Entonces, si OpenDocument no sirve del todo, MEJOREMOS eso. Pero no hagamos otro.

Y por sobretodas las cosas: No hagamos otro que es CERRADO bajo la mentira de que es abierto, solo porque es un XML, y una empresa muy poderosa dice que es abierto.

SQLAlchemy: Un ORM que sabe de álgebra relacional

Hace algunas semanas que estoy leyendo la doc y haciendo algunos experimentos "caseros" (descolgados, sin ningún propósito concreto de momento) con SQLAlchemy.

SQLAlchemy es, al mismo tiempo, un set de herramientas de acceso a SQL y un ORM. Y resalto el "y". Es la primera herramienta de estas características que veo que implementa este concepto de separar claramente, e incluso como cosas usables de manera independiente, las dos caras de la moneda: El "lidiar" con SQL desde una aplicación (sobretodo para consultas), y el mapear un modelo de objetos a una base de datos.

Traducción libre de la página principal del sitio:

Las bases de datos SQL se alejan más del comportamiento de una colección de objetos a medida que la performance y el tamaño de la base de datos se vuelve más importante; las colecciones de objetos se alejan más de conceptos como tablas y filas conforme la abstracción se vuelve más importante. SQLAlchemy intenta acomodar simultáneamente estos principios.

SQLAlchemy no ve a las bases de datos sólo como una colección de tablas; las ve como motores de álgebra relacional. Su ORM permite mapear clases contra una base de datos de varias formas distintas. Las sentencias SQL no solamente consultan tablas—es posible realizar consultas de joins, subqueries y uniones. Así, las relaciones de la base de datos y el modelo de objetos se desacoplan desde el principio, permitiendo que los dos conceptos se exploten a su máximo potencial.

Realmente esto no es marketing, cuando uno empieza a usar la herramienta y analizar los ejemplos en la documentación, se ve claramente que esta filosofía se aplica... y da frutos. De todos los ORM existentes para Python, creo que SQLAlchemy es el único considerado "de verdad", es decir, que podría usarse en escenarios más complejos de la simple aplicación web con 3 o 4 ABMs que normalmente se desarrollan con Django o TurboGears. Es a su vez uno de los más nuevos, pero ha tomado la comunidad "por asalto", y me atrevo a especular que es por lejos el que más rápidamente ha avanzado (y continúa avanzando...)

SQLAlchemy escala hacia arriba... y hacia abajo. Por ejemplo, está creciendo bastante también un proyecto, Elixir, que implementa una capa "declarativa" sobre SQLAlchemy que resuelve de una manera sencilla e intuitiva (muy al estilo del Active Record de Ruby on Rails) los casos más comunes.

Por último (y esto no es exclusivo de SQLAlchemy, sino extensivo a todos los otros ORMs para Python): Cuánto más "lindo" es un ORM con un lenguaje dinámico. Cuando hay que acercar los mundos de SQL y OOP en Java o C#, se nota mucho el overhead de jerarquías de clases y abstracciones e interfaces que se "apilan" para lograr algo extensible y robusto... y que adhiera a las restricciones del tipado estático. Con Python (o Ruby), se puede crear el puente, igualmente extensible y robusto, de una manera mucho más directa. Gracias a Darío en el laburo tenemos un excelente generador de código que nos resuelve automágicamente toda la parafernalia de código extra... si no lo tuviéramos, calculo que estaría pidiendo a gritos que laburemos con otra cosa... jeje.

VirtualBox 1.5 - Seamless windows

¿Notan una mezcla rara en este screenshot?

VirtualBox 1.5 Seamless windows

:)

Es un nuevo chiche de la versión 1.5 de VirtualBox. La llaman "Seamless windows", y lo que hace VB en este modo es ocultar el escritorio del sistema operativo guest (Windows XP Home en este caso), para lograr una mayor integración con el host.

Por ahora, únicamente funciona para Windows como "guest", y no al revés, y requiere que sí o sí el sistema operativo virtualizado tenga instaladas las "guest additions".

Ya había visto (aunque no probado) experimentos similares usando QEMU, y también pruebas sobre VirtualBox, pero en ambos casos usando un feature de Windows Terminal 6 (o superior) que permite que el cliente en lugar de recibir el escritorio completo de Windows pueda recibir solamente la ventana activa. Entonces, el truco era correr Windows virtualizado en background, y luego abrir alguna aplicación mediante el cliente Terminal Server de Linux. Pero esto tiene varios drawbacks:

  • Es bastante complejo de configurar / administrar
  • Funciona únicamente para Windows, y solamente versiones de windows que tengan implementado el RDP (Remote Desktop Protocol), lo cual te limita a versiones Professional o Enterprise (no Home) de Windows XP o superior.
  • Por una limitación de RDP, solo se puede trabajar con una aplicación simultánea (aunque creo que algunas versiones de Windows, o con configuraciones especiales, esta limitación podía salvarse).

El approach que eligió VirtualBox me gusta más. Si bien por ahora funciona solo con Windows, funciona en CUALQUIER Windows en el que sean instalables las Guest Additions. No depende de ninguna configuración de networking entre host y guest. Puedo abrir todas las ventanas y aplicaciones que quiera. Y calculo que a futuro implementarán esto también en las guest additions de Linux y MacOS. Mi impresión personal es que arrancaron con Windows porque hay más usuarios que corren Windows sobre Linux que al revés.

Y lo más lindo: Funciona out of the box. No tuve que hacer nada más que actualizar VirtualBox, arrancar la virtual machine que tiene instalado Windows, actualizar las Guest Additions también a 1.5... y listo. Con CTRL-L conmuto entre el modo seamless y el normal.

Dolores O'Riordan en Buenos Aires

Nunca fuí fan, ni siquiera un mero "seguidor" de The Cranberries, pero siempre me gustó su música. Así que cuando me enteré que se presentaba Dolores O'Riordan en el Gran Rex, decidí sacar una entrada, e ir. Esto forma parte de un "plan" de tratar de disfrutar de la música en vivo cada vez que pueda, siempre que el tiempo y el presupuesto me lo permitan. Porque más de una vez me ha pasado dejar de lado un recital, porque no es de un artista al cual sigo, y después arrepentirme. La música en vivo siempre se disfruta más que un disco; un show siempre tiene un touch personal. Y no hace falta ser fanático del artista XYZ para ir a verlo, o para apreciar su obra.

Así que ahí estuvimos. Me encantó!. Dolores abrió a full con Zombie (de The Cranberries), y no perdió oportunidad de mechar los clásicos de su ex-banda con sus nuevos temas solistas del album "Are You Listening?", que era en sí el motivo del show. Por cierto, ya había escuchado su nuevo trabajo, y me gustó mucho: En muchos temas suena a The Cranberries, en muchos explora otras facetas. En ese sentido, me sorprendió que el set list incluyera temas que en principio no me imaginé que haría en vivo, porque en el disco suenan  muy "de estudio". Ejemplo, "The black widow" (a propósito... ese tema ¿no es digno de la banda de sonido de una película de Tim Burton?).

Nunca había visto a Dolores en vivo. Tiene toda la onda en el escenario. E hizo un gran esfuerzo por satisfacer a sus die-hard-fans, que estaban todos en las primeras filas, completamente extasiados :) El show duró casi dos horas, en las que pudimos escuchar muchos de los temas de su primer disco solista, y como ya dije, varios hits de The Cranberries.

Una única crítica: El Gran Rex le quedó chico al sonido de la banda, especialmente hacia el final, cuando le pusieron más energía. Para mi gusto, para un lugar cerrado, saturaba un poco, y le restaba matices. Pero hay que tener en cuenta que digo esto desde la pseudo-subjetividad de estar ubicado en el super pullman, que no es la ubicación ideal desde el punto de vista acústico, menos en un teatro "normalito" como el Gran Rex.

El camino del oro: de La Carolina a Nogolí

Este finde largo anduve de travesía con Hielo Azul por San Luis. La propuesta consistía en unir a pie La Carolina con Nogolí, pasando por varios puestos serranos (algunos abandonados), y transitando caminos alguna vez recorridos en busca de oro.

Como siempre lo pasé genial, se armó un grupo de gente muy lindo, con mucha buena onda. Tuvimos como bonus-track una nevada el primer día, que le dió un toque interesante... aunque también, frío... mucho! Pero yo personalmente disfruté el estar caminando en medio de una nevadita, y me despaché sacando unas cuantas fotos en las inmediaciones del primer campamento de un paisaje que para mi fue, gracias al toque que le da la nieve, inusual.

IMGP2438.JPG IMGP2447.JPG IMGP2442.JPG

El segundo día de a poquito fue asomando el sol, que nos acompañó todo el domingo, y también el lunes. En general, todas fueron jornadas de caminatas cortas, de entre 3 y 5 hs., sin demasiados desniveles, así que ibamos tranquilos. La nota de color del segundo día la pusieron los caballos del paisa que nos hacía el porteo del equipo de campamento y la comida: Eran animales grandes, que no estaban acostumbrados a caminar por esas sierras, y se empacaron más de una vez. Es la primera vez que me pasó llegar al lugar de acampe antes que los caballos... jeje.

IMGP2480.JPG IMGP2488.JPG

El lunes, arrancamos más o menos tempranito, y después de descender hasta el río La Quebrada, y posteriormente, al río Molles, llegamos hasta un puesto en Nogolí en el que un vehículo nos trasladó hasta La Serrana, un complejo turístico que un poco por la época, y otro poco porque están refaccionando, estaba abierto solo para nosotros. Ahí disfrutamos de un excelente asado, una buena ducha, y un par de horitas de modorra hasta que llegó el minibus que nos trasladó a San Luis para emprender el regreso.

IMGP2526.JPG IMGP2529.JPG IMGP2538.JPG IMGP2552.JPG

Pensé que no había sacado tantas fotos, en parte porque las pilas recargables me jugaron (ooootra vez...!) una mala pasada, pero saqué casi 150, de las cuales quedaron 130. Gracias Eze por el préstamo de pilas del último día. Me salvó. Algunas fotos soleadas están medio verdosas, porque estuve "jugando" a setear el balance de blancos manualmente... y en un par de oportunidades le pifié. Probablemente en el transcurso de los días retoque esas fotos y las vuelva a subir arregladas. Moraleja: A pesar de que muchos fotógrafos pro o semi-pro recomiendan NO usar el balance de blancos en modo "auto" en las cámaras point-and-shot... mí cámara tiene un buen balance automático (al menos al aire libre), porque las fotos no salieron mejores que otras veces, y todo el tiempo tuve que estar pendiente de como seteaba el balance... y varias veces me equivoqué. Así que no voy a volver a experimentar con esto, salvo para situaciones en que la luz realmente sea "dudosa".

Podés ver todas las fotos de este viaje siguiendo este enlace.

Por último: No puede ser que haciendo estas salidas con la frecuencia que las hago, siga padeciendo las falencias de mi bolsa de dormir sintética con relleno de fibra Hollow, encima de 1ra (o 2da generación), comprada en el año '98 (o sea, RECONTRA amortizada, encima...!). Tengo que comprarme una bolsa con relleno de plumas, MUCHO más confortable, liviana y "comprimible". Si vuelvo a hacer una travesía en la que haya riesgo de temperaturas nocturnas inferiores a 0 grados sin invertir antes en una bolsa mejor, soy un pelotudo. He dicho.

Los Simpson

Hoy (a estas horas, debería decir ayer) fuimos con Diego, Eze y Luis a ver Los Simpson. Por colgados, y no comprar las entradas antes por internet, nos encontramos con que la función de las 20.10 estaba agotada :( La siguiente era a las 22.40. Diego, que es el que vive más lejos de Capital no tuvo problema... así que para las 22.40 sacamos.

Eso se tradujo en dar un laaaaargo paseo por Abasto (el shopping, y el barrio), compartir una pizza con unas cervezas en una pizzería en la que nos arrancaron la cabeza (bueno, no tanto, pero fue caro), luego un café con algo dulce, y finalmente, la película.

Buenísima. Para mí, no deja de ser en el fondo un capítulo largo de Los Simpson (aunque en varias críticas que leí se ha recalcado que no), pero es uno bueno. Y hacen buen uso de los recursos del cine: formato wide, mejor sonido, etc. Y supieron armar un guión que se ajusta perfectamente a los 87 minutos de duración. Si te gustan Los Simpson, no podés dejar de verla. Y creo que vale la pena verla en cine, porque si no, le quitás ese condimento extra de la pantalla grande y demás, y lo acercás más a un capítulo cualquiera que podés ver en Fox en cualquier momento (a propósito: excelente ironía de Homero al respecto al comienzo de la película...!)

TIP: Si van a verla, NO se levanten de la butaca hasta el final de los títulos!