viernes, 27 de marzo de 2009

EL uso de GOTO o cómo convertir tu código en espagueti


Hace algunos años, cuando apenas aprendía a programar en C en la vocacional, me encontre con una instrucción de programación muy simpática: la instrucción GOTO. Me provocó curiosidad el saber qué hacía aquella instrucción, así que investigué un poco y descubrí que se trataba de una instrucción muy buena onda.

La instrucción GOTO (proveniente de la combinación de las palabras en inglés "go to" o, "ir a") se utiliza para modificar el flujo de un programa. Cuando se ejecuta, provoca un salto dentro del código hacia otra instrucción, marcada mediante una etiqueta. Por ejemplo:

int main()
{
printf("\n Antes del salto del GOTO.");
goto SALTO; // Instrucción GOTO
printf("\n Esta línea no se mostrará.");
SALTO: // Etiqueta
printf("\n Después del salto.");
}

Yo en ese momento pensé: "Wow!!! esta instrucción es genial!!!" y de inmediato comencé a utilizarla en los programas que debía realizar para entonces. Y es que en esos momentos me resultaba complicado entender estructuras como el while, el do-while o el for. Además, ¿no es perfecto el no tener restricciones para andar saltando de instrucción en instrucción por todo el código, sin preocuparse por permanecer o no dentro de un mismo bloque de código?

Pues bien, entregué mis programas con GOTO a mi profesora (la materia era 'Estructuras de datos', por cierto) y al revisar mi código exclamó con asombro "¿quién te enseñó esa palabrota? Me quitas esos GOTOS ahora mismo!!!". ¿Qué? ¿Pero por qué? Mi profesora me dijo que utilizar GOTOs era una mala práctica en programación, que rompía con el paradigma de la programación estructurada y blah blah blah, total que aprendí a no utilizarlo más, aunque no comprendía del todo el porque era malo usar un pequeño GOTO.

Los años pasaron y fui adquiriendo experiencia en programar en distintos lenguajes y en distintos paradigmas. Un buen día me encontre con la carpeta que contenía mis primeros programas y, con cierta nostalgia, empece a revisarlos y note con sorpresa que no entendía el código de muchos de ellos: aquellos en los que utilizaba GOTO. Por ejemplo:

int main()
{
int i = 1, n, r = 1;
init:
scanf("%d", &n);
if (0 > n) goto init;
if (n == 0) goto result;
loop:
r = r * i;
i++;
if (i > n) goto result;
goto loop;
result:
printf("r = %d", r);
}

Después de analizarlo algunos minutos podemos ver que se trata de una versión iterativa del programa que calcula el factorial de un número. Como podrán notar, el uso de GOTOs vuelve tediosa la tarea de entender un código, debido principalmente a los saltos que se producen de aquí para allá dentro del flujo del programa, y esto tan solo en un algoritmo sencillo. Indudablemente el problema se agrava en ejemplos más complejos, en los que el uso del GOTO simplemente hace imposible la tarea de reinterpretar un código.

Es precisamente esta la razón por la cual utilizar instrucciones GOTO no es tan buena idea. La aparente agilidad con la que se controla el flujo de un programa usando GOTOs origina un flujo de datos sumamente complicado de seguir, dando lugar a lo que se conoce como "Código espagueti". No en vano Edsger Dijkstra, uno de los más reconocidos computólogos de todos los tiempos, escribió los artículos "A Case against the GOTO statement" y "GOTO statement considered harmful" en los cuales explica la enorme dificultad para verificar y corregir programas que usan esta instrucción. Más aún, Dijkstra llegó a decir de los estudiantes que aprendieron a programar utilizando BASIC (un lenguaje de programación que invita al uso de instrucciones GOTO) que "habían sido irremediablemente inhabilitados para programar decentemente".

No obstante estos argumentos que parecen censurar el uso de esta instrucción, lo cierto es que la instrucción GOTO es una de las operaciones más primitivas para el control del flujo de los programas, y de hecho muchos compiladores traducen internamente sus estructuras de control a instrucciones GOTO, y existen situaciones muy específicas en las cuales usar una instrucción GOTO es la mejor solución (por ejemplo, en el manejo de excepciones internas de un programa). De cualquier manera, resulta 100% recomendable utilizar estructuras de control antes que esta sencilla y a la vez complicada instrucción.

Saludos.

domingo, 22 de marzo de 2009

Blogger.shyGuy.addEntry("About JavaTexting...");

Blogger.shyGuy.entry = new Entry("About JavaTexting...");

Blogger.shyGuy.entry.addParagraph("¿Qué tal a todos?");

Blogger.shyGuy.entry.addParagraph("Pues esta vez escribo " +
"para traerles la nueva locura del verano (y sí!!! apenas " +
"es primavera). Se trata de algo que inicié con un amigo " +
"como un pequeño reto, y que de pronto empezó a parecernos " +
"algo cool: hacer JavaTexting (cool para los geeks, claro).");

Blogger.shyGuy.entry.addParagraph("¿Qué es JavaTexting? Pues " +
"a menos que alguien ya nos halla ganado el término o el " +
"concepto, JavaTexting significa expresar todo texto " +
"electrónico con formato de código Java. La idea es simple: " +
"en cualquier oportunidad que tengas para escribir algo en " +
"tu computadora (chatear en el messenger, publicar en un " +
"blog, cambiar tu nombre de usuario, etc.), piensa cómo lo " +
"escribirías en Java, y pones esa \"línea de código\".");

Blogger.shyGuy.entry.addParagraph("El encanto de esta tontería " +
"radica en que puedes utilizar muchas herramientas del " +
"lenguaje Java para expresarte de manera creativa. Por " +
"ejemplo, digamos que estoy enfermo del estómago y quiero " +
"que todos se enteren de mi dolor. Javatexteando esto en " +
"algún medio electrónico, puedo emplear las siguientes lineas:");

shyGuy.add(new Pain(shyGuy.pain._BELLYACHE, "Dolor de estómago"));
shyGuy.isFeelingGood() == false;

Blogger.shyGuy.entry.addParagraph("Tambien por ejemplo, al " +
"chatear en messenger, en vez de los aburridos mensajes " +
"normales puedes mostrar que tan friki eres escribiendo: ");

shyGuy.sendMsg(msgUser.juan, "Hola Juan!");
shyGuy.sendMsg(msgUser.juan, "qué haces?");

shyGuy.sendBuzz(msgUser.juan);

Blogger.shyGuy.entry.addParagraph("Algo que ví en otro blog y " +
"que se puede \"implementar\" con Javatexting es una genial " +
"declaración de amor friki como esta:");

jose.loves(maria) == true;
if (maria.loves(jose)) {
while (true) {
jose.happiness++;
}
} else {
jose = null;
}

Blogger.shyGuy.entry.addParagraph("En fin, posibilidades hay " +
"muchas. Para hacer Javatexting, el único límite es tu " +
"imaginación (o que quieras escribir algo no computable).");

Blogger.shyGuy.entry.addParagraph("Saludos!!! Comenten!!!");