Primeros tiempos software.qxp 26/05/2009 14:44 PÆgina 51 AUTORES CIENTÍFICO-TÉCNICOS Y ACADÉMICOS Los primeros tiempos del software (parte I) Prof. Doctor Félix García Merayo Vicepresidente de ACTA à No hay atajo sin trabajo Refrán Introducción E n 1993 la National Academy of Engineering, Academia Nacional de Ingeniería, concedió su premio Charles Stark Draper a John Backus. ¿Cuáles eran sus méritos para merecer tan apreciado galardón? Fue sin duda su intervención en el desarrollo del lenguaje FORTRAN, primer lenguaje de ordenador de alto nivel y de propósito general. La decisión de la Academia fue aplaudida por la mayor parte de los profesionales de la computación, muchos de los cuales sabían bien de la contribución que Backus y su lenguaje FORTRAN habían tenido en el desarrollo de su propia profesión. Fortran (actualmente ya no se escribe con letras mayúsculas), aunque en uso hoy día, ha sido superado por otros lenguajes como C++, Visual Basic o por sistemas de software como UNIX, AIX o Windows, que reflejan mejor los cambios habidos en el hardware en general o en el entorno de los ordenadores personales y las estaciones de trabajo. Al aceptar el premio, Backus reconoció que el lenguaje había sido el resultado de un trabajo en equipo. Estos fueron sus colaboradores, todos como él trabajando en aquel momento para la compañía IBM: Ziller, Herrick, Beeber, Sheldon Best, Goldberg, Mitchell, Nelson Sayre, Sheridan y Stern. También Hughes, del Libermore Lab, y Nutt, de la United Aircraft Corporation. Donald Knuth fue considerado por muchos como el programador más grande del mundo, The Worlds Greatest Programmer. Alguna vez dijo que siempre se levantaba por las mañanas con una idea nueva que le capacitaba para añadir un par de líneas más a su programa del día anterior, lo que le proporcionaba una gran satisfacción. 51 Primeros tiempos software.qxp 26/05/2009 14:44 PÆgina 52 ACTA Los primeros tiempos del software (parte I) Añadía que eso mismo debía pasarles a los poetas, a los músicos o a los pintores. A él, la programación le producía ese sentimiento. En uno de mis anteriores artículos preparado para los Manuales de ACTA, concretamente el titulado La larga vida de un lenguaje de programación, mencionaba, entre otras cosas, que acababa de cumplirse en aquel momento el cincuentenario del diseño y creación del lenguaje FORTRAN con la producción de su primer compilador (año 1957). En él se contaba su historia, el desarrollo de las distintas versiones a lo largo de los años y las aplicaciones hechas con ese lenguaje. Añadiremos ahora que su utilización está aún presente en todas las aplicaciones donde se hace necesaria la colaboración de arquitecturas de altas prestaciones, los supercomputadores, para resolver problemas técnico-científicos de alta gama y de cálculo intensivo. Volvamos al premio Draper. Fue instituido precisamente para dar a los ingenieros el prestigio y la dotación económica que los Nobel conceden a los científicos. En el caso que nos ocupa, fue concedido a Backus, como hemos dicho, para reconocer el desarrollo de un software, es decir, algo que, por definición, no tiene esencia física, algo que no es hardware. Fue concedido también por algo que, en la época del desarrollo de los primeros computadores, pocos pensaban que sería necesario. Pero no sólo era necesario un software, sino que en la década de los noventa su desarrollo y marketing sobrepasaron el del propio hardware. Tanto es así que, en muchos casos, se ha convertido en una utilidad barata y de producción masiva. ¿Cómo ha emergido el software y cuál ha sido su relación con la evolución del hardware? ¿Cuáles fueron sus etapas constructivas y su orientación a lo largo de los primeros años de su puesta en servicio? Estas son algunas de las cuestiones a las que tratamos de dar contestación a lo largo de este escrito. à Una definición Una definición simple del concepto software es la siguiente: conjunto de instrucciones capaces de dirigir al ordenador para realizar una tarea específica. Con esa palabra indicamos una entidad única, separada del hardware, capaz de trabajar, sin embargo, en colaboración con él para resolver un problema concreto. Hemos dicho entidad única, pero ciertamente no es así. Un sistema de computación es como una esfera formada por capas sucesivas concéntricas, correspondiendo cada una de ellas a un tipo de software y 52 todas ellas montadas sobre un núcleo de hardware. Incluso en el centro de esa esfera, el denominado nivel del procesador central, no existe una distinción clara: chips que contienen microcódigo son capaces de dirigir otros chips con el fin de realizar la mayor parte de las operaciones básicas del procesador. Técnicamente esos códigos reciben el nombre de firmware, término que por sí sugiere una distinción más bien borrosa. Veamos un ejemplo con el que nos encontramos a diario. Situemos el microcódigo en un extremo, y pongamos en el otro un cajero, una máquina expendedora de billetes de un banco. Para servirse de esa máquina, el usuario presionará una serie de teclas en una secuencia determinada dando lugar con ello a que el computador que gobierna esa máquina ejecute un conjunto de operaciones complejas pero de forma correcta. Los diseñadores de tales máquinas tienen claro que sus usuarios no tienen por qué conocer nada de ordenadores, pero lo cierto es que, en este caso, el cliente del banco lo que hace (sin saberlo) es programar el computador que está detrás de la máquina dispensadora. El uso de estas máquinas comparte muchos de los atributos que le son comunes también a la programación. Por ejemplo, si el cliente presiona una tecla errónea en una larga sucesión de ellas, la transacción quedará totalmente invalidada. Además, si las reglas son demasiadas, ello pondrá en evidencia un pobre diseño de la máquina y confundirá al usuario más experto. Tenemos otro ejemplo similar cuando se trata de una grabadora de vídeo casera, grabadoras que muchos usuarios encuentran o han encontrado alguna vez dificultades para programarlas. Pues bien; la esencia del software se encuentra precisamente entre esos dos extremos aludidos. Scott Kim, diseñador de ordenadores personales, decía que no existe diferencia fundamental entre la programación de computadores y la utilización del propio computador. El significado de sus palabras aplicado al ejemplo de las capas concéntricas, indica que esas capas son finas y continuas y se extienden desde el microcódigo encastrado en el firmware hasta el menú de comandos situados más al exterior, en la parte periférica, como ocurre en la máquina expendedora de moneda. El software está situado en algún lugar en medio de las capas extremas. Otros, sin embargo, no opinan así. La gente encargada del desarrollo de complejos sistemas de software comentan con frecuencia que su trabajo tiene poco que ver con la programación de computadores que se enseña en las escuelas. Y lo que es aún peor; esa enseñanza, utilizando ejemplos demasiado simples, produ- Primeros tiempos software.qxp 27/05/2009 10:26 PÆgina 53 Los primeros tiempos del software (parte I) El ingeniero estadounidense Howard H. Aitken nació en Hoboken, Nueva Jersey, el 9 de marzo de 1900. Sus primeros estudios superiores los cursa en la Universidad de WiscosinMadison, obteniendo más tarde, en 1939, su grado de doctor en Harvard, donde fue profesor de Física. Fue el alma del diseño de una calculadora electromecánica que le facilitara la solución numérica de ciertas ecuaciones diferenciales que había encontrado durante sus investigaciones. Se la bautizó, en principio, con el nombre de Automatic Sequence Controlled CalculatorASCC, conocida más tarde como Harvard Mark I. Para su construcción se basó en la máquina de Babbage y en la utilización de tarjetas perforadas. El proyecto de la máquina finalizó en 1944 cuando se contó con la ayuda financiera de IBM y la colaboración como programadora de Grace Hopper. Aunque los primeros trabajos se habían llevado a cabo con fondos de la Universidad de Harvard, se hicieron necesarias otras subvenciones para acabar el proyecto y éstas fueron efectivas cuando Aitken entró en contacto con Thomas Watson, presidente de IBM, y éste aceptó la financiación. Aitken aprovechó la experiencia de expertos de IBM trabajando, en particular, con tres de sus más importantes ingenieros: Durface, Hamilton y Lake. En enero de 1943 el proyecto de Aitken se hace realidad. La máquina electromecánica se había terminado de construir en los laboratorios que IBM tenía en Endicott, donde se hicieron las primeras pruebas de funcionamiento. Pasó luego a Harvard, dándose a conocer en 1944. Fue la primera calculadora terminada, fiable y operativa. Sus dimensiones eran extraordinarias: 15 metros de largo y 2,5 de ancho; su peso era de unas 5 toneladas. Empleaba relés electromecánicos. Su rendimiento: sumas en menos de un segundo, 6 segundos para la multiplicación y 12 para la división. Aitken continuó trabajando en el diseño de máquinas más avanzadas que la Mark I. Siguieron la Harvard Mark II, la Mark III y la Mark IV, calculadora, esta última, ya completamente electrónica y con una memoria de núcleos de ferrita. Aitken fue galardonado en 1970 con la Medalla Edison que concede la IEEE por una meritoria carrera de contribuciones pioneras al desarrollo y aplicación de los computadores digitales, así como por su contribución a la enseñanza y formación en ese mismo campo. Aitken, como sucedió con Grace Hopper, también fue oficial pero, en su caso, de la Reserva Naval de los Estados Unidos. Falleció el 14 de marzo de 1973, en San Luis, Misuri. ce en los estudiantes la falsa sensación de que la producción del software es mucho más simple de lo que en realidad es. El desarrollo de un software de calidad no se reduce a la escritura de buenos programas individuales. Consiste en escribir un conjunto de programas capaces de interactuar entre ellos y con todos en su conjunto, dando lugar a un sistema complejo que funcione. De eso se ocupa precisamente la ingeniería del software: diseñar, producir y sintonizar. La historia del software no debería tratarse de forma separada de la historia del hardware. Muchos ejemplos demuestran que se han dado innovaciones en el software que han tenido poco o ningún impacto hasta que no han podido combinarse con las correspondientes innovaciones del hardware habidas en el tiempo. De la misma forma, el comentario tantas veces repetido de que el progreso del hardware medido, por ejemplo, por el número de circuitos contenidos en un chip de silicio deja muy atrás el progreso del software, probablemente es falsa. Por supuesto debe reconocerse que la tecnología del hardware tiene que superar en ocasiones los propios límites de la física, límites que contribuyen a que el diseño en esa tecnología sea con frecuencia muy complejo. Algunos conceptos relacionados con el software Software. Conjunto de programas que un computador necesita y utiliza para realizar su trabajo. Es un término genérico con el que se indican los componentes intangibles, no físicos, de un sistema de computación. Se refiere, por tanto, a los programas ejecutados por el computador a diferencia de los componentes físicos del mismo. Es necesario hacer una distinción entre el software de sistemas y el software de aplicaciones. Software de sistemas. También conocido como software del sistema, es un tipo de software ligado al hardware para proporcionar así un sistema de computación total y efectivo, dando lugar de esa manera a un sistema aceptable y funcional para el usuario final. Normalmente es suministrado por el propio fabricante del computador. En este tipo de software se incluyen el sistema operativo, 53 Primeros tiempos software.qxp 26/05/2009 14:44 PÆgina 54 ACTA Los primeros tiempos del software (parte I) los compiladores, los intérpretes, programas de servicio, programas de gestión de ficheros, etc. Software de aplicaciones. También conocido como programas de aplicación. Se refiere a un software específico con el que se lleva a cabo una tarea determinada dentro de una organización dada. Por ejemplo, el programa de nómina, el de gestión de cuentas corrientes, el de diseño de carreteras, etc. Con este software se lleva a cabo un trabajo para un usuario concreto y se escribe específicamente para él. Ingeniería del software. Conjunto de actividades encaminadas al diseño, desarrollo, puesta a punto y verificación del software. Se incluyen en esta tarea general los requerimientos del usuario y del propio software, el diseño detallado de la arquitectura del producto, el desarrollo de programas empleando, por ejemplo, técnicas de programación estructurada, la validación del producto, el análisis de rendimientos, etc. Todo ello encaminado a producir programas eficientes y confiables. Programa. Conjunto de instrucciones y de datos que utilizan esas instrucciones y que el ordenador se encarga de ejecutar secuencialmente para llevar a cabo una determinada tarea. Para poder ejecutar un programa éste tiene que almacenarse previamente en la memoria principal del computador. Instrucción. Elemento básico de un programa de ordenador que especifica, entre otras cosas, la operación a realizar, dónde se encuentran los datos con los que operar y dónde se almacenará el resultado de la operación. Sentencia. Unidad básica de un programa de ordenador escrito mediante un lenguaje fuente como Fortran, PL/1, COBOL, etc. Una sentencia se compone de palabras clave, constantes, operadores simbólicos y nombres de variables. Una sentencia da lugar a varias instrucciones de máquina cuando es compilada. Compilador. Programa particular del software del sistema que traduce un programa de aplicación escrito en un lenguaje de alto nivel, como C o Fortran, a código de máquina. Por eso se dice que los lenguajes de alto nivel se compilan completos antes de ejecutarlos. El usuario escribe un programa fuente en un cierto lenguaje y el compilador produce un programa objeto en lenguaje de máquina como resultado de la compilación. Sólo el programa objeto es ejecutable. 54 Ensamblador. Programa traductor que toma un programa fuente escrito en lenguaje ensamblador y produce un programa objeto en lenguaje de máquina. Un lenguaje ensamblador es un lenguaje de bajo nivel cuyas sentencias son similares, en forma, a las instrucciones del ordenador. La diferencia es que el lenguaje ensamblador emplea mnemónicos para indicar los códigos de operación, para las direcciones donde se ubican datos y resultados, etc., en lugar de números en binario que son los utilizados por el propio lenguaje de la máquina. Dado que cada ordenador tiene su propio código de máquina dependiente de su hardware, los lenguajes ensambladores son diferentes de una máquina a otra de marca diferente, incluso entre modelos de una misma marca. Lenguaje de bajo nivel. Lenguaje cercano a la máquina. Dispone de un conjunto de instrucciones fuente idéntico al que posee el computador y que, por tanto, éste es capaz de ejecutar directamente. Intérprete. Programa particular del software del sistema que traduce un programa de aplicación escrito en un lenguaje de alto nivel capaz de ser interpretado, como APL o algunos Basic, a código de máquina. La diferencia con un compilador es que el intérprete traduce (interpreta) cada sentencia y luego la ejecuta procediendo así hasta alcanzar el final del programa. à Los comienzos (1944-1951) Para poder programar la máquina electromecánica Harvard Mark I, los usuarios perforaban, por cada instrucción, una serie de orificios alineados (hasta 24 por línea) sobre una cinta de papel. En el verano de 1944, año en que la máquina fue dada a conocer públicamente, la Marina de los Estados Unidos ordenó a Grace Murray Hopper, que era una oficial de la Navy trabajando en el Computation Lab, Laboratorio de Computación, ayudar a Howard Aitken en la programación del Mark I. Grace había sido profesora de matemáticas en el Vassar College y decidió abandonar ese empleo para trasladarse a la escuela de guardiamarinas Midshipmen School, donde quedó matriculada. Grace tenía ya varios galones en la bocamanga de su uniforme cuando se vio por vez primera con Aitken y contaba así el encuentro: Aitken me mostró, blandiéndolo en su mano, un objeto ancho con tres cintas y me dijo: esto es una compu- Primeros tiempos software.qxp 26/05/2009 14:44 PÆgina 55 Los primeros tiempos del software (parte I) tadora. Yo dije, sí, señor. ¿Qué otra cosa podía decir? Me añadió que le gustaría que yo calculara los coeficientes de la serie del arco tangente para el jueves siguiente. De nuevo, ¿qué podría contestarle? Sí, señor. No sabía realmente lo que estaba pasando pero así fue mi encuentro con Howard Hathaway Aitken. tecleadas en un gran tablero a modo de máquina de escribir y empleando una notación matemática ordinaria, siendo después traducidas a un código numérico que el Mark III ya era capaz de ejecutar. Esos códigos se grababan en una cinta magnética, se leían a continuación por la computadora y después se ejecutaban. Añadir que las secuencias utilizadas con más frecuencia se almacenaban en un tambor magnético para no tener que repetirlas. Es la misma idea que tuvo Konrad Zuse en Alemania empleando cintas de papel para introducir la secuencia de comandos en su máquina Z4. Harvard Mark I/IBM ASCC. Este relato marca el comienzo de la programación de computadores en los Estados Unidos. Grace escribió la secuencia de códigos para la serie pedida y más tarde también para expresiones matemáticas mucho más complicadas, entre ellas, formulaciones físicas para el diseño de lentes. Las secuencias de código que se empleaban con gran frecuencia acabaron siendo cableadas dentro de los circuitos del Mark I, aunque ello no presentaba demasiada flexibilidad. Pero no debemos olvidar que ese computador no tenía el programa almacenado, por lo que Grace tuvo necesariamente que desarrollar otras secuencias de instrucciones de menos uso en sendas cintas de papel. Muy pronto se dio cuenta de que de existir una manera de reutilizar las cintas ya codificadas para otro problema, se ahorrarían muchas horas de trabajo. Eso no lo permitía la máquina en cuestión de una forma sencilla pero la idea tomó raíces y progresó de manera que posteriores modificaciones permitieron que se montaran carretes de cintas conectadas a la máquina. Perforadora de cinta de papel. Por ello, en un diseño posterior de la computadora, el Mark III, Aitken desarrolló un dispositivo encargado de recibir las instrucciones del programador, Grace Murray Hopper. Ninguna de las dos máquinas citadas eran capaces de almacenar los programas en su memoria interna, elemento que hoy conocemos como memoria principal; pero de estos diseños primitivos nació la idea de conseguir una computadora capaz de almacenar ella misma los programas y los datos con los que debían ejecutarse esos programas. Se estaba apuntando a la máquina de programa almacenado. En este sentido, tanto la realidad de Grace Hopper preparando cintas capaces de utilizarse más de una vez como la de Rutishauser, que operaba en el Instituto Técnico Federal de Zürich con la Z4 en 1952, que consideraba que la misma calculadora capaz de resolver un problema debía ser la que preparase sus propias instrucciones, constituyeron el momento crítico del nacimiento del software. Con la aparición del computador de programa almacenado, cualquier secuencia de instrucciones que se necesitara más de una vez, se almacenaba en una cinta de papel. Cuando un problema determinado requería esa secuencia, el computador leía la cinta, almacenaba en memoria interna dicha secuencia y la insertaba en el lugar apropiado del programa general o programa principal. Con este sistema, el programador podía escribir programas cada vez más complejos y sofisticados sin tener que rescribir secuencias de instrucciones en binario ya escritas por él o por otros pro- 55 Primeros tiempos software.qxp 26/05/2009 14:44 PÆgina 56 ACTA Los primeros tiempos del software (parte I) gramadores: nacía así la biblioteca de rutinas, donde podían encontrarse los códigos más usuales. Uno de los primeros computadores de programa almacenado, el EDSAC, en Cambridge, Inglaterra, hacía uso de esta filosofía: poseía una amplia biblioteca de secuencias (hoy las llamamos subrutinas) escritas de antemano, desarrolladas, verificadas y perforadas en cintas de papel que permitían al programador incorporarlas a sus propios programas. Actualmente, esta mecánica recibe el nombre de llamada a una subrutina, y se lleva a cabo mediante una sentencia CALL que contiene el nombre de la secuencia de código que se necesita (a la que se llama). à Los compiladores UNIVAC (1952) Decimos compilar para traducir el verbo inglés to compile. Uno de los primeros significados que encontramos para esta palabra es: reunir información proveniente de lugares distintos y colocarla en un libro, en un informe o en una lista; poner todo junto (Cambridge, International Dictionary of English). Pero ¿de dónde hemos heredado la palabra compilar y cuándo la empleamos en cuestiones informáticas? Tal como hemos dicho más arriba, las secuencias de código se perforaban, primero en cintas de papel, luego en bloques de fichas de cartulina. De esa manera, un programa podía prepararse seleccionando los bloques de fichas apropiados en los que se habían escrito, perforado, los códigos provisionales, los códigos de transición (el programa fuente). Luego se agrupaba el resultado en un nuevo bloque de fichas. Esa actividad recibió el nombre de compilar. A principios de los cincuenta, los usuarios de ordenadores desarrollaron programas que aligeraron al computador en estas tareas, y esos programas recibieron el nombre de compiladores: había nacido el software de sistemas. Precisamente, fue Grace Hopper quien jugó un papel crucial, no sólo en el desarrollo de esos compiladores, sino también en la transmisión del concepto desde el laboratorio de la Universidad de Harvard al mundo comercial. El término compilador fue definido por Hopper como una rutina constructora de programas capaz de generar un programa determinado con el objeto de resolver un problema específico. Hoy día recibe el nombre de compilador aquel programa que traduce las instrucciones escritas en un lenguaje familiar para el usuario de ordenadores a un código binario que el computador puede ejecutar posteriormente. Evidentemente este concepto no coincide con el que tenía Hopper. Para ella, como se ha dicho, un compilador tomaba y utilizaba subrutinas almacenadas en una 56 Tarjeta perforada de 90 columnas tipo IBM. biblioteca. Entonces, y siguiendo la definición de Grace, el modo como trabajaba un compilador era el de un programa que copiaba el código contenido en una subrutina en el lugar adecuado de un programa principal, exactamente donde el programador sabía que tenía que estar. Esas subrutinas tenían un alcance limitado y solían estar restringidas a cálculos clásicos como el del seno, el coseno, logaritmos y, sobre todo, a operaciones aritméticas en coma flotante de cantidades expresadas en lo que hoy conocemos como notación científica. No obstante, los compiladores eran piezas de software muy complejas. Copiar una rutina como, por ejemplo, la del cálculo del seno de un argumento, requería especificar la localización del valor de ese argumento, así como la localización donde debería estar ubicado el resultado del cálculo, lugar que era diferente para cada ejecución del programa principal que se sirviera de tal subrutina. Por todo lo dicho, resulta inapropiado utilizar, como se hace alguna vez, la palabra ensamblar en lugar de compilar, para significar la construcción de un programa a base de bloques de subrutinas. La compilación integraba subrutinas en un flujo continuo de instrucciones. Como se ha dicho, Grace era oficial de la Marina, dedicándose a la computación en ese cuerpo; pero en cierto momento fue persuadida por Jonh Mauchly para que dejara su empleo y colaborara con él en su trabajo de programación de la nueva máquina UNIVAC, Universal Automatic Computer, que se estaba construyendo en aquel entonces. Grace Hopper aceptó, pero sus sentimientos de fuerte vinculación con la Marina (su bisabuelo también había pertenecido al mismo cuerpo) le hicieron regresar pronto, llegando a alcanzar el grado de contralmirante cuando llegó su retiro definitivo. Hopper dio el nombre de programación automática (automatic programming) a la actividad de diseñar y utilizar los compiladores. Produjo el compilador A-0 para el UNIVAC en 1952 y más tarde, en 1953, el A-1 y el A-2. Volveremos a referirnos a ella. Primeros tiempos software.qxp 26/05/2009 14:44 PÆgina 57 Los primeros tiempos del software (parte I) à El sistema Whirlwind de Laning y Zierler (1954) El primer sistema de programación que trabajaba como un compilador moderno fue desarrollado a principio de los años cincuenta en el Instituto de Tecnología de Massachussets, MIT. La autoría se debió a H. Laning y N. Zierler (le llamaron indistintamente programa traductor o programa interpretativo), y se trataba de un sistema para una computadora conocida con el nombre de Whirlwind del citado instituto. Nunca se le dio nombre a tal sistema pero fue descrito en un manual titulado A Program for Translation of Mathematical Equations for Whirlwind I; es decir, se trataba de un sistema otra vez relacionado con las matemáticas; esta vez, con la resolución de ecuaciones. John Backus lo calificó como un elegante concepto llevado a cabo elegantemente. A diferencia de los compiladores UNIVAC, la filosofía de este sistema estaba mucho más cerca de las tendencias informáticas modernas. En concreto, tomaba como input los comandos del usuario y generaba como output, como salida, un código de máquina equivalente que no solamente era capaz de ejecutar los comandos originales sino también hacía un seguimiento de las posiciones de memoria utilizadas, manejaba bucles repetitivos, así como otras tareas. Los comandos de este sistema algebraico de Laning y Zierler se escribían utilizando una sintaxis análoga a la empleada por el álgebra; se traducían luego al código de la máquina Whirlwind con lo que ésta podía ya ejecutarlos. El sistema realmente no fue, aunque pudiera parecerlo, un lenguaje de programación de propósito general, sino más bien un medio para resolver únicamente ecuaciones algebraicas. Por lo tanto, no presentaba ninguna utilidad para todos aquellos usuarios del sistema UNIVAC que estaban interesados en solucionar aplicaciones de gestión y de negocio. Por ello, Backus, después de sus piropos iniciales para el sistema, fue luego más realista al decir que, a pesar de la publicidad que se hizo del mismo, fue totalmente ignorado. Hemos leído que la razón que daba Backus para esa ignorancia del producto en el mercado fue que el sistema amenazaba lo que él denominaba el sacerdocio de los programadores: poseían un perverso orgullo motivado por su habilidad para trabajar en código de máquina utilizando siempre técnicas y trucos que otros no podían descubrir. Donald Knuth, que había examinado y analizado en 1980 varios sistemas de programación, veía otra razón: el sistema era diez veces más lento que otros sistemas de codificación aparecidos para Whirlwind. à Ensambladores Estos sistemas llegaron a conocerse como lenguajes de programación. La aparición de este término se debe a que tenían algunos atributos comunes con los lenguajes naturales con los que se expresa el hombre como, por ejemplo, algunas reglas sintácticas para su construcción. La historia del desarrollo del software ha recorrido su camino, en muchas ocasiones, paralelamente a la historia de los lenguajes de programación de alto nivel. Entendemos por este tipo de lenguajes, aquellos que generan código de máquina (en binario) a partir de códigos cercanos al álgebra o cercanos a la forma en que se describe un proceso. Ahora bien, es necesario añadir que aunque los lenguajes de alto nivel se hicieron imprescindibles, la programación en muchas instalaciones continuó haciéndose a niveles mucho más bajos de programación y, por tanto, más cercanos a la máquina, incluso bien entrada la década de los sesenta. Aunque se denominaban lenguajes, la verdad es que estos códigos de bajo nivel generaban realmente una sola instrucción de máquina (o como mucho algunas pocas) por cada instrucción original o fuente escrita por el programador. Después, cada uno de los códigos fuente se traducía, en una correspondencia uno-auno, al código binario correspondiente que el computador ejecutaba ya directamente. Debido a todas estas acciones, se decía (y actualmente también) que tales programas se ensamblaban pero no que se compilaban y el programa encargado de ese ensamblaje recibió el nombre de programa ensamblador. Veamos un ejemplo de la sintaxis de una instrucción, la suma, escrita en un lenguaje ensamblador. INSTRUCCIONES PARA SUMAR DOS CANTIDADES X + Y = Z L R1 , X A R1 , Y ST R1 , Z La primera instrucción se indica con el mnemónico L, de LOAD, cargar. Traslada el contenido de la posición de memoria que el programador ha llamado X, y que es precisamente donde está el primer sumando, al registro del procesador R1. La segunda instrucción A, de ADD, suma el contenido que ya tenía el registro R1 con el segundo dato que se encuentra en la posición de la 57 Primeros tiempos software.qxp 26/05/2009 14:44 PÆgina 58 ACTA Los primeros tiempos del software (parte I) memoria principal, conocida mnemónicamente como Y. El resultado de la suma queda temporalmente en R1. Por último, se lleva el resultado de la suma desde R1 a una posición de memoria fuera del registro del procesador, concretamente a la posición simbólica Z. Para ello se ha empleado la instrucción ST, STORE, almacenar. En Z quedará, como hemos dicho, la suma de las dos cantidades X e Y. Puede verse que se emplean mnemónicos no sólo para indicar códigos de operación, sino también para designar simbólicamente las posiciones de memoria o los registros donde se ejecutan las operaciones. Aparecieron ampliaciones a esa correspondencia uno-a-uno que dieron lugar a lo que actualmente se denomina macro. Se trataba de instrucciones fuente únicas pero que generaban más de una instrucción de máquina. Muchas instalaciones comerciales recientes mantuvieron extensas bibliotecas de macros para realizar, por ejemplo, operaciones como la clasificación de datos o la intercalación de unos con otros. Una de las tareas importantes del ensamblador era, y lo es actualmente, distribuir la memoria total de la máquina a la vista de todos los símbolos de las variables que forman el programa, así como mantener un control de la memoria durante la ejecución de dicho programa. Tabuladora IBM-407. Es importante mencionar aquí que un grupo de usuarios de máquinas IBM en Estados Unidos, SHARE, grupo del que hablaremos a continuación, fue quien se encargó de diseñar y desarrollar un 58 ensamblador para la máquina IBM 704. Ese leguaje, con las consiguientes variaciones y mejoras, llegó hasta los tiempos en que apareció en el mercado la tercera generación de ordenadores con la máquina System/360 de la compañía IBM. Los ensambladores siguen siendo programas vitales para los programadores. à Grupos de usuarios SHARE, GUIDE y GSE Es curioso observar que mientras los fabricantes y suministradores de computadores estaban muy interesados en el desarrollo de lenguajes de alto nivel para sus máquinas, la corriente de las aún pequeñas comunidades de usuarios caminaba por otras sendas. En 1955, varios usuarios de la máquina IBM 701, ubicados en el área de Los Ángeles, pasaron a utilizar una nueva máquina, migraron a la IBM 704, que ofrecía mejores rendimientos y más capacidades, y todos ellos se agruparon con el fin de compartir experiencias, considerando que ello sería mejor que trabajar sin relación alguna. En agosto de 1955 mantuvieron el primer encuentro en la sede de RAND Corporation (era un lugar neutral), en Santa Mónica. A esa reunión acudieron representantes de compañías tan importantes como la North America Aviation y la Lockheed. El grupo se llamó SHARE (compartir), grupo con un crecimiento rápido y que muy pronto comenzó a desarrollar bibliotecas de rutinas variadas; entre otras, rutinas orientadas al álgebra de matrices. Cada miembro del grupo podía utilizar los desarrollos de los demás. Esquema en papel mostrando el panel cableado de una tabuladora de IBM. IBM, que había comenzado el patrocinio de los usuarios de sus equipos de tabulación, las tabulado- Primeros tiempos software.qxp 26/05/2009 14:44 PÆgina 59 Los primeros tiempos del software (parte I) ras de programa cableado en un panel, amplió ese soporte, y aún sigue haciéndolo, al grupo SHARE, que adquiría otro tipo de máquinas, sus computadores de programa almacenado. Sin duda alguna, la creación del grupo fue una verdadera bendición para IBM; en el grupo estaban todos los usuarios de los grandes ordenadores de aquel entonces. En un solo año, la asociación llegó a tener 62 miembros y se considera que la propia asociación ayudó a IBM a vender su ordenador 704. SHARE influía, y mucho, con su opinión en las estrategias y futuras direcciones de IBM. De modo que SHARE se sentaba a la mesa con IBM para ayudar a tomar decisiones sobre los futuros programas de producción, tanto de software como de hardware. Mucho más tarde, y a imitación de SHARE, nacieron otras asociaciones de usuarios. La de minis de Digital Equipment se llamó DECUS y en Europa, COMMON, reúne a los usuarios de minis de IBM. Pero volviendo a SHARE, hemos de señalar la aparición que de la misma se produjo en otros continentes. En lo referente a Europa, hemos vivido su historia y su actuación desde el año 1962, primero como usuario de IBM y más tarde desde el mismo seno de la compañía. En Europa agrupaba a los usuarios técnico-científicos, universidades, laboratorios de investigación, desarrollo y producción. A la sombra de SHARE apareció en Europa otra asociación: GUIDE. Agrupaba a usuarios de otro tipo: los de los grandes centros de cálculo de empresas de gestión, comerciales y entidades financieras. Ambas asociaciones se fundieron en una sola en 1995, mediante un acuerdo firmado entre los presidentes de SHARE y GUIDE, en Viena, con el reconocimiento de IBM. La fusión pasó a denominarse GSE, GUIDE SHARE EUROPE, asociación que, con más de 4.000 asociados actualmente, aún permanece y que se ha establecido en casi todos los países de Europa donde IBM tiene mercado. GSE mantiene estrechas relaciones e intercambios con SHARE de Estados Unidos. Finalizar diciendo que nos sentimos muy honrados al haber sido elegido para presidir actualmente las Regiones de España y Portugal en el seno de GSE. à La clasificación e intercalación de datos Las primeras instalaciones, tanto comerciales como científicas, tuvieron que enfrentarse a una tarea que era muy común y que estaba íntimamente ligada al hardware, como era el manejo de conjuntos de datos denominados ficheros. Estos ficheros estaban formados por registros almacenados secuencialmente en memorias externas, normalmente en carretes de cintas magnéticas, que ofrecían grandes ventajas frente a la utilización común de las tarjetas perforadas, aunque la técnica de almacenamiento fuera la misma: registro tras registro en secuencia. Pero para utilizar esos datos era necesario clasificarlos primero en un cierto orden, alfabético, numérico, ascendente, descendente. Con ello, y después de esa operación, era sencillo encontrar un dato concreto en un fichero. La clasificación de datos, ya fuera numérica o alfabética, dominó la computación, sobre todo la de tipo comercial, desde los primeros años. En 1973 se estimó que ocupaba un 25% del tiempo total del ordenador. Se daba con frecuencia la situación de tener que clasificar un gran fichero sólo para encontrar un par de registros en el mismo, lo que suponía un alto coste de tiempo del ordenador. Los analistas de sistemas trataron de minimizar este tipo de situaciones, aunque no pudieron evitarlo completamente. La programación tenía que sincronizarse con la propia clasificación, ya que las tareas comunes en una compañía consistían en un proceso de los datos, una actualización de los ficheros y en la impresión de los correspondientes informes de salida. Y entre las operaciones de proceso estaban embebidas las operaciones de clasificación de registros y de resultados impresos de acuerdo con una determinada clave, tareas que se llevaban a cabo mediante programas de clasificación ad hoc. Los resultados en papel se encuadernaban y, a partir de esos legajos, era posible tener acceso a los datos corporativos de la empresa. Por ejemplo, si un cliente de una compañía de seguros deseaba conocer el estado de su póliza, el empleado de esa compañía entraba en el listado correspondiente clasificado por número de cliente, y accedía así a la información del peticionario. Todo esto nos indica que la clasificación e intercalación de unos registros con otros dentro de un mismo fichero se presentó en los principios del procesamiento como algo inevitable y dominante. Sólo cuando aparecieron en el mercado los discos magnéticos como memoria externa del computador, los tiempos de búsqueda en ficheros se acortaron drásticamente, ya que con este soporte de hardware, la búsqueda de un registro podía hacerse al azar, es decir, de forma directa sin tener que recorrer todo el fichero hasta llegar al registro requerido. Cuando los métodos de acceso al disco fueron madurando, la clasificación fue perdiendo protagonismo, aunque realmente esta operación no desapareció hasta bien llegado el final de la década de los sesenta. 59 Primeros tiempos software.qxp 26/05/2009 14:44 PÆgina 60 ACTA Los primeros tiempos del software (parte I) Es curioso mencionar aquí a John von Newman: se encargó de evaluar el diseño de la máquina EDVAC de acuerdo con las posibilidades que presentaba para clasificar los datos. Este fue su razonamiento: si la EDVAC podía clasificar tan bien como lo hacían las máquinas clasificadoras mecánicas, aquella debería considerarse como una máquina de propósito general. Un programa de clasificación mecanografiado en 1945 por Von Newman en su máquina de escribir y que más tarde fue procesado por la EDVAC, fue probablemente el primer programa existente de clasificación preparado para un computador de programa almacenado. Lo mismo ocurrió con Eckert y Mauchly cuando comenzaron a construir el UNIVAC. Entre sus tareas estaba el desarrollo de un software para la clasificación e intercalación de datos. Esto no lo hicieron solos; colaboró con ellos Frances Betty Holberton, una de las personas que habían abandonado el proyecto ENIAC y que había marchado con Eckert a la Eckert-Mauchly Corporation. Betty tuvo allí la responsabilidad del desarrollo del software para el UNIVAC. Hemos dicho desarrollo del software. En aquellos tiempos no se conocía esa tarea por el nombre que le hemos dado; era más bien y simplemente un tipo de programación. En 1952 apareció como resultado de los trabajos de Betty uno de los primeros productos debido a su colaboración. Se trataba de una rutina encargada de leer y clasificar los datos almacenados en las cintas del UNIVAC. Donald Knuth dijo del producto que era la primera rutina importante del software para la programación automática que nunca antes se había desarrollado. Las técnicas desarrolladas por Holberton para aquella programación incipiente sirvieron de patrón en el mundo de la computación durante muchos años. Es importante notar el hecho de que las cintas albergaban más datos que los que podían almacenarse en la memoria. Téngase en cuenta que el computador no puede procesar información alguna que antes no se haya almacenado en esa memoria principal. Por lo tanto, las rutinas debían leer la información de las cintas contenida en un pequeño bloque de registros, llevarlo a la memoria, clasificarlo internamente y volver a grabar en la cinta el bloque ya clasificado y así sucesivamente con el resto de los bloques de la cinta magnética. Para poder realizar las operaciones anteriores era necesario utilizar simultáneamente dos carretes de cintas que eran leídas hacía adelante y hacia atrás. 60 Donald Knuth. Para finalizar, añadir que las rutinas de software desarrolladas en UNIVAC por Holberton y su equipo constituyeron verdaderas piezas maestras, cada una de ellas de un contenido con un alto grado de complejidad. Incluso ella misma reconoció este hecho cuando comentaba que se hacía necesario disponer de rutinas más sencillas que no dieran lugar a ese uso masivo de operaciones de clasificación. Pero habría que esperar a que determinados recursos físicos de los sistemas de computación, particularmente las memorias, tuvieran una mayor capacidad y su tecnología de fabricación las abaratara; debería pasarse de la memoria de núcleos de ferrita, que era la utilizada, a la de transistores. Y eso aún tardaría en llegar algunos años. De todas formas, con la aparición de los discos magnéticos mencionados anteriormente, los problemas de tiempo se aliviaron mucho. Apareció el concepto de listas encadenadas y, como consecuencia, las correspondientes técnicas mediante las cuales cada registro de una lista contenía información del siguiente (o anterior) registro. Con ello la clasificación fue perdiendo su importancia. Para finalizar esta parte queremos añadir unas frases de Knuth que adornan de mérito todos los desarrollos habidos en el área del software: Siempre me he dado cuenta de que la tarea de escribir un software es mucho más difícil que cualquier otra cosa que yo haya hecho en mi vida. Tenía que retener muchas cosas en mi cabeza al mismo tiempo. Y esto lo dijo Donald Knuth, que fue uno de los mejores implantadores de reglas para la construcción del software y uno de los más grandes programadores de todos los tiempos, como ya se ha advertido. à La aparición de dos lenguajes clave El uso de la palabra inglesa language podría resultar arriesgado en informática ya que implica mucho Primeros tiempos software.qxp 26/05/2009 14:44 PÆgina 61 Los primeros tiempos del software (parte I) más de lo que los primeros usuarios e inventores de la misma pensaron. Se deriva del francés langue, lengua, lo que implica que es hablado. Pero los lenguajes de programación no se hablan, como los lenguajes naturales, sino que se escriben de acuerdo con unas determinadas reglas sintácticas muy precisas. Lo que vamos a describir a continuación tiene mucho que ver con esa noción de lenguaje de programación que vamos a comenzar definiendo. Un algoritmo es una secuencia de operaciones que se ejecutan sobre un conjunto inicial de objetos para producir un conjunto final de otros objetos diferentes. Un lenguaje de programación es un conjunto de convenciones para escribir algoritmos. Un algoritmo expresado en un lenguaje de programación es un programa. Nos referiremos ahora a dos puntas de lanza dentro de esos lenguajes de programación pero de alto nivel cuyos respetivos diseños se llevaron a cabo bien entrada la década de los cincuenta: FORTRAN y COBOL fueron sus nombres. El primero orientado a las aplicaciones matemáticas y, como consecuencia, a las técnico-científicas, y el segundo a las aplicaciones de gestión. FORTRAN nació, como se ha señalado, en IBM, y la iniciativa de COBOL se produjo en el Departamento de Defensa de los Estados Unidos. En una publicación actual de la ACM, Fortran Forum, en su número de diciembre de 2006 se recogía el siguiente comentario: En 1954, un equipo de IBM liderado por John Backus comenzó a trabajar en el primer lenguaje de programación de alto nivel, FORTRAN, lo que fue anunciado a la comunidad del mundo de la computación en la conferencia Western Joint Computer Conference que tuvo lugar en los Ángeles, California, en febrero de 1957. A mediados de abril del mismo año aparece el primer documento sobre el compilador FORTRAN, compilador construido y adaptado para la máquina IBM 704. FORTRAN, escrito con mayúsculas hasta hace pocos años, significa Formula Translation, es decir, Traducción de fórmulas. Su nombre le viene del hecho de que su sintaxis (símbolos y reglas) era, y es, similar a la del álgebra matemática. Fortran, escrito con minúsculas como se hace ya en la actualidad, causó un gran éxito en la comunidad de usuarios de IBM desde su comienzo y tal lenguaje, que aún hoy día se mantiene vivo y es ampliamente utilizado, como se ha dicho, sobre todo en el procesamiento paralelo y en la supercomputación, ha sido a lo largo de los años modificado, ampliado y estandarizado en todas las sucesivas versiones que han ido apareciendo. Peter B. Sheridan, proyecto Fortran. El 10 de noviembre de 1954, IBM publica a través de su grupo de investigación para la programación un primer informe titulado PRELIMINARY REPORT, Specifications for the IBM Mathematical Formula Translating System, FORTRAN, en el que se anunciaban los objetivos de tal lenguaje: El sistema de Traducción de Fórmulas Matemáticas de IBM, o brevemente FORTRAN, comprenderá un amplio conjunto de programas capaces de aceptar en el IBM-704 la formulación concisa de un problema basada en la notación matemática y de producir automáticamente un programa 704 de alta velocidad encaminado a la solución del problema. Del comité encargado del proyecto, de su estudio, diseño y desarrollo encabezado por John W. Backus, ya hablamos en las primeras líneas de este artículo. Irving Ziller, proyecto Fortran. ¿Cuáles fueron las razones del éxito de este lenguaje? En primer lugar, su adaptación al lenguaje natural de las matemáticas constituía una sintonía casi perfecta, con la utilización casi de los mismos símbolos de operación y la posibilidad del empleo de exponentes y subíndices. Los científicos y los ingenieros lo encontraron totalmente familiar. En segundo lugar, IBM tuvo el acierto de editar unos manuales muy concisos, claros y de fácil comprensión destinados a aprender el lenguaje y 61 Primeros tiempos software.qxp 26/05/2009 14:44 PÆgina 62 ACTA Los primeros tiempos del software (parte I) 62 producir con él los primeros programas. El sistema FORTRAN (lenguaje fuente y compilador) era un sistema mucho más rápido que el desarrollado por Laning y Zierler: se escribían los programas fuente en pocas horas y éstos producían unos programas de máquina que se ejecutaban en menos tiempo. Por supuesto que la eficiencia de los códigos objeto era muy sobresaliente y superaba a los códigos máquina escritos por programadores directamente en ese lenguaje a nivel de máquina. Backus y su equipo dotaron al lenguaje con el uso de la aritmética de coma flotante de una forma rápida y eficiente. Este tipo de aritmética es vital para las aplicaciones tanto técnicas como científicas. Por último, y esto ha sido criticado siempre por muchos programadores de alto nivel (pero desconocedores de la ingeniería y sus aplicaciones), el sistema Fortran escondía para el usuario los detalles más internos del hardware de la máquina, lo cual era algo superfluo para ese tipo de usuarios, interesados sobre todo, y sólo, en producir aplicaciones de forma sencilla y rápida, es decir, en concentrarse en la solución de su propio problema. para aplicaciones comerciales, tales como el B-0, también conocido con los nombres de MATH-MATIC o FLOW-MATIC. Así mismo tuvo su influencia en el COBOL un proyecto de IBM llamado Comercial Translator. La compañía Honeywell también desarrolló otro lenguaje comercial, FACT, que en muchos aspectos superaba al COBOL, pero no logró el reconocimiento del gobierno americano. IBM, que ha sido líder del mercado de los ordenadores, también tuvo una posición dominante con el éxito de este lenguaje. Todas las demás marcas anunciaron y pusieron a disposición de sus usuarios el sistema Fortran. Este tipo de sintaxis parecía darle a COBOL la posibilidad de convertirse en un lenguaje autodocumentado. Bastaba con leer sus sentencias para comprender el significado y la finalidad de la aplicación total. La realidad es bastante diferente. Ni los creadores de un programa son capaces, con el paso de los años, de recordar y saber con certeza el significado de lo que escribieron. A Grace Hopper se debe la idea de que en COBOL se pudieran manejar nombres con gran número de caracteres como se hace en un lenguaje natural. Por ejemplo, en Fortran se escribe la sentencia, IF A > B para comparar dos variables y tomar la correspondiente decisión según el resultado de la comparación; en COBOL podía hacerse mediante la sentencia equivalente así: IF HORAS-EMPLEADO IS GREATER THAN MAXIMO El éxito del lenguaje Fortran ocurrió paralelo al desarrollo y aparición en el mundo comercial y de gestión del COBOL, Common Business Oriented Languaje, desarrollado pocos años más tarde y nacido, como ya hemos dicho, en el Departamento de Defensa, que en mayo de 1959 formó un comité para estudiar la posibilidad de desarrollar un lenguaje de programación común para los negocios. El esfuerzo se concentró en la producción de las especificaciones de tal lenguaje, que aparecieron al final del mismo año. Hechas públicas las bases, varios fabricantes procedieron a escribir compiladores para sus propios modelos de máquinas. Al año siguiente, 1960, el gobierno de los Estados Unidos anunció que todos los ordenadores deberían poder procesar aplicaciones escritas en COBOL. Ello llevó a ese lenguaje a ser estandarizado de tal forma que una aplicación escrita en COBOL podía, sin cambios, ser ejecutada en cualquier máquina, cualquiera que fuese su proveedor. La cuestión de si COBOL es un lenguaje bien diseñado y lo suficientemente potente para su campo de aplicaciones, es un debate que ha llegado hasta nuestros días. Fortran Forum, ACM Press, SIGPLAN. Parte de las primeras versiones de COBOL se debieron al trabajo y entusiasmo que Grace Hopper puso en el desarrollo de los primeros compiladores para el UNIVAC. Así, allá por el año cincuenta y seis, Grace ya había desarrollado varios compiladores Fundamental Algorithms, Serie The Art of Computer Programming, Volumen 1, Donald E. Knuth, Addison-Wesley, 1977. Lo mismo que ha pasado con Fortran, también COBOL ha sobrevivido a las distintas generaciones de ordenadores y ha llegado hasta nuestros días. Hemos arribado así hasta la década de los sesenta después de recorrer los hitos del software desde sus primeros tiempos. Enlazaremos en una próxima ocasión con los hechos históricos descritos y los extenderemos en el tiempo más allá de 1960. à Referencias The Programming Language Landscape, Henry Ledgard y Michael Marcotty, SRA Inc, 1981. A History of Modern Computing, P. E. Ceruzzi, The MIT Press, 2003. Lenguajes de Programación, Allen B. Tucker, McGraw-Hill, 1987.