Git

Cuando Percy le envía a Ron la carta donde le dice que se aleje de Harry, en Harry Potter y la Orden del Fénix, Ron rompe la carta y dice que Percy es el “world’s biggest git”. Git (como lo define Wiktionary) es

  1. (British slang) A contemptible person.

    Elissa is a right git.

  2. (British slang) A stupid or unpleasant person.

    Jacko is a git.

Bueno. De eso no voy a hablar ahora.

De lo que voy a hablar es de Git, el programa iniciado por Linus Torvalds para reemplazar a BitKeeper como sistema de control de versiones.

Yo no tengo mucha experiencia con sistemas de control de versiones; he usado CVS y tengo todos mis documentos en Subversion desde hace ya algunos años. Fuera de eso, sólo de vez en cuando he utilizado otros sistemas como Bazaar para bajar algún proyecto que me interesara cuando lo estaban desarrollando.

Hay distintos desarrolladores que defienden uno u otro sistema de control de versiones; algunos al punto del fanatismo. Todos los repositorios de GNOME se cambiaron de CVS a Subversion en estos días (después de un intento fallido hace seis meses), y eso desató toda una discusión por parte de la gente que no le gusta Subversion.

Como sea, yo no me he metido en eso. Subversion me funciona a mí para mantener mis documentos bajo control de versiones, pero no me he puesto a ver si hay algo mejor o más rápido o que proteja a los gatitos indefensos.

Pero para mi programa de geometría necesito un canvas, y lo único que se ve que será usable en un tiempo razonable (para GNOME, obviamente) es el Criawips/CriaCanvas, o CCC.

Sven Herzberg es el lead developer del proyecto (creo que es el único de hecho), y cuando descubrí su canvas la única página que había disponible daba como repositorio uno en Subversion. De ahí bajé el código y comencé a usarlo, hasta que me di cuenta que no tenía forma de manipular el orden en que se dibujan los elementos en el canvas; eso es malo, porque en un programa como el que yo quiero hacer los puntos deben estar “hasta arriba” (top layer) siempre.

Así que escribí una implementación rápida, y se la mandé por correo a Sven, preguntándole si se podría incluir. Me respondió diciéndome que el repositorio en Subversion estaba deprecado (el nuevo está en Git), y dándome unos consejos para mejorar la implementación que había hecho.

Así que bajé la versión que había en el repositorio en Git, reescribí mi implementación y se la mandé a Sven. Él la incluyó en el repositorio, y me pidió que escribiera un demo de lo que había hecho para un programa incluido con CCC que muestra pequeños ejemplos de lo que ofrece la biblioteca. Después de escribir mi prototipo hice el demo, que de hecho me hizo descubrir dos bugs en CCC; uno en lo que yo había contribuido, y otro en otra parte del sistema.

Total que ya le he enviado como siete parches a Sven, y estoy contribuyendo regularmente con el proyecto; me conviene, porque lo necesito para mi programa.

Pero el punto es que he tenido que usar Git bastante, y debo admitir que está bastante chido. Sobre todo porque yo suelo desarrollar en mi desktop y en mi laptop; entonces hago un pull del repositorio de Sven en mi desktop, y después hago un pull de mi desktop a mi laptop. Si se desincronizan puedo hacer (de forma bastante sencilla) un merge entre mi desktop y mi laptop; y además tengo un branch para mis propios cambios (que también puedo sincronizar entre mi laptop y desktop), con lo cual puedo generar parches fáciles de enviar para Sven.

En pocas palabras; Git está poca madre para desarrollo distribuido. Después de leer durante años cómo Linus trabaja para mantener el kernel, puedo entender perfectamente por qué desarrolló así el programa. Lo chistoso es que funcione igual de bien para el kernel (cientos de megas de código fuente, literalmente miles de programadores), y para un bibliotequita como CCC (dos megas de código fuente, un puñado de programadores).

Ahora: no sé si Git sea una solución “mejor” que Subversion. En particular, es bastante complejo (más que Subversion sin duda), consecuencia obvia de que es (creo) más poderoso. También come disco duro como si fuera gratis: de los dos megas que usa CCC, mi copia del repositorio genera casi doce. Y no es terriblemente intuitivo, especialmente si uno viene de sistemas como CVS.

Pero está muy, muy bonito. Sí tiene cosas bastante interesantes.

No voy a pasar mis documentos de Subversion a Git (Subversion es perfecto para ese caso de uso); pero en parte creo que he colaborado de forma tan sencilla con Sven porque Git lo facilita. Eso, y que necesito a CCC para mi programa.

Primer prototipo del programa de geometría

Después de estudiar un poco el sistema de tipos de GObject, escribir algo de código, bajar la versión de desarrollo de CCC, corregirle unos bugs que tenía, agregarle funciones que necesitaba, y pelearme con vnc2swf, por fin quedó mi primer prototipo (recalco, prototipo) de mi programa de geometría.

La parte en que me peleé con vnc2swf fue porque un screenshot no refleja realmente nada del prototipo, así que hice un screencast en Flash. Lamento hacerlo en algo que no es libre, pero Istanbul sencillamente me falló (además de que estoy seguro que la mayor parte de mis lectores no tiene los codecs de Ogg Theora), y el otro que había usado que genera GIFs sacaba unas “animaciones” bastante chafas.

Así que les dejó la animación; es sólo un prototipo (repito): me falta mucho para tener lo que realmente busco. Pero hay progreso.

Por cierto, el código JavaScript para controlar la barra de búsqueda de la animación puede matar al Internet Explorer. O al menos eso decía el código.

Actualización: Quité la barra de búsqueda en JavaScript. Sencillamente no funcionaba.

GObject

Comencé a trabajar en mi programa de geometría, pero rápidamente me di cuenta de que, si lo hacía en C tradicional, el diseño iba a ser significativamente distinto de cómo originalmente lo había planeado.

En particular, en Java ya tenía algunas clases para manejar las construcciones geométricas; nada de cómo dibujarlas en pantalla, sólo cómo relacionarlas entre ellas. Y estaba usando herencia mucho, porque es lo correcto hacer aquí.

En C por supuesto no hay herencia, y si me seguía por un camino de estructuras con funciones me iban a alterar bastante las cosas. Nada realmente grave (se puede hacer así también), pero no como yo lo quería originalmente.

Así que me lancé el clavado de por fin aprender a usar GObject, el sistema de tipos (con herencia e interfaces) para C que usa GLib, Gtk+, y por consiguiente GNOME y amiguitos. Nunca lo había querido aprender a usar porque me daba bastante hueva, y no había tenido necesidad realmente.

Está bastante chido. Sí hay un montón de cosas que hay que hacer a pata, un montón de código repetido, y la herencia tiene sus bemoles. Por ejemplo, hay que hacer cast cuando uno quiere ver al objeto como si fuera de una clase más particular, obviamente; pero también uno tiene que hacer cast cuando se quiere ver al objeto como si fuera de una clase más general. O sea, en pocas palabras, se tiene que hacer cast siempre.

Pero funciona, y bastante chido además. Como consecuencia, mi diseño con herencia está básicamente intacto, y además está bastante divertido usar GObject (aunque sin duda es mucho más engorroso que usar un lenguaje OO de verdad). Y claro, no he aprendido bien todo; apenas estoy viendo cómo definir métodos virtuales, y no sé nada aún acerca de cómo definir y usar interfaces con GObject.

Pero está entretenido sin duda alguna.

El programa de geometría

Para mi tesis eventualmente voy a necesitar hacer dibujos de entes geométricos que son endemoniadamente engorrosos de hacer a pie en PStricks (por ejemplo, hacer la triangulación de Delaunay de un conjunto de puntos).

Por supuesto tales dibujos terminaré haciéndolos programáticamente; pero sería padre poderlos hacer con un programa interactivo; i.e., en una ventana poner los puntos como se me pegue la gana (con la posibilidad de cambiarles la posición con el ratón, por supuesto), y con un fabuloso click generar la triangulación. O el diagrama de Voronoi. O el casco convexo. O lo que se nos pegue la regalada gana. Y no sólo eso; que también tenga construcciones geométricas obvias, como círculos y polígonos.

Por supuesto, tal programa ya existe (en gran medida); se llama The Geometer’s Sketchpad; pero tiene dos grandes “fallas”: una, sólo corre en Windows (módulo Wine y cosas así). Y dos, es un programa propietario.

A mucha gente esas dos cosas les puede importar un comino; a mí no.

En Linux ha habido varios intentos de hacer un equivalente (en software libre, por supuesto); el más famoso tal vez sea DrGeo. Muchísimo menos famoso es un programa en el que Juan y Omar llevan (literalmente) años trabajando, que más o menos buscaba (o busca) resolver lo que a mí me interesa.

Me dieron ganas de entrarle al problema, y les pregunté que qué onda con su código. Omar me dijo que de plano convenía empezar de cero, porque su primera versión estaba escrita con Gtk+ 1 (y por tanto usa el original GnomeCanvas, que como todo mundo sabe consummatum est), y la segunda versión (en C#, hasta donde yo supe) estaba en pañales.

Lo que ellos querían era mucho más ambicioso a lo que yo busco: tenían contemplado usar Lua como lenguaje de extensión, por ejemplo. A mí me interesa generar código en PStricks para mi tesis; me queda muy claro que ese es mi principal objetivo, así que un lenguaje de extensión ni siquiera me pasa por la mente ahorita. No se descarta nada, pero tengo una lista de prioridades bien definida.

También quiero (o quería; más adelante ahondo) usar Java como lenguaje de programación, y usar Java GNOME (porque ni de loco lo hago en Swing). La decisión de usar Java tiene varias justificaciones: en primer lugar lo conozco mucho mejor que C# (aunque a la hora de la verdad dudo mucho que eso realmente importe). Pero más importante (para al menos), es una decisión política. Con la liberación de Java por parte de Sun, espero ver un montón de aplicaciones escritas en Java proliferando en GNOME, y quiero saltar al vagón. Además de que sinceramente creo que el lenguaje es el adecuado… como sin duda también lo sería C#.

Como sea, mis alegres intenciones se caen ante un problema enorme: no hay bindings de GNOME para Java. Mejor dicho; sí hay, pero las estables apestan (como bien lo han dicho sus propios creadores), y las nuevas (mucho más chidas) están en pañales.

Y no me refiero a que estén verdes: en gran medida no están. Básicamente están implementadas ventanas y una clase de botón. Y ni hablemos de Pango, Cairo (fundamental en lo que yo quiero), y similares.

Además, yo pensaba lanzarme a hacer un lienzo (canvas) sencillito (y lento) que hiciera lo que yo quiero, y después cambiarme al nuevo lienzo que eventualmente aparecerá en Gtk. El problema es que el nuevo lienzo ya está… en pañales también, y sin ser integrado en GNOME. Además de que es versión 0.0.1… ni soñar de bindings para Java (aunque, curiosamente, sí hay para Python y C#).

Así que tengo básicamente dos opciones: hacer el programa en C (como los hombres y mujeres de verdad de antaño), o ayudar extensivamente en los bindings, y hacerlo en Java. No quiero hacerlo en C# por razones políticas, como ya expliqué.

Si tuviera tiempo, tomaría la segunda opción; pero quiero titularme para junio. Así que me lanzaré a hacerlo en C. La idea de usar Java no está para nada descartada; sólo esta primera iteración estará escrita en C. Varios programadores dicen que un proyecto debe ser reescrito al menos una vez; usaré esta iteración para entender bien cómo quiero este programa, cometer errores (inevitables al primer intento) en el diseño, y (lo principal) sacar mi tesis. La generación de código en PStricks es ortogonal a casi todo, según yo; incluso podría exportar a un formato XML, y la generación de código PStricks hacerla de una vez en Java.

En forma paralela (y conforme vaya acostumbrándome a las distintas APIs de CCC y Cairo) ayudaré con los bindings correspondientes, para que la segunda iteración sea posible en primer lugar.

O al menos ese es plan: igual y termino sin hacer mucho por la presión de la tesis. Pero suena interesante, y ni siquiera terriblemente complicado