Vala

These days, a lot of people on GNOME planet are talking about Vala, a new programming language aimed to facilitate the development of applications and libraries for the GNOME platform. Vala is very similar to C#, but what is interesting about it, is that it’s perfectly integrated with the Glib/GObject object system. The compiler translates the Vala source code into C. It uses GObject to create classes and interfaces, and GIDL metadata for introspection. This has some advantages: there is no need for any additional runtime, Vala programs are compatible at ABI level with C programs, writing bindings for existing GNOME libraries is really easy and straightforward. Alberto Ruiz wrote about how simple was to write a binding for GtkMozEmbed. After look at howtraumatic were the Java bindings for Gtk, or how difficult has been the creation of GStreamer bindings for Mono, I think this is the best feature of Vala.

Anyway, I think Vala still lacks some key tools in order to become a real choice for GNOME developers. In the case of Mono, there is a great advantage called MonoDevelop. Days ago, version 0.15 of this awesome IDE was released. With no doubt, I think this is the best IDE for GNOME. The GUI editor, the subversion integration, the localization support and autotools integration are very appreciated features. Of course, is not perfect, It lacks a debugger and fixes for some annoying bugs, but it’s a very active project and has a great community behind it.

And talking about languages, at the end of this month, it should be released the alpha version of Python 3.0. On June, Guido van Rossum published a report about the final decisions concerning Python 3000. I am very happy with most of the changes, it was time to break some backwards compatibility. Python will be even better that what it is now.

Dolor de cabeza con Python

Un problema de usar lenguajes dinámicos es que, al no tener etapa de compilación, no es posible detectar muchos de los errores sino hasta que se lanza alguna excepción mientras el programa se ejecuta. Un problema peor es cuando por alguna razón el error no produce una excepción y el programa termina funcionando erróneamente si dar ninguna pista sobre dónde puede estar el problema.

Examinen este pedazo de código en Python:

class MyClass:
	pass

if MyClass() < 1:
	do_something()
else:
	do_something_else()

o algo más curioso todavía:

if MyClass() < float('-infinity'):
	do_something()

do_something() siempre se ejecuta.

Lo correcto debería ser que al hacer este tipo de comparaciones se lanzara una excepción. La única forma de poderlo hacer debería se cuando sea explícito que el objeto puede compararse.

Noten que este código si lanza una excepción del tipo TypeError:

a = MyClass() + 1

Según lo que me dijeron en #python, parece ser que todos los objetos en Python están habilitados para hacer comparaciones. Esta es la razón por la cual se pueden ordenar fácilmente listas con cualquier tipo de datos en ellas. Debido a que arreglar esto supondría un corte con la compatibilidad hacia atrás, sólo podremos disfrutar de una adecuado comportamiento hasta que tengamos Python 3.0. Si esto hubiera estado listo ahora mismo me habría ahorrado un gran dolor de cabeza buscando un error.

Babylon en Deskbar Applet

En windows existe un programa muy práctico llamado Babylon Translator. Cuando uno esta leyendo algo en cualquier idioma y desea traducirlo, digamos, al español, basta con seleccionar la palabra, presionar una tecla y Babylon traduce esa palabra. Hay dos cosas que le dan valor adicional, una es que el programa reconoce automáticamente el idioma de la palabra a traducir y otra es que se puede usar con cualquier palabra de cualquier programa, por ejemplo el navegador, el visor de pdfs, etc.

Para tener una funcionalidad parecida en Linux, he escrito un handler de Deskbar Applet, para que haga lo mismo. El handler usa el servicio en linea de Babylon. Al final la funcionaliad quedó casi igual, uno selecciona una palabra en cualquier programa, presiona una tecla y se habre una pestaña del navegador con la traducción. Por supuesto todo el crédito se lo lleva la gente de Deskbar Applet, ya que el handler es más bien trivial.

Si alguien quiere usar esta funcionalidad, aquí dejo el handler. Para poder usarlo simplemente hay que colocarlo en ~/.gnome2/deskbar-applet/handlers. Deskbar es un applet del panel de Gnome, la mayoría de las distros lo traen por defecto, y si no, se puede instalar fácilmente.

Por ahora lo dejo así, porque es lo que necesito, pero creo que hay muchas cosas que se podrían mejorar, como agregar soporte para traducir a otros idiomas (por ahora sólo es a español), usar diccionarios diferentes a los de Babylon o incluso no abrir el navegador sino un pequeño recuadro al estilo Babylon.

Actualización Modifiqué un poco el script para que muestre la traducción directamente en el deslizante de Deskbar. Ahora se requiere Beautiful Soup, lo estoy usando para extraer la info del html generado por Babylon, me parece que es un hack feo, pero no se me ocurrió otra manera de hacerlo. Aquí va un screenshot:

https://i0.wp.com/farm1.static.flickr.com/211/498711669_683e69052d_m.jpg

Scratch

Quedé impresionado con Scratch, el nuevo lenguaje para introducir a los niños en la programación desarrollado por el MIT Media Lab. Lo bueno es que es libre (Licencia MIT), aunque sólo está para Mac y Windows, pero dicenque ya lo están portando para el X0 del proyecto OLPC. ¡Que bacano sería ser niño y tener este juguete!

Mas rapido, pero mas lento

En estas vacaciones de diciembre, fui a visitar a mi familia en Medellín. Mi tía Patricia tenía un viejo computador portátil Toshiba Satellite Pro 440 CDT que ya no usaba y decidió regalárselo a mi Papá. Es un portátil que ya tiene sus 11 años, pero, dado que mi papá escasamente usa el PC para leer y escribir correos electrónicos, navegar por Internet y de vez en cuando escribir una carta, le sirve perfectamente. Por supuesto, como buen entusiasta de software libre, pensé que si se le instalara Linux se podría explotar más su potencial. Sin embargo, rápidamente descubrí algo que me dejó atónito y me motivó a escribir esta entrada en mi blog.

El Toshiba Satellite Pro 440 CDT tiene las siguientes características:

Procesador
Intel Pentium MMX de 166 Mhz
Memoria
32 MB
Disco Duro
2 GB.
Software
Microsoft Windows 98 y Microsoft Office 97.

Después de ver las características tan bajas del equipo, hay algo que me da muchísima tristeza. Office arranca mucho, muchísimo más rápido que el OpenOffice de mi PC. Casi cuatro veces más rápido. Aún cuando mi PC tiene 32 veces más memoria que el portátil y un procesador con 20 veces más Mhz. No estoy muy seguro de esto pero, en mi opinión, Office 97 y OpenOffice 2.0 tienen prácticamente la misma funcionalidad.

Después de jugar un rato con el portátil me di cuenta que la velocidad general de sistema, arranque del sistema operativo, apertura de archivos, etc es bastante buena, muy comparable a la de mi PC. Es cierto que hay varias cosas que no pueden ser iguales, por ejemplo, creo que el portátil explotaría antes de poder usar algo como F-Spot o editar imágenes de 8MP con GIMP. La interfaz de mi PC también es más bonita, con más resolución y efectos interesantes. En fin, creo que hay un millón de cosas que no podría ser iguales, pero en el caso de programas como OpenOffice y Office, que son prácticamente iguales, el hecho de que haya un rendimiento similar, o incluso superioridad en el computador de 11 años de edad, me parece algo desgarrador.

¿Qué es lo que pasa? Culpo a los programadores. Somos especialistas en derrochar toda cantidad de recursos que tengamos disponibles. Anteriormente los computadores venían con 32 MB de memoria y los programas tenían que funcionar con eso, y funcionaban. Eso hacía que los programadores se interesaran por mejorar el uso de los recursos. Ahora hay abundancia y se puede derrochar.

Aunque hoy en día tenemos hardware decenas de veces más rápido que hace diez años, parece ser que la calidad y rendimiento de los programas no ha crecido en la misma proporción (si es que ha crecido en algo).

Hay casos mucho más extremos aún. En el mundo del desarrollo de juegos siempre se ha mantenido una tradición de explotar al máximo las capacidades del PC. Es quizás por esto que los juegos son los únicos que parecen mostrar un verdadero avance proporcional a los adelantos en hardware. Recuerdo cuando alguna vez escribí un sencillo juego para PlayStation. El sistema contaba con la miserable cantidad de 1MB de memoria de vídeo y 2MB de memoria de sistema. A mi me parecía demasiado difícil hacer algo con tan pocos recursos, sin embargo los expertos hacían juegos espectaculares con eso. Sabían usar muy bien los recursos.

El tema no necesariamente da para comparar programas viejos con nuevos. Hoy en día también hay buenos programadores que saben utilizar adecuadamente sus recursos. Hay un perfecto ejemplo de dos programas contemporáneos que tienen funcionalidad muy similar pero difieren enormemente en el uso de recursos: uTorrentAzureus.

La descarga de uTorrent es de 170KB, la de Azureus es de 9.4 MB, eso es 57 veces más, todo esto sin contar detalles como que Azureus requiere un runtime de Java (~50MB) y que viene en un instalador comprimido (bz2) mientras que uTorrent viene en un ejecutable standalone listo para ser ejecutado. El consumo promedio de Memoria de uTorrent es de 4.6MB, mientras que el de Azureus es de 40MB. El consumo de CPU es difícil de medir, pero los desarrolladores de uTorrent dice puede correr hasta en un CPU 486, eso ni siquiera cumple los requisitos mínimos del runtime de Java, en el caso de Azureus.

Ambos programas tienen casi las mismas funcionalidades, Azureus era el más popular, sin embargo, gracias a la superioridad en rendimiento de uTorrent, este le ha ganado el puesto y su popularidad crece en forma exponencial.

Hay otra razón por la cual hay tanta diferencia en estos programas: El lenguaje de programación. Aceptémolo, por más que varios estudios aseguren que la velocidad de los programas escritos en lenguajes como Java, C#, Python, Lisp, etc. sea igual o, algunos se atreven a decir, superior que C o C++, la verdad es que en la práctica todos los programas realmente eficientes están escritos en C o C++. uTorrent está escrito en C++, Microsoft Office está escrito en C++. Azureus está escrito en Java, OpenOffice está en gran parte escrito en Java. Pero ojo, esto no quiere decir que todos los programas de C++ sean necesariamente eficientes.

Es cierto que otros lenguajes hace al programador más productivo y en general más feliz, pero creo que es difícil negar que con C y C++ se puedan obtener programas más rápidos. ¿O tal vez sea mejor decir que con un poco más de esfuerzo a la hora de programar, esfuerzo al que casi siempre nos obliga C++, se obtengan mejores programas?

C++ siempre me encantó y lo usé mucho para muchos proyectos. Hace un tiempo me enamoré de Python y ha pasado bastante tiempo desde la última vez que usé C++ ¿Será que es tiempo de abrir el baúl y volver a sacar esos conocimientos de C++? ¿O será mejor seguir con los lenguajes de alto nivel y más bien tratar de hacer esfuerzos para lograr un balance entre felicidad del programador y eficiencia del programa?

MonoHotDraw

Por estos dias estoy programando MonoHotDraw, que es el séptimo intento por hacer una librería de diagramación para MonoUML. Se llama MonoHotDraw porque está basado en el diseño de HotDraw y JHotDraw. MonoHotDraw está escrito en C# con Mono y usa varias herramientas de GnomeGtkCairoPango, etc.

Aquí hay un video de una aplicación que estoy escribiendo para una tarea de universidad que usa MonoHotDraw. Es un sencillo editor de mapas mentales. Se supone que debo entregarlo el 18 de diciembre. Tengo que apurarme y convertirlo en algo decente.

Por cierto, YouTube no me reconoció el video correctamente. Termina instantaneamente. Google Video si lo reconoció, aunque la resolución está fea. ¿Alguien sabe como convertir videos ogg theora en avi xvid o algo compatible con YouTube?

Actualización.

Olvidé decir que MonoHotDraw se encuentra disponible en el repositorio Subversion de MonoUML. La licencia de MonoHotDraw es LGPL, aunque tal vez la cambie a MIT X11. ¿Qué opinan ustedes?

Error en Mono

Hoy, mientras trabajaba en MonoCanvas, estaba husmeando en el código de Mono, cuando por casualidad me di cuenta de un error que, al parecer, nadie había notado. El operador de inequidad (!=) entre dos objetos del tipo System.Drawing.RectangleF estaba implementado de esta forma:

public static bool operator != (RectangleF r1, RectangleF r2)
{
	return (r1.X != r2.X) && (r1.Y != r2.Y) &&
        (r1.Width != r2.Width) && (r1.Height != r2.Height);
}

Obviamente, la implementación correcta debería ser:

public static bool operator != (RectangleF r1, RectangleF r2)
{
	return (r1.X != r2.X) || (r1.Y != r2.Y) ||
        (r1.Width != r2.Width) || (r1.Height != r2.Height);
}

Aproveché que estaba trabajando con la versión SVN e inmediatamente hice un parche y lo mandé.

Es increible como, pese a la gran cantidad de pruebas unitarias que tiene Mono, se haya colado un bug de este tipo. Me he dado cuenta de que en el código trivial, como el de este ejemplo, es más fácil dejar pasar bugs. Esto caso me recuerda mucho al caso del error en la búsqueda binaria en Programming Pearls.

Curiosamente el error lo encontré mientras miraba el código, pero ¿qué hubiera pasado si estuviera escribiendo una aplicación que usara ese operador? Creo que hubiera pasado un largo rato partiendome la cabeza antes de siquiera sospechar que es el operador el que tiene un bug. La moraleja de la historia es no subestimar las tareas triviales a la hora de programar.