Saturday, August 31, 2019

El Programador Humilde

Conferencia ACM Turing (Association for Computing Machinery) 1972
From: http://www.cs.utexas.edu/users/EWD/transcriptions/EWD03xx/EWD340.html
Original typescript http://www.cs.utexas.edu/users/EWD/ewd03xx/EWD340.PDF

"El Programador Humilde"
por:
Edsger W. Dijkstra


Como resultado de una larga secuencia de coincidencias, ingresé oficialmente a la profesión de programación la primera mañana de primavera de 1952 y, por lo que he podido rastrear, fui el primer holandés en hacerlo en mi país. En retrospectiva, lo más sorprendente fue la lentitud con la que, al menos en mi parte del mundo, surgió la profesión de programación, una lentitud que ahora es difícil de creer. Pero estoy agradecido por dos vívidos recuerdos de ese período que establecen esa lentitud más allá de cualquier duda.
 

Después de haber programado durante unos tres años, tuve una discusión con A. van Wijngaarden, quien era mi jefe en el Centro de Matemáticas en Amsterdam, una discusión por la cual estaré agradecido con él mientras viva. El punto era que se suponía que debía estudiar física teórica en la Universidad de Leiden simultáneamente, y cuando encontré las dos actividades cada vez más difíciles de compaginar, tuve que decidir, ya sea para dejar de programar y convertirme en un teórico real y respetable. físico, o para llevar mi estudio de física a una finalización formal solamente, con un mínimo de esfuerzo, y para convertirme en ..... ¿sí qué? ¿Un programador? ¿Pero era una profesión respetable? Después de todo, ¿qué era la programación? ¿Dónde estaba el sólido cuerpo de conocimiento que podría apoyarlo como una disciplina intelectualmente respetable? Recuerdo vívidamente cómo envidiaba a mis colegas de hardware, quienes, cuando se les preguntó acerca de su competencia profesional, al menos pudieron señalar que sabían todo acerca de los tubos de vacío, los amplificadores y el resto, mientras que sentí que, al enfrentar esa pregunta, yo se pararía con las manos vacías. Lleno de dudas, llamé a la puerta de la oficina de van Wijngaarden y le pregunté si podía "hablar con él por un momento"; Cuando salí de su oficina varias horas después, era otra persona. Después de haber escuchado mis problemas con paciencia, estuvo de acuerdo en que hasta ese momento no había mucha disciplina de programación, pero luego explicó en voz baja que las computadoras automáticas estaban aquí para quedarse, que estábamos al principio y podíamos ¿No podría ser yo una de las personas llamadas a hacer de la programación una disciplina respetable en los próximos años? Este fue un punto de inflexión en mi vida y completé mi estudio de física formalmente tan rápido como pude. Una moraleja de la historia anterior es, por supuesto, que debemos ser muy cuidadosos cuando damos consejos a las personas más jóvenes; a veces lo siguen!
 

Otros dos años después, en 1957, me casé y los ritos de matrimonio holandeses requieren que declares tu profesión y dije que era programador. Pero las autoridades municipales de la ciudad de Amsterdam no lo aceptaron porque no existía tal profesión. Y, lo creas o no, pero bajo el título "profesión", ¡mi acto de matrimonio muestra la ridícula entrada "físico teórico"!
 

Tanto por la lentitud con la que vi surgir la profesión de programación en mi propio país. Desde entonces, he visto más del mundo, y tengo la impresión general de que en otros países, además de un posible cambio de fechas, el patrón de crecimiento ha sido muy similar.

Permítanme tratar de capturar la situación en esos viejos tiempos con un poco más de detalle, con la esperanza de comprender mejor la situación actual. Mientras seguimos nuestro análisis, veremos cuántos malentendidos comunes sobre la verdadera naturaleza de la tarea de programación se remontan a ese pasado ahora distante.
 

Las primeras computadoras electrónicas automáticas eran todas máquinas únicas de ejemplares únicos y todas se encontraban en un entorno con el sabor emocionante de un laboratorio experimental. Una vez que la visión de la computadora automática estuvo allí, su realización fue un tremendo desafío para la tecnología electrónica disponible en ese momento, y una cosa es cierta: no podemos negar el coraje de los grupos que decidieron intentar construir un equipo tan fantástico. Para equipos fantásticos eran: en retrospectiva, uno solo puede preguntarse si esas primeras máquinas funcionaron, al menos algunas veces. El problema abrumador era conseguir y mantener la máquina funcionando correctamente. La preocupación por los aspectos físicos de la informática automática todavía se refleja en los nombres de las sociedades científicas más antiguas en el campo, como la Asociación de Maquinaria de Computación (ACM) o la Sociedad Británica de Computación, nombres en los que se hace referencia explícita al equipo físico.

¿Qué pasa con el pobre programador? Bueno, para decir la verdad sincera: apenas lo notaron. Por un lado, las primeras máquinas eran tan voluminosas que apenas podía moverlas y, además, requerían un mantenimiento tan extenso que era bastante natural que el lugar donde las personas intentaran usar la máquina fuera el mismo laboratorio donde se había desarrollado la máquina. . En segundo lugar, su trabajo algo invisible era sin glamour: se podía mostrar la máquina a los visitantes y eso era varios órdenes de magnitud más espectacular que algunas hojas de codificación. Pero lo más importante de todo, el propio programador tenía una visión muy modesta de su propio trabajo: su trabajo derivaba todo su significado de la existencia de esa maravillosa máquina. Como se trataba de una máquina única, sabía muy bien que sus programas solo tenían un significado local y, como era obvio que esta máquina tendría una vida útil limitada, sabía que muy poco de su trabajo tendría un valor duradero. Finalmente, hay otra circunstancia que tuvo una profunda influencia en la actitud del programador hacia su trabajo: por un lado, además de no ser confiable, su máquina generalmente era demasiado lenta y su memoria era demasiado pequeña, es decir, se enfrentaba a un dolor en el zapato, mientras que, por otro lado, su código de orden, por lo general un tanto extraño, satisfaría las construcciones más inesperadas. Y en aquellos días, muchos programadores inteligentes obtuvieron una inmensa satisfacción intelectual de los trucos astutos mediante los cuales se las arregló para comprimirlo todo hasta lo imposible para adaptarse a las limitaciones de su equipo.
 

Dos opiniones sobre programación en aquellos dias. Los menciono ahora, volveré sobre ellos más tarde. La única opinión era que un programador realmente competente debería ser ingenioso y muy aficionado a los trucos inteligentes; la otra opinión era que la programación no era más que optimizar la eficiencia del proceso computacional, en una dirección u otra.
La última opinión fue el resultado de la frecuente circunstancia de que, de hecho, el equipo disponible era como un doloroso zapato que, y en esos días a menudo se encontraban con la ingenua expectativa de que una vez que hubiera máquinas más potentes disponibles, la programación ya no sería un problema, porque entonces la lucha para llevar la máquina al límite ya no sería necesaria ya que de eso se trataba la programación, ¿no? Pero en las siguientes décadas sucedió algo completamente diferente: máquinas más potentes estuvieron disponibles, no solo un orden de magnitud más poderoso, incluso varios órdenes de magnitud más potentes. Pero en lugar de encontrarnos en el estado de felicidad eterna de todos los problemas de programación resueltos, ¡nos encontramos hasta el cuello en la crisis del software! ¿Cómo podía ser?
 

Hay una causa menor: en uno o dos aspectos, la maquinaria moderna es básicamente más difícil de manejar que la maquinaria antigua. En primer lugar, tenemos las interrupciones de E/S, que ocurren en momentos impredecibles e irreproducibles; En comparación con la vieja máquina secuencial que pretendía ser un autómata totalmente determinista, este ha sido un cambio dramático y muchas canas de un programador de sistemas dan testimonio del hecho de que no debemos hablar a la ligera sobre los problemas lógicos creados por esa característica. En segundo lugar, tenemos máquinas equipadas con varios niveles de almacenamiento, lo que nos presenta problemas de estrategia de gestión que, a pesar de la extensa literatura sobre el tema, siguen siendo bastante esquivas. Esto aún más, con la complicación adicional debida a los cambios estructurales de las máquinas reales.
 

Pero llamé a esto una causa menor:  La causa principal es ... ¡que las máquinas se han vuelto más poderosas en varios órdenes de magnitud! Para decirlo sin rodeos: mientras no hubiera máquinas, la programación no era un problema en absoluto; cuando teníamos algunas computadoras débiles, la programación se convirtió en un problema leve, y ahora tenemos computadoras gigantes, la programación se convirtió en un problema igualmente gigantesco. En este sentido, la industria electrónica no ha resuelto un solo problema, solo los ha creado, ha creado el problema de usar sus productos. Para decirlo de otra manera: a medida que el poder de las máquinas disponibles creció en un factor de más de mil, la ambición de la sociedad de aplicar estas máquinas creció en proporción, y fue el pobre programador quien encontró su trabajo en este campo de tensión explotado entre fines y medios. La mayor potencia del hardware, junto con el aumento quizás aún más dramático en su confiabilidad, hizo posibles las soluciones con las que el programador no se había atrevido a soñar unos años antes. Y ahora, unos años más tarde, tuvo que soñar con ellos y, lo que es peor, ¡tuvo que transformar tales sueños en realidad! ¿Es sorprendente que nos encontremos en una crisis de software? No, ciertamente no, y como puede suponer, incluso se predijo con mucha antelación; pero el problema con los profetas menores, por supuesto, es que solo cinco años después se sabe realmente que tenían razón.
 

Luego, a mediados de los años sesenta, sucedió algo terrible: las computadoras de la llamada tercera generación hicieron su aparición. La literatura oficial nos dice que su relación precio / rendimiento ha sido uno de los principales objetivos de diseño. Pero si toma como "rendimiento" el ciclo de trabajo de los diversos componentes de la máquina, poco evitará que termine con un diseño en el que la mayor parte de su objetivo de rendimiento se alcanza mediante actividades internas de mantenimiento de dudosa necesidad. Y si su definición de precio es el precio que se pagará por el hardware, poco evitará que termine con un diseño que es terriblemente difícil de programar: por ejemplo, el código de pedido podría aplicarse, ya sea al programador o sobre el sistema, decisiones vinculantes tempranas que presentan conflictos que realmente no pueden resolverse. Y en gran medida, estas desagradables posibilidades parecen haberse convertido en realidad.

Cuando se anunciaron estas máquinas y se conocieron sus especificaciones funcionales, muchos de nosotros debimos de ser bastante poco fiables; Al menos yo lo fuí. Era razonable esperar que tales máquinas inundaran la comunidad informática y, por lo tanto, era aún más importante que su diseño fuera lo más sólido posible. Pero el diseño encarnaba defectos tan graves que sentí que de un solo golpe el progreso de la ciencia informática se había retrasado al menos diez años: fue entonces cuando tuve la semana más negra de toda mi vida profesional. Quizás lo más triste ahora es que, incluso después de todos esos años de experiencia frustrante, mucha gente cree sinceramente que alguna ley de la naturaleza nos dice que las máquinas tienen que ser así. Silencian sus dudas observando cuántas de estas máquinas se han vendido, y derivaban de esa observación la falsa sensación de seguridad de que, después de todo, el diseño no podría haber sido tan malo. Pero después de una inspección más cercana, esa línea de defensa tuvo la misma fuerza convincente que el argumento de que fumar cigarrillos debe ser saludable porque muchas personas lo hacen.

Es en este sentido que lamento que no sea habitual que las revistas científicas en el área de la informática publiquen revisiones de las computadoras recién anunciadas de la misma manera que revisamos las publicaciones científicas: revisar las máquinas sería al menos tan importante. Y aquí tengo una confesión que hacer: a principios de los años sesenta escribí tal revisión con la intención de presentarla al CACM, pero a pesar del hecho de que los pocos colegas a quienes se envió el texto para su consejo, me instaron para hacerlo, no me atreví a hacerlo, temiendo que las dificultades, tanto para mí como para el comité editorial, demostraran ser demasiado grandes. Esta supresión fue un acto de cobardía de mi parte por el cual me culpo cada vez más. Las dificultades que preveía eran consecuencia de la ausencia de criterios generalmente aceptados, y aunque estaba convencido de la validez de los criterios que había elegido aplicar, temía que mi revisión fuera rechazada o descartada como "una cuestión de gusto personal". . Todavía pienso que tales revisiones serían extremadamente útiles y anhelo verlas aparecer, ya que su apariencia aceptada sería un signo seguro de madurez de la comunidad informática.



La razón por la que he prestado la atención anterior a la escena del hardware es porque tengo la sensación de que uno de los aspectos más importantes de cualquier herramienta informática es su influencia en los hábitos de pensamiento de aquellos que intentan usarla, y porque tengo razones creer que esa influencia es muchas veces más fuerte de lo que comúnmente se supone. Pasemos ahora nuestra atención a la escena del software.
 

Aquí la diversidad ha sido tan grande que debo limitarme a unos pocos peldaños. Soy dolorosamente consciente de la arbitrariedad de mi elección y le ruego que no saque ninguna conclusión con respecto a mi agradecimiento por los muchos esfuerzos que quedarán sin mencionar.
 

1.-Al principio existía el EDSAC en Cambridge, Inglaterra, y creo que es bastante impresionante que desde el principio la noción de una biblioteca de subrutinas desempeñara un papel central en el diseño de esa máquina y de la forma en que debería usarse. Han pasado casi 25 años y la escena informática ha cambiado drásticamente, pero la noción de software básico todavía está con nosotros, y la noción de subrutina cerrada sigue siendo uno de los conceptos clave en la programación. Deberíamos reconocer las subrutinas cerradas como una de las mejores invenciones de software; ha sobrevivido a tres generaciones de computadoras y sobrevivirá a unas pocas más, porque abastece la implementación de uno de nuestros patrones básicos de abstracción. Lamentablemente, su importancia se ha subestimado en el diseño de las computadoras de tercera generación, en la que la gran cantidad de registros explícitamente nombrados de la unidad aritmética implica una gran sobrecarga en el mecanismo de subrutina. Pero incluso eso no eliminó el concepto de la subrutina, y solo podemos rezar para que la mutación no resulte hereditaria.
 

2.-El segundo desarrollo importante en la escena del software que me gustaría mencionar es el nacimiento de FORTRAN. En ese momento, este era un proyecto de gran temeridad y las personas responsables de él merecen nuestra gran admiración. Sería completamente injusto culparlos por las deficiencias que solo se hicieron evidentes después de una década de uso extenso: ¡los grupos con una anticipación exitosa de diez años son bastante raros! En retrospectiva, debemos calificar a FORTRAN como una técnica de codificación exitosa, pero con muy pocas ayudas efectivas para la concepción, ayudas que ahora se necesitan con tanta urgencia que ha llegado el momento de considerarla desactualizada. Cuanto antes podamos olvidar que FORTRAN ha existido, mejor, porque como vehículo de pensamiento ya no es adecuado: desperdicia nuestra capacidad intelectual, es demasiado arriesgado y, por lo tanto, demasiado costoso de usar. El destino trágico de FORTRAN ha sido su amplia aceptación, encadenando mentalmente a miles y miles de programadores a nuestros errores pasados. Rezo diariamente para que más de mis compañeros programadores encuentren los medios para liberarse de la maldición de la compatibilidad.
 

3.-El tercer proyecto que no quisiera dejar sin mencionar es LISP, una empresa fascinante de naturaleza completamente diferente. Con unos pocos principios muy básicos en su base, ha demostrado una notable estabilidad. Además de eso, LISP ha sido el proveedor de una considerable cantidad de aplicaciones informáticas más sofisticadas. LISP ha sido descrito en broma como "la forma más inteligente de hacer un mal uso de una computadora". Creo que esa descripción es un gran cumplido porque transmite todo el sabor de la liberación: ha ayudado a varios de nuestros seres humanos más talentosos a elaborar pensamientos que antes eran imposibles.
 

4.-El cuarto proyecto a mencionar es ALGOL 60. Mientras que hasta el día de hoy los programadores de FORTRAN todavía tienden a comprender su lenguaje de programación en términos de la implementación específica con la que están trabajando, de ahí la prevalencia de los volcados octal y hexadecimal, mientras que la definición de LISP sigue siendo una curiosa mezcla de lo que significa el lenguaje y cómo funciona el mecanismo, el famoso Informe sobre el lenguaje algorítmico ALGOL 60 es el fruto de un esfuerzo genuino para llevar la abstracción un paso vital más adelante y definir un lenguaje de programación en una implementación. forma independiente ¡Se podría argumentar que a este respecto sus autores han tenido tanto éxito que han creado serias dudas sobre si podría implementarse en absoluto! El informe demostró gloriosamente el poder del método formal BNF, ahora bastante conocido como Notación de Backus-Naur-Form [1], y el poder del inglés cuidadosamente redactado, al menos cuando es utilizado por alguien tan brillante como Peter Naur. Creo que es justo decir que solo unos pocos documentos tan cortos como este han tenido una influencia igualmente profunda en la comunidad informática. La facilidad con la que, en años posteriores, los nombres ALGOL y ALGOL-like se han utilizado, como una marca comercial desprotegida, para prestar parte de su gloria a una serie de proyectos más jóvenes, a veces poco relacionados, es un complemento un tanto impactante para su posición. La fuerza de BNF como dispositivo de definición es responsable de lo que considero una de las debilidades del lenguaje: una sintaxis demasiado elaborada y no demasiado sistemática ahora podría estar metida en los límites de muy pocas páginas. Con un dispositivo tan poderoso como BNF, el Informe sobre el lenguaje algorítmico ALGOL 60 debería haber sido mucho más corto. Además de eso, dudo mucho sobre el mecanismo de parámetros de ALGOL 60: permite al programador tanta libertad combinatoria que su uso seguro requiere una disciplina fuerte por parte del programador. Además de costoso de implementar, parece peligroso de usar.
 

5.-Finalmente, aunque el tema no es agradable, debo mencionar PL/1, un lenguaje de programación para el cual la documentación definitoria es de un tamaño y complejidad alarmantes. Usar PL/1 debe ser como volar un avión con 7000 botones, interruptores y manijas para manipular en la cabina. Absolutamente no veo cómo podemos mantener nuestros programas en crecimiento firmemente dentro de nuestro control intelectual cuando, por su barroco puro, el lenguaje de programación —nuestra herramienta básica, eso sí! - ya escapa a nuestro control intelectual. Y si tengo que describir la influencia que PL/1 puede tener en sus usuarios, la metáfora más cercana que me viene a la mente es la de una droga. Recuerdo de un simposio sobre lenguaje de programación de nivel superior una conferencia dada en defensa de PL/1 por un hombre que se describió a sí mismo como uno de sus usuarios dedicados. Pero dentro de una conferencia de una hora en elogio de PL/1, se las arregló para pedir la adición de unas cincuenta nuevas "características", cuando era de suponer que la fuente principal de sus problemas podría ser que contenía demasiadas "características". El orador mostró todos los síntomas deprimentes de la adicción, reducidos al estado de estancamiento mental en el que solo podía pedir más, más, más ... Así como cuando FORTRAN ha sido descrito como trastorno infantil, el PL/1 completo, con sus crecientes características de tumor maligno, podría llegar a ser considerado como una enfermedad mortal.
 

Ya he hablado demasiado sobre el pasado. Pero no tiene sentido cometer errores a menos que luego podamos aprender de ellos. De hecho, creo que hemos aprendido tanto, que dentro de unos años la programación puede llegar a ser una actividad muy diferente de lo que ha sido hasta ahora, tan diferente que es mejor que nos preparemos para el choque. Déjeme bosquejar uno de los futuros posibles. A primera vista, esta visión de la programación quizás en un futuro cercano tal vez pueda parecer absolutamente fantástica. Permítanme, por lo tanto, agregar también las consideraciones que pueden llevar a la conclusión de que esta visión podría ser una posibilidad muy real.
 

La visión es que, mucho antes de que los años setenta se hayan completado, podremos diseñar e implementar el tipo de sistemas que ahora están agotando nuestra capacidad de programación, a expensas de solo un pequeño porcentaje en años-hombre de lo que cuestan ahora, y además de eso, estos sistemas estarán prácticamente libres de errores. Estas dos mejoras van de la mano. En este último aspecto, el software parece ser diferente de muchos otros productos, donde, por regla general, una mayor calidad implica un precio más alto. Aquellos que quieran un software realmente confiable descubrirán que deben encontrar medios para evitar la mayoría de los errores desde el principio, y como resultado el proceso de programación se volverá más barato. Si desea programadores más efectivos, descubrirán que no deben perder el tiempo depurando, no deben introducir errores para comenzar. En otras palabras: ambos objetivos apuntan al mismo cambio.
 

Un cambio tan drástico en un período de tiempo tan corto sería una revolución, y para todas las personas que basan sus expectativas para el futuro en una extrapolación sin problemas del pasado reciente, en apego a algunas leyes no escritas de inercia social y cultural, la posibilidad de que se produzcaá un cambio drástico puede parecer insignificante. ¡Pero todos sabemos que a veces ocurren revoluciones! ¿Y cuáles son las posibilidades de ésta?
 

Parece que hay tres condiciones principales que deben cumplirse. El mundo en general debe reconocer la necesidad del cambio; en segundo lugar, la necesidad económica debe ser lo suficientemente fuerte; y, en tercer lugar, el cambio debe ser técnicamente factible. Permítanme discutir estas tres condiciones en el orden anterior.
 

1.-Con respecto al reconocimiento de la necesidad de una mayor fiabilidad del software, ya no espero desacuerdos. Hace solo unos años, esto era diferente: hablar de una crisis de software era una blasfemia. El punto de inflexión fue la Conferencia sobre Ingeniería de Software en Garmisch, octubre de 1968, una conferencia que creó una sensación cuando se produjo la primera admisión abierta de la crisis del software. Y a estas alturas generalmente se reconoce que el diseño de cualquier sistema sofisticado grande será un trabajo muy difícil, y cada vez que uno se encuentra con personas responsables de tales emprendimientos, uno se encuentra muy preocupado por el problema de la fiabilidad, y con razón. En resumen, nuestra primera condición parece haber sido satisfecha.
 

2.-Ahora, la necesidad económica. Hoy en día, a menudo se encuentra la opinión de que en los años sesenta la programación era una profesión sobrepagada, y que en los próximos años se espera que los salarios de los programadores bajen. Por lo general, esta opinión se expresa en relación con la recesión, pero podría ser un síntoma de algo diferente y bastante saludable, a saber. que tal vez los programadores de la última década no hayan hecho un trabajo tan bueno como deberían haberlo hecho. La sociedad se está insatisfecha con el desempeño de los programadores y de sus productos. Pero hay otro factor de mucho mayor peso. En la situación actual, es bastante habitual que para un sistema específico, el precio a pagar por el desarrollo del software sea del mismo orden de magnitud que el precio del hardware necesario, y la sociedad lo acepta más o menos. Pero los fabricantes de hardware nos dicen que en la próxima década se puede esperar que los precios del hardware bajen con un factor de diez. Si el desarrollo de software continuara siendo el mismo proceso torpe y costoso que es ahora, las cosas se saldrían completamente de balance. No puede esperar que la sociedad acepte esto y, por lo tanto, debemos aprender a programar un orden de magnitud con mayor eficacia. Para decirlo de otra manera: siempre y cuando las máquinas sean el elemento más importante en el presupuesto, la profesión de programación podría salirse con la suya con sus técnicas torpes, pero ese paraguas se doblará rápidamente. En resumen, también nuestra segunda condición parece estar satisfecha.
 

3.-Y ahora la tercera condición: ¿es técnicamente factible? Creo que podría serlo y le daré seis argumentos en apoyo de esa opinión.
 

Un estudio de la estructura de los programas reveló que éstos, incluso los  alternativos para la misma tarea y con el mismo contenido matemático, pueden diferir enormemente en su capacidad de gestión intelectual. Se han descubierto varias reglas, cuya violación perjudicará gravemente o destruirá totalmente la capacidad de gestión intelectual del programa. Estas reglas son de dos tipos. Los del primer tipo se imponen fácilmente mecánicamente, a saber. por un lenguaje de programación adecuadamente elegido. Ejemplos son la exclusión de declaraciones goto[2] y de procedimientos con más de un parámetro de salida. Para aquellos del segundo tipo, al menos, pero eso puede deberse a la falta de competencia por mi parte, no veo forma de imponerlo mecánicamente, ya que parece necesitar algún tipo de comprobador de teoremas automático para el que no tengo pruebas de su existencia. Por lo tanto, por el momento y quizás para siempre, las reglas del segundo tipo se presentan como elementos de disciplina requeridos para el programador. Algunas de las reglas que tengo en mente son tan claras que pueden enseñarse y nunca sería necesario discutir si un programa determinado las viola o no. Ejemplos son el requerimiento de que no debe escribirse ningún bucle sin proporcionar una prueba de finalización ni sin indicar la relación cuya invariabilidad no será destruida por la ejecución de la declaración repetible.
 

Ahora sugiero que nos limitemos al diseño e implementación de programas intelectualmente manejables. Si alguien teme que esta restricción sea tan severa que no podamos vivir con ella, puedo tranquilizarlo: la clase de programas intelectualmente manejables sigue siendo lo suficientemente rica como para contener muchos programas muy realistas para cualquier problema capaz de tener una solución algorítmica. No debemos olvidar que no es nuestro negocio hacer programas, es nuestro negocio diseñar clases de cómputos que muestren el comportamiento deseado. La sugerencia de limitarnos a programas manejables intelectualmente es la base de los primeros dos de mis seis argumentos anunciados:
 

1.- El primer argumento es que, dado que el programador solo necesita considerar programas manejables intelectualmente, las alternativas que está eligiendo deben ser mucho más fáciles de manejar.
 

2.- El segundo argumento consiste en que, tan pronto como hayamos decidido restringirnos al subconjunto de los programas intelectualmente manejables, habremos logrado, de una vez por todas, una reducción drástica del espacio de solución a considerar. Y este argumento es distinto del argumento uno.
 

3.- El argumento tres se basa en el enfoque constructivo del problema de la corrección del programa. Hoy una técnica habitual es hacer un programa y luego probarlo. Pero: las pruebas de programa pueden ser una forma muy efectiva de mostrar la presencia de errores, pero es irremediablemente inadecuado para mostrar su ausencia. La única forma efectiva de aumentar significativamente el nivel de confianza de un programa es dar una prueba convincente de su corrección. Pero primero no se debe hacer el programa y luego probar su idoneidad, porque entonces el requisito de proporcionar la prueba solo aumentaría la carga del pobre programador. Por el contrario: el programador debe permitir que la prueba de corrección y el programa crezcan de la mano. El argumento tres se basa esencialmente en la siguiente observación: Si primero se pregunta cuál sería la estructura de una prueba convincente y, una vez encontrado esto, construye un programa que satisfaga los requisitos de esta prueba, estas preocupaciones de corrección resultarían ser una guía heurística muy efectiva. Por definición, este enfoque solo es aplicable cuando nos limitemos a programas manejables intelectualmente, pero nos proporciona medios efectivos para encontrar uno satisfactorio entre estos.
 

4.- El argumento cuatro tiene que ver con la forma en que la cantidad de esfuerzo intelectual necesario para diseñar un programa depende de la longitud del programa. Se ha sugerido que hay algún tipo de ley de la naturaleza que nos dice que la cantidad de esfuerzo intelectual que se necesita aumenta con el cuadrado de la longitud del programa. Pero, gracias a Dios, nadie ha podido probar esta ley. Y esto se debe a que no tiene por qué ser cierta. Todos sabemos que la única herramienta mental por medio de la cual un razonamiento muy finito puede cubrir una miríada de casos se llama "abstracción"; Como resultado, la explotación efectiva de sus poderes de abstracción debe considerarse como una de las actividades más vitales de un programador competente. En este sentido, podría valer la pena señalar que el propósito de la abstracción no es ser vago, sino crear un nuevo nivel semántico en el que uno pueda ser absolutamente preciso. Por supuesto, he tratado de encontrar una causa fundamental que impida que nuestros mecanismos de abstracción sean lo suficientemente efectivos. Pero no importa cuánto lo intenté, no encontré tal causa. Como resultado, tiendo a suponer, y hasta ahora no ha sido refutado por la experiencia, que mediante la aplicación adecuada de nuestros poderes de abstracción, el esfuerzo intelectual necesario para concebir o comprender un programa no necesita crecer más que proporcionalmente a la duración del programa. Pero un subproducto de estas investigaciones puede tener una importancia práctica mucho mayor y, de hecho, es la base de mi cuarto argumento: El subproducto fue la identificación de una serie de patrones de abstracción que juegan un papel vital en todo el proceso de componer programas. Ahora se sabe lo suficiente sobre estos patrones de abstracción a los que podría dedicar una conferencia sobre cada uno de ellos. Lo que la familiaridad y el conocimiento consciente de estos patrones de abstracción implican y me dí cuenta de ello, es que si hubieran sido de conocimiento común hace quince años, el paso de BNF a compiladores dirigidos por sintaxis, por ejemplo, podría haber tomado unos minutos en lugar de unos años. Por lo tanto, presento nuestro conocimiento reciente de los patrones de abstracción como algo vital como cuarto argumento.
 

5.- Ahora el quinto argumento: Tiene que ver con la influencia de la herramienta que estamos tratando de usar sobre nuestros propios hábitos de pensamiento. Observo una tradición cultural, que probablemente tiene sus raíces en el Renacimiento, de ignorar esta influencia, considerar la mente humana como el maestro supremo y autónomo de sus artefactos. Pero si empiezo a analizar los hábitos de pensamiento de mí mismo y de mis semejantes, llego, me guste o no, a una conclusión completamente diferente, a saber: Que las herramientas que estamos tratando de usar y el lenguaje o la notación que estamos usando para expresar o registrar nuestros pensamientos, son los principales factores que determinan lo que podemos pensar o expresar !!. El análisis de la influencia que los lenguajes de programación tienen en los hábitos de pensamiento de sus usuarios, y el reconocimiento de que, por ahora, la capacidad intelectual es, con mucho, nuestro recurso más escaso, juntos nos dan una nueva colección de criterios para comparar los méritos relativos de los distintos lenguajes de programación. El programador competente es plenamente consciente del tamaño estrictamente limitado de su propio cráneo; por lo tanto, aborda la tarea de programación con total humildad y, entre otras cosas, huye de los trucos ingeniosos como de la peste. En el caso de un lenguaje de programación conversacional bien conocido, me han dicho desde varios lados que tan pronto como una comunidad de programación está equipada con un terminal para él, ocurre un fenómeno específico que incluso tiene un nombre bien establecido: se llama "las frases de una sola línea". Toma una de dos formas diferentes: un programador coloca un programa de una línea en el escritorio de otro y con orgullo dice lo que hace y agrega la pregunta "¿Puedes codificar esto con menos símbolos?", ¡Como si tuviera alguna relevancia conceptual! - o simplemente preguntar "¡Adivina qué hace!". De esta observación debemos concluir que este lenguaje como herramienta es una invitación abierta a trucos ingeniosos, y aunque exactamente esta pudiera ser la exposición pública de algunos de los recursos disponibles de aquellos a quienes les gusta mostrar cuán inteligentes son, lo siento, pero debo considerar esto como una de las cosas más condenatorias que se pueden decir sobre un lenguaje de programación. Otra lección que deberíamos haber aprendido del pasado reciente es que el desarrollo de lenguajes de programación “más ricos” o “más poderosos” fue un error en el sentido de que estas monstruosidades barrocas, estos conglomerados de idiosincrasias, son realmente inmanejables, tanto mecánica como mentalmente. Veo un gran futuro para lenguajes de programación muy sistemáticos y muy modestos. Cuando digo "modesto", quiero decir que, por ejemplo, no solo la "cláusula for" de ALGOL 60, sino incluso el "bucle DO" de FORTRAN podrían verse expulsados ​​por ser demasiado barrocos. He realizado un pequeño experimento de programación con voluntarios realmente experimentados, pero algo bastante inesperado apareció. Ninguno de mis voluntarios encontró la solución obvia y más elegante. Tras un análisis más detallado, esto resultó tener una fuente común: su noción de repetición estaba tan estrechamente relacionada con la idea de una variable controlada asociada que se fuera incrementando, que se bloquearon mentalmente sin poder ver lo obvio. Sus soluciones fueron menos eficientes, innecesariamente difíciles de entender, y les llevó mucho tiempo encontrarlas. Fue una experiencia reveladora pero también impactante para mí. Finalmente, en un aspecto, uno espera que los lenguajes de programación del mañana difieran mucho de lo que estamos acostumbrados hasta ahora: y en un grado mucho mayor que hasta ahora, deberían invitarnos a reflexionar en la estructura de lo que escribimos, en todas las abstracciones necesarias para enfrentar conceptualmente la complejidad de lo que estamos diseñando. Hasta aquí en cuanto a la mayor adecuación de nuestras herramientas futuras, ha sido la base del quinto argumento.
 

Como comentario adicional, me gustaría insertar una advertencia para aquellos que identifican la dificultad de la tarea de programación con la lucha contra las deficiencias de nuestras herramientas actuales, porque podrían concluir que, una vez que nuestras herramientas sean mucho más adecuadas, la programación ya no ser un problema. La programación seguirá siendo muy difícil, porque una vez que nos hayamos liberado de la circunstancia engorrosa actual, nos encontraremos libres para abordar los problemas que ahora están más allá de nuestra capacidad de programación.
 

6.- Pueden polemizar con mi sexto argumento, ya que no es tan fácil recopilar evidencia experimental para su apoyo, un hecho que no me impedirá creer en su validez. Hasta ahora no he mencionado la palabra "jerarquía", pero creo que es justo decir que este es un concepto clave para todos los sistemas que incorporan una solución bien realizada. Incluso podría ir un paso más allá y hacer un artículo de fe, a saber, que los únicos problemas que realmente podemos resolver de manera satisfactoria son aquellos que finalmente admiten una solución bien realizada. A primera vista, esta visión de las limitaciones humanas puede parecer una visión bastante deprimente de nuestra situación, ¡pero no lo siento así, al contrario! La mejor manera de aprender a vivir con nuestras limitaciones es conocerlas. En el momento en que seamos lo suficientemente modestos como para probar sólo soluciones bien ejecutadas, debido a que los otros esfuerzos escapan a nuestro control intelectual, haremos todo lo posible para evitar que todas esas interfaces perjudiquen nuestra capacidad de emplear el sistema de una manera útil. Y no puedo dejar de esperar que esto conduzca otra vez al descubrimiento de que, después de todo, se puede abordar un problema considerado anteriormente como no tratable. Cualquiera que haya visto cómo la mayoría de los problemas de la fase de compilación llamada "generación de código" puede rastrearse hasta las divertidas propiedades del código de órdenes, conocerá un ejemplo simple del tipo de cosas que tengo en mente. La aplicabilidad más amplia de las soluciones bien realizadas es mi sexto y último argumento para la viabilidad técnica de la revolución que podría tener lugar en la década actual.
 

En principio, te dejo decidir por ti mismo cuánto peso vas a dar a mis consideraciones, sabiendo muy bien que no puedo obligar a nadie más a compartir mis creencias. Como cada revolución seria, provocará una oposición violenta y uno puede preguntarse dónde esperar que las fuerzas conservadoras intenten contrarrestar tal desarrollo. No los espero principalmente en las grandes empresas, ni siquiera en el negocio de las computadoras; Los espero más bien en las instituciones educativas que brindan la capacitación de hoy y en esos grupos conservadores de usuarios de computadoras que piensan que sus viejos programas son tan importantes que no creen que valga la pena reescribirlos y mejorarlos. A este respecto, es triste observar que en muchos campus universitarios la elección de la instalación central de computación a menudo ha sido determinada por las demandas de algunas aplicaciones establecidas pero costosas, sin tener en cuenta la pregunta cuántos miles de "pequeños usuarios" que estén dispuestos a escribir sus propios programas iban a sufrir por esta elección. Con demasiada frecuencia, por ejemplo, la física de alta energía parece haber chantajeado a la comunidad científica con el precio de su equipo experimental existente. La respuesta más fácil, por supuesto, es una negación rotunda de la viabilidad técnica, pero me temo que necesita argumentos bastante sólidos para eso. No se puede obtener seguridad, por desgracia, de la observación de que el techo intelectual del programador promedio de hoy evitará que la revolución tenga lugar: con otros que programen de manera mucho más efectiva, es probable que sea eliminado de la foto de todos modos.
 

También puede haber impedimentos políticos. Incluso si sabemos cómo educar al programador profesional del mañana, no es seguro que la sociedad en la que vivimos nos permita hacerlo. El primer efecto de enseñar una metodología —más que diseminar conocimiento— es mejorar las capacidades de los que ya son capaces, magnificando así la diferencia en inteligencia. En una sociedad en la que el sistema educativo se utiliza como instrumento para el establecimiento de una cultura homogeneizada, en la que se impide que la crema llegue a la cima, la educación de programadores competentes podría ser difícil de llevar a la práctica.
 

Déjenme concluir. Las computadoras automáticas han estado con nosotros durante un cuarto de siglo. Han tenido un gran impacto en nuestra sociedad en su capacidad como herramientas, pero en esa capacidad su influencia no será más que una ondulación en la superficie de nuestra cultura, en comparación con la influencia mucho más profunda que tendrán en su capacidad de desafío intelectual sin precedente en la historia cultural de la humanidad. Los sistemas jerárquicos parecen tener la propiedad de que algo considerado como una entidad indivisa en un nivel, se considera como un objeto compuesto en el siguiente nivel inferior de mayor detalle; Como resultado, el grano natural de espacio o tiempo que es aplicable en cada nivel disminuye en un orden de magnitud cuando cambiamos nuestra atención de un nivel al siguiente nivel inferior. Entendemos las paredes en términos de ladrillos, ladrillos en términos de cristales, cristales en términos de moléculas, etc. Como resultado, el número de niveles que se pueden distinguir significativamente en un sistema jerárquico es algo proporcional al logaritmo de la relación entre los más grandes. y el grano más pequeño, y por lo tanto, a menos que esta relación sea muy grande, no podemos esperar muchos niveles. En la programación de computadoras, nuestro componente básico tiene un tiempo asociado de menos de un microsegundo, pero nuestro programa puede tomar horas de tiempo de cálculo. No conozco ninguna otra tecnología que cubra una proporción de 10^10 o más: la computadora, en virtud de su fantástica velocidad, parece ser la primera en proporcionarnos un entorno donde los artefactos altamente jerárquicos son posibles y necesarios. Este desafío, a saber. La confrontación con la tarea de programación es tan única que esta novedosa experiencia puede enseñarnos mucho sobre nosotros mismos. Esto, debería profundizar nuestra comprensión de los procesos de diseño y creación, debería darnos un mejor control sobre la tarea de organizar nuestros pensamientos. Si no fuera así, a mi gusto, ¡no deberíamos merecer la computadora en absoluto!
 

Esto ya nos ha dado algunas lecciones, y la que he elegido destacar en esta charla es la siguiente: Haremos un trabajo de programación mucho mejor, siempre que abordemos la tarea con una plena apreciación de su tremenda dificultad, siempre que nos atenemos a lenguajes de programación modestos y elegantes, siempre que respetemos las limitaciones intrínsecas de la mente humana y abordemos la tarea. como programadores muy humildes.

[1] https://es.wikipedia.org/wiki/Notaci%C3%B3n_de_Backus-Naur  es un metalenguaje usado para expresar gramáticas libres de contexto: es decir, una manera formal de describir lenguajes formales.
[2] https://es.wikipedia.org/wiki/GOTO GOTO es una instrucción propia de los primeros lenguajes de programación, como BASIC. Esta instrucción suele existir en todos los lenguajes aunque con un mnemónico adaptado al propio lenguaje. La instrucción GOTO ha sido menospreciada en los lenguajes de alto nivel, debido a la dificultad que presenta para poder seguir adecuadamente el flujo del programa, tan necesario para verificar y corregir los programas.

[NT] (Traduciendo esto, he tenido la momentánea y placentera sensación de estar un tiempo dentro de los razonamientos y estructura mental de una mente privilegiada y bien estructurada.) 

No comments:

Post a Comment