Las expectativas razonables

Imagen de César

En 5º curso teníamos un par de asignaturas optativas, y podíamos elegir incluso asignaturas de otras carreras, así que yo me cogí una del plan de matemáticas, Computación II, en la que aprendí a programar en C. Daba aquella asignatura la gran profesora Pilar Lasala, autora de varios libros sobre la materia. En uno de ellos leí algo que me escandalizó: su explicación sobre el procedimiento con el que se creaban los programas.

El primer paso –explicaba–, es escribir el programa (el código fuente). Una vez escrito, se compila. A continuación, se ejecuta el programa y se buscan los fallos. Se corrigen los fallos (en el código fuente), se vuelve a compilar, se vuelve a ejecutar y se buscan más fallos. Se repite el proceso hasta que no podamos encontrar más fallos.

Me escandalicé al leer esto porque a mí esto me sonó a enoooorme chapuza, algo que me resultaba inadmisible que estuviese escrito en un libro. Yo era el típico idiota que se creía más listo que nadie, así que para mí era evidente que el proceso correcto era escribir bien el código fuente, perfecto de partida, sin errores: lo de andar buscando y corrigiendo fallos una y otra vez no era de recibo, oiga.

Han pasado unos 20 años desde entonces. He pasado casi tantos diciéndome a mí mismo “¡qué razón tenía aquella mujer!” y avergonzado de mi estúpida ingenuidad.

Resulta que escribir un programa sin errores es sencillo cuando el programa es trivial (tan trivial como aquellos programas que yo escribía cuando estaba aprendiendo a programar), pero cuando el programa crece en tamaño y complejidad, la cosa se complica muchísimo. ¡Muchísimo! Entender el porqué es muy fácil: ver los errores en un programa con pocas líneas de código es tan sencillo como encontrar una aguja en un pajar sin paja: la dificultad de encontrar la aguja en el pajar la pone la cantidad de paja. Conforme aumenta el número de líneas de código, aumenta la probabilidad de que al programador se le cuele un gazapo, y aumenta así mismo la dificultad para encontrarlo. El programador cuenta con herramientas automáticas que le ayudan a encontrar gazapos, del mismo modo que un usuario cuenta con un corrector ortográfico para encontrar sus faltas de ortografía. Pero del mismo modo que un corrector ortográfico no encontrará ciertas faltas de ortografía, las herramientas del programador no encontrarán ciertos errores sintácticos o lógicos en sus programas.

Aun cuando el programador fuese capaz de escribir un programa sin errores sintácticos ni lógicos, resulta que este programa haría lo que el programador pensó que debería hacer y como el programador pensó que debería hacerse, ¿lo recordamos? Para programar el programa, el programador piensa en todos los casos que se vayan a poder dar, en todas las posibilidades, en todas las circunstancias... Si el programa no es trivial, fácilmente podremos tener millones de casos posibles cuando el usuario ejecute el programa, la mayoría de las cuales estarán dentro de lo contemplado por el programador; pero algunas no lo estarán, dando lugar a errores o mal funcionamiento en tiempo de ejecución.

Por si todo esto fuera poco, hemos de tener también en cuenta que los programas no lo hacen todo por sí mismos, sino que confían en otros programas, programados por otros programadores, para hacer muchas de las tareas que deben hacerse. Por ejemplo, cuando un programador programa un programa de nóminas, el programador no programa cómo se dibujarán puntito a puntito los botones que aparecerán en las ventanas que aparecerán en el monitor, ni programará cómo se accede a la unidad de almacenamiento para recoger o dejar la información, ni otras muchas cosas: lo que el programador programará será fundamentalmente la lógica del cálculo de nóminas y una interfaz para el usuario, y para que todo esto funcione confiará en los programas de terceros.

Resumiendo, podemos decir que el apocalíptico (pero real) panorama que tenemos delante, cuando lo que tenemos delante es un sistema informático no trivial, es que: es casi imposible que el programador haya escrito lo que quería programar sin ningún error, que además es casi imposible que lo que el programador quería programar no tuviese errores (es decir, contemplase perfectamente todas las posibilidades posibles), y que además es casi imposible que el programa funcione sin errores (aun cuando el programador perfecto hubiese programado el programa perfecto) debido a que el programa necesitará de otros programas cuyo funcionamiento perfecto es casi imposible por las mismas razones. A poco que entendamos de probabilidad, nos haremos fácilmente a la idea de que crear un programa (no trivial) sin fallos podría calificarse de milagro.

El usuario medio, sin embargo, desconocedor de todas estas dificultades, lo que espera es que todo funcione bien siempre.

Conocí a un tipo llamado David, uno de esos con un gran talento. Era Director de Calidad en una empresa en la que trabajé. Él expresaría este hecho diciendo que “el usuario medio tiene unas expectativas de calidad poco razonables”.

Que las expectativas del usuario no sean razonables es perjudicial para el usuario y perjudicial para el informático, es decir, perjudicial para todos.

Supongamos, por poner un ejemplo, que somos un usuario de cierto programa. Si esperamos que el programa satisfaga todas nuestras necesidades, se comporte siempre como queremos, y nunca falle, probablemente más pronto que tarde la realidad se encargará de desengañarnos. Como consecuencia, nos sentiremos frustrados. Si no queremos padecer esta desagradable sensación, más vale que vayamos asumiendo que los fallos y las carencias van a estar siempre ahí: estas o aquellas, en este o en aquel programa. Cuanto antes asumamos que la informática es imperfecta, antes podremos ser felices (o no demasiado desgraciados) con ella.

Supongamos, por poner otro ejemplo, que somos un empresario que quiere encargar un desarrollo a medida (un programa específico para la empresa, una aplicación web...). Si no somos conscientes de todo lo anterior, pensamos que es todo muy fácil y esperamos que todo funcione a la primera, bien y siempre, cuando el informático nos pase un presupuesto nosotros pensaremos que intenta timarnos. Entonces, nosotros rebajaremos el precio; con lo cual el informático o bien rechazará el trabajo o bien nos hará una chapuza. No estar dispuestos (¡por creer que no lo vale!) a pagar el precio que vale un trabajo bien hecho, acabará pasándonos factura. Cuanto antes asumamos que el trabajo de programar es un trabajo difícil y laborioso, antes podremos valorar adecuadamente los presupuestos que nos presenten. (Por supuesto, la otra parte de hacer una buena compra es no pagar por una chapuza el precio de un trabajo bien hecho.)

Muchos informáticos son tipos muy listos que hacen muy bien su trabajo, por lo que hay muchas cosas que funcionan muy bien casi siempre. Por otra parte, los vendedores (profesionales o aficionados) siempre recomiendan sus productos como si fuesen perfectos, aun cuando estén muy lejos de serlo. En informática (como en cualquier otra cosa), perfecto no hay nada y todos dicen que lo suyo es lo mejor.

Tres consejos, a modo de resumen, para ser felices y para que no nos engañen: Tengamos expectativas realistas, no confiemos ciegamente en las valoraciones ajenas, y aprendamos a valorar las dificultades y el trabajo que lleva hacer bien las cosas.