sábado, 9 de septiembre de 2017

El peligroso, salvaje e indispensable GOTO

Para Dante,
aunque sea con cerca de
30 años de retraso.


En marzo de 1968, el científico de computación holandés Edsger W. Dijkstra (conocido en occidente como Edgar Dijkstra) publicó el influyente artículo "Go To statement considered harmful" (La instrucción Go To considerada dañina) en el boletín de Comunicaciones de la ACM (Association for Computing Machinery), también conocida como CACM. En este artículo señalaba que el uso creciente del salto incondicional estaba ocasionando que los programas se volvieran ilegibles y muy propensos a errores y reflexionaba y disertaba como el mantener cierta disciplina en la programación permitiría hacer no solamente programas legibles y confiables, sino hacerlos más grandes y propensos a modificarlos en vez de rehacerlos (es decir, hacerlos más flexibles).

Por un lado, esto dio inicio a la disciplina llamada Programación Estructurada donde todo el flujo del programa está basado en bloques bien definidos y que no deben traslaparse ni intereferir entre sí.

Pero esto también ocasionó una gran polémica que, aunque es muy técnica y se ha ido acallando, sigue siendo escabrosa.
Desde el principio muchos programadores protestaron porque la sentencia GO TO era su principal herramienta de control de flujo, no había otra cosa; en 1974 el propio Donald Kunth (matemático considerado el mayor experto en algoritmos computacionales y profesor emérito en Stanford) argüía que a veces el uso del GO TO mejoraba la eficiencia de ejecución, de forma era mejor alternativa que el detrimento en legibilidad; en 1978 los diseñadores del lenguaje C, Brian Kernighan y Dennis Ritchie dijeron que "se podía abusar infinitamente del GO TO", pero de todas maneras lo incluyeron en las especificaciones de C.
El también científico de la computación, el suizo Niklaus Wirth, jefe del equipo de diseño de los lenguajes académicos Euler, Algol W, Pascal, Modula, Modula-2 y Oberon (que por cierto era el editor del CACM cuando se publicó la carta de Dijkstra), diseñó los lenguajes para impulsar la disciplina del estructuralismo en la programación, aunque incluyó el GO TO por si acaso. Esto dio origen a una de las preguntas más peliagudas y difíciles que influyen aun ahora en el diseño de lenguajes modernos: ¿las reglas en la sintaxis del lenguaje usado fomentan la buena programación?

El lenguaje JAVA, por ejemplo, tiene reservada la instrucción goto aunque no la usa. Esto es principalmente porque en los lenguajes modernos se usa pero con formatos muy específicos y con nombres diferentes: son la sentencias exit, continue, break y exception (o try-catch); esto es, hay que ver su uso, es equivalente a la función que desempeñaba el goto:

exit. Salida incondicional de un programa.
continue. Salta incondicionalmente a la siguiente iteración en un ciclo.
break. Sale incondicionalmente de un ciclo.
exception (o try-catch). Esta es la instrucción menos parecida al GO TO, aparentemente, pero si uno analiza su funcionamiento, su objetivo es casi el mismo: cuando se ejecutan algunas sentencias y operaciones ocasionan errores (por ejemplo, en una operación cuando se intenta dividir ente cero o cuando se le pide a la máquina que lea un número, pero la entrada contiene letras o símbolos no numéricos) y en este caso, se ejecuta la sentencia exception (o la parte equivalente, catch) que sirve como etiqueta o punto de entrada para ejecutar una subrutina o un bloque para manejar el error (recuperarse o al menos morir graciosamente). Esto es el equivalente a una sentencia GO TO condicionada y la ejecución de un bloque etiquetado:

if [ocurrió un error] goto excepcion
excepcion:
{ ....
   líneas de código para manejar el error
   ....
   ....
}

En resumen:

  • La sentencia GO TO no es mala per se, solamente cuando se usa sin control y en exceso es cuando es dañina.
  • La sentencia GO TO ya amaestrada se usa actualmente para manejo de excepciones, por ejemplo, mediante sentencias ejecutables ya más evolucionadas.
  • La sentencia GO TO se puede usar cuando el uso de otras sentencias o estructuras de control puedan conducir a un flujo complejo del programa (nota. Cuidado en este caso, si pasa esto, puede ser indicador de que el flujo completo del programa necesite rediseñarse, si nos gana la flojera, puede pasarnos lo mismo que al monito de la historieta del principio del post: en vez de un bug horriblito, le salió un velocirraptor salvaje).



5582.30