27 de diciembre de 2011

El obstáculo de las distribuciones regionales

En general, aplaudo cuando un gobernante defiende el uso de software libre en las administraciones: al fin y al cabo, todos sabemos a qué bolsillos van los ingresos de Microsoft u Oracle, y a nadie le gusta que un país tenga un déficit tecnológico horroroso. Y cuando se utiliza software libre en las clases de informática de los institutos, mi alegría se torna en éxtasis: ya he defendido aquí que el modelo actual por el que se dan clases de informática pagando licencias de Windows y Office es, sencillamente, una estafa. La educación pública se convierte así (y permítanme la diatriba) en un centro de formación de productos de empresas privadas financiado con dinero público, y del que se benefician, sobre todo, los accionistas de multinacionales extranjeras. Ya que se beneficiarán de que los alumnos sean educados para usar sus productos, como mínimo deberían regalar todas las licencias a los institutos, pero ni eso les exigen los gobernantes.

Dejando al lado este asunto, hay algo que cada vez me huele peor en el tema de las distribuciones regionales. Me refiero a esas distribuciones que tanto abundan en España. Y lo que huele mal es, precisamente, que haya tantas.

Es evidente que con semejante fragmentación, esto no avanza hacia ningún sitio. Hay gente que, por ejemplo, pretende en serio que los vendedores de ordenadores preinstalen Linex, la distribución de Extremadura, una región de poco más de 1 millón de habitantes. Si ya de por si resulta difícil que compañías como Dell lo hagan con Ubuntu para un mercado mundial, imagínense con Linex.

Otro argumento muy común a favor de estas distribuciones es que gracias al software libre se pueden contratar programadores y compañías locales, en lugar de depender de los de la multinacional de turno. Si bien esto es cierto (y es una de las mayores ventajas del software libre), es obvio que la fragmentación juega muy en contra de la estandarización. Ejemplo, pongamos que es usted un programador y crea un magnífico programa que por alguna razón la administración quiere comprar, pues si quiere extenderse a administraciones de más allá de su terruño tendrá que soportar todas distribuciones. Que puede merecer la pena económicamente, pero es un obstáculo más. Otro ejemplo: Trisquel, la distro de Galicia, tiene la particularidad de estar dirigidas por fanáticos del FSF que eliminan todo software que no cumpla las cuatro sagradas reglas de Stallman. Y olvidémonos de soporte comercial para el mercado de usuarios de escritorio.

Existe un espacio donde tal vez las distribuciones regionales tengan sentido, y es en la administración de sistemas de la administración (valga la redundancia). Los gobiernos regionales tienen sistemas informáticos propios lo suficientemente extensos y complejos como para poder beneficiarse de tener todo bajo control, sin embargo, este es un uso a nivel interno que a los ciudadanos no importa.

Más allá de este caso, ¿de verdad necesitan las escuelas de cada región una distribución educativa distinta?

Diría que hemos llegado a un punto en el que las distribuciones regionales, más que un beneficio están suponiendo un obstáculo para el progreso del software libre. En lugar de crear y mantener distribuciones onanistas, las administraciones deberían optar por cosas como debianedu, edubuntu, o directamente Ubuntu, o cosas así. No se trata de eliminar su inversión en software libre, sino de dirigirlo a proyectos más grandes, donde se pueda aunar esfuerzos con muchas otras personas, con muchas otras administraciones. Entre ayuntamientos, provincias, regiones y estados hay en Europa unas 200.000 administraciones, algo en común se podrá tener.

3 de diciembre de 2011

Trapos sucios de Unix: readdir()

Una de las cosas más curiosas de los sistemas Unix es cómo han ido cambiando su propia imagen a lo largo de los años. Hoy Unix se entiende como sinónimo de fiable, eficiente, buen diseño, profesional, etc; a pesar de que Unix era un sistema operativo muy simplista, con importantes fallos y carencias  que tuvieron que arreglarse o añadirse posteriormente, a menudo no de la mejor manera. Un buen ejemplo de ello es la historia de readdir(), una función que devuelve la lista de archivos y/o subdirectorios presentes dentro de un directorio.

Uno de los principios fundamentales de la filosofía Unix es el de "Todo es un archivo", es decir, la unificación de toda clase de I/O sobre un sistema de archivos jerárquico en el que los archivos, además de archivos, pueden representar a dispositivos de hardware. Tal fuerza dogmática tiene este principio que cuando se diseñó Unix se decidió, o se asumió de manera natural, que los directorios también eran archivos normales y corrientes. Así que las primeras versiones de Unix no tenían llamadas al sistema para algo tan común como listar un directorio.

¿Cómo averiguaba entonces un programa, como por ejemplo ls, los contenidos de un directorio? Pues tratándolos literalmente como archivos. Se abría el directorio con fopen() y se leía el contenido con fread(). El contenido de los archivos de tipo directorio era simplemente una lista consecutiva de parejas nombre/número de inodo, cada una representando un archivo y/o subdirectorio. Y el programa tenía que echar un ojo a esas estructuras e interpretarlas él mismo para saber qué había dentro del directorio, no existía ninguna llamada al sistema que lo hiciera por ti.

Por esa razón, la primera función readdir() no fue una llamada al sistema, sino una función implementada dentro de los programas que lo necesitaban. Si no lo creen, pueden verlo ustedes mismos en la función readdir() del ls.c de Unix Version 7, de 1979. Cuando los diferentes sistemas Unix fueron incorporando características que hacían de esta manera de trabajar con directorios un inconveniente, acabaron añadiendo llamadas al sistema (getdents()) que sirvieran de ayuda para implementar readdir(), la cual se acabaría incorporando a la libc.

Como prueba de esta herencia, han quedado ciertos retazos en algunos sistemas Unix (por ejemplo, FreeBSD), en los que el comando cat directorio es un comando válido, que se ejecuta sin errores, e imprime en la pantalla algo que parece "basura" sin formato del tipo de /dev/random pero que, en realidad, es el contenido del directorio, tal y como ocurría en los Unix originales (en Linux esto no ocurre, se ha asumido que los directorios son directorios, y tratar de leer un directorio como archivo devuelve el error EISDIR).

Pero no se acaba aquí esta historia. Que el diseño original de Unix tuviera estos entresijos acabaría teniendo consecuencias que se heredaron con el tiempo, hasta llegar a hoy.

El hecho de que los directorios originales de Unix fueran simples concatenaciones lineales de parejas nombre/númerodeinodo hizo que las interfaces asumieran que el contenido de un directorio sería siempre lineal. De ese modo surgieron APIs como telldir(), la cual obtiene la posición de un elemento dentro del listado de un directorio. Esta posición puede utilizarse en seekdir() para mover un listado a una posición determinada del directorio. Es decir, se trata a un directorio como un archivo en el que un programa puede moverse de un lado a otro sin problemas.

Esto causó un gran problema con el advenimiento de los sistemas de archivos modernos, basados en estructuras de árbol. Las estructuras de árbol utilizadas en sistemas de archivo (B-Tree y similares) tienen como una de sus características fundamentales el rebalanceo para redistribuir los nodos del árbol a medida que se crean o eliminan archivos. Este rebalanceo puede cambiar el orden en el que un determinado elemento aparece en un listado de directorio, es decir, no se garantiza que usar seekdir() en una posición determinada dos veces consecutivas nos lleve al mismo elemento.

¿Que han hecho los sistemas de archivo Unix basados en B-Trees para lidiar con este problema? Esencialmente, tratar de parchear el problema (resolverlo no es posible, siempre habrá que mantener la compatibilidad con la tradición Unix). Por ejemplo, JFS tiene un B-Tree extra exclusivamente dedicado a mantener una doble indexación que permita satisfacer las garantías de readdir() y compañía. Btrfs, un sistema de archivos de última generación, también mantiene una doble indexación, por cada elemento añadido a un directorio se crean dos items: uno ordenado por hash y otro ordenado secuencialmente. Ext3/4 por su parte sólo ordena los elementos por hash, pero trata de mantener la secuencialidad leyendo los contenidos del directorio por el orden de hash.

Estas técnicas suponen, por supuesto, un trabajo y E/S extra que tiene un impacto en el rendimiento. ¡Ah, y por supuesto, la concepción lineal de los directorios implica que listarlos con readdir() y operar con ellos puede tener una complejidad algorítmica lineal! Así que resulta que Unix, culmen del buen diseño de sistemas operativos, implementa los directorios de una forma verdaderamente patética, y nos hacer pagar sus errores con impacto en el rendimiento (hay software que usa diferentes trucos para evitar acumular miles de archivos en un mismo directorio).

La lección de toda esta historia es que por muy genial que sea el diseño de tu software, obsesionarse con abstracciones perfectas e intentar imponerlas bajo la creencia de que su pureza es la única forma decente de hacer las cosas puede llegar a ser un gran error.

27 de noviembre de 2011

Estupidez artificial

En los últimos meses se han visto un par de cosas muy interesantes hechas con ordenadores que a mi juicio tienen una gran importancia. Me refiero a la victoria del ordenador de IBM "Watson" en un concurso de Jeopardy, y "Siri", el asistente de voz del iPhone.

Y si, sé que, además del tradicional reconocimiento de voz, existen programas como las acciones de voz de Android y aplicaciones análogas. Pero les desafío a encontrar alguien que diga en serio que Siri no está bastante más refinado, basta echar un ojo a los vídeos donde se comparan a ambos. Siri no sólo reconoce lo dicho sino que capta el contexto de las conversaciones y las intenciones con una calidad envidiable, y está perfectamente integrado con el resto del sistema. Para la gente no interesada en la tecnología, poder decir a un teléfono "recuerdame que tengo que comprar leche cuando salga del trabajo" es muy llamativo, y para bien o para mal Apple va a ser considerado por el público como la primera compañía que fue capaz de hacer semejantes operaciones con cierta dignidad y sin instalar ningún extra. Fanboysmo no, gracias.

La relevancia de Watson y Siri es que, en el espacio de unos pocos meses, han mostrado al mundo que comunicarse a los ordenadores mediante voz ha dejado de ser una cosa de ciencia ficción o de programas de reconocimiento de voz, la charla puede ser un medio habitual para comunicarse con ordenadores. Ejemplo, búsqueda. Aunque la afirmación que se ha leído por ahí sobre que Siri es un "google killer" es una clara exageración, no excluye la realidad de que buscar mediante voz -entender lo que se pregunta, no simplemente sintetizar la búsqueda en texto- va a ser algo cada vez más importante para los motores de búsqueda. Wolfram Alpha -utilizado por Siri para responder algunas preguntas- parece cada vez más interesante.

Todo lo dicho en este artículo es obvio y lo habrán leído ya en otros lados. Sin embargo, en este humilde blog he decidido ponerme mi sombrero futurista e intentar ir más allá. Watson usa 2.880 Power7, 16 TB de RAM y 4 TB de almacenamiento. ¿Que ocurrirá el día en el que el progreso del hardware y la mejora y "comoditización" de esta clase de software ponga esa misma capacidad de procesamiento en un puñetero teléfono móvil? Quizás lleguemos a descargarnos toda la literatura médica vigente hasta la fecha y la base de datos de Wikipedia, y podremos obtener diagnósticos médicos preliminares -Watson ya está en ello- o información de cualquier concepto histórico. ¿Por qué no? De hecho, llegaríamos a tener cosas así en la nube antes de que los móviles lleguen a ese punto.

También es interesante plantearse los retos que este tipo de juguetes planteará a los programadores. Tradicionalmente, los programadores se relacionan con sus usuarios mediante interfaces de usuario. Pero visto lo visto, no es ninguna quimera plantearse un mundo en el que los usuarios quieran usar programas hablando.

Lo más curioso de esto es que la sociedad mitificó durante años la "inteligencia artificial". En realidad no necesitamos inteligencia, nos basta con un cierto nivel de estupidez artificial que sea capaz de buscar dentro de bases de datos y entender órdenes simples, algo así ya sobra para causar una revolución social. Piensen en puestos de asistencia al cliente, ciertas clases de funcionarios. ¿Cuánto tardaremos en ver Siris y Watsons por las esquinas?