La historia de Mel, un verdadero programador

Esta es una traducción de un artículo enviado a Usenet por Ed Nather (utastro!nather) el 21 de mayo de 1983. Se trata de una historia de los inicios de la informática, como diría Linus Torvalds: “cuando los hombres eran hombres y programaban sus propios drivers.” 🙂 En realidad es todavía anterior a eso.

Es una historia que lleva circulando mucho tiempo por Internet. Sin embargo, solo la he encontrado completa en inglés. En español, lo único que he encontrado es esta página que traduce solo los primeros párrafos, así que he decidido traducirla para hacerla llegar a un mayor número de personas. Se trata de una gloriosa historia que no se puede perder. Espero que la disfrutéis tanto como yo.

Un reciente artículo dedicado al lado “macho” de la programación decía esta simple y clara frase:

Los verdaderos programadores escriben en Fortran.

Puede que lo hagan ahora, en esta decadente era de cerveza light, calculadoras de mano y software fácil de usar, pero en los Buenos Viejos Tiempos, cuando el término “software” sonaba divertido y los Verdaderos Ordenadores estaban hechos de tambores magnéticos y válvulas de vacío, los Verdaderos Programadores escribían en código máquina. Ni Fortran, ni RATFOR, ni siquiera lenguaje ensamblador. Código máquina. Puros, simples e inescrutables números hexadecimales. Directamente.

Para evitar que toda una nueva generación de programadores crezca en la ignorancia de este glorioso pasado, me siento obligado a describir, tan bien como pueda a pesar del salto generacional, cómo escribía código un Verdadero Programador. Le llamaré Mel, porque ese era su nombre.

Conocí a Mel cuando trabajaba para la Royal McBee Computer Corp., una subsidiaria ahora desaparecida de la compañía Royal Typewriter. La firma fabricaba el LGP-30, un ordenador pequeño y barato (para los estándares de la época) con memoria de tambor, y acababa de empezar a fabricar el RPC-4000, un ordenador muy mejorado, mayor, mejor y más rápido, también con memoria de tambor. Cada núcleo costaba demasiado y no iba a durar para siempre, de todos modos. (Por eso no has oído hablar de la compañia, o del ordenador)

Yo había sido contratado para escribir un compilador de Fortran para este nuevo portento y Mel era mi guía hacia sus maravillas. Mel no aprobaba los compiladores.

“Si un programa no puede reescribir su propio código,” preguntaba, “¿de qué sirve?”

Mel había escrito, en hexadecimal, el programa más popular que la compañía poseía. Funcionaba en el LGP-30 y jugaba al blackjack con los clientes potenciales en las ferias de informática. Su efecto siempre era dramático. El pabellón del LGP-30 se montaba en cada show y los vendedores de IBM se quedaban por allí hablando unos con otros. Si esto vendía ordenadores o no, era una cuestión que nunca se discutía.

El trabajo de Mel era reescribir el programa de blackjack para el RPC-4000. (¿Portar? ¿Qué significa eso?) El nuevo ordenador tenía un esquema de direccionamiento de uno a uno, en el cual cada instrucción máquina, además del código de operación y la dirección del operando necesario, tenía una segunda dirección que indicaba en qué lugar del tambor magnético estaba situada la siguiente instrucción. En términos modernos, ¡cada una de las instrucciones iba seguida por un GO TO! Eso se fumaría en pipa al Pascal.

A Mel le encantaba el RPC-4000 porque podía optimizar su código: o sea, colocar instrucciones en el tambor de forma que según una terminaba su trabajo, la siguiente llegaba al cabezal de lectura justo en ese momento y estaba disponible para ejecutarla inmediatamente. Había un programa que hacía eso, un “ensamblador optimizador”, pero Mel se negaba a usarlo.

“Nunca sabes dónde va a poner las cosas”, explicaba, “así que tienes que usar constantes separadas”.

Pasó mucho tiempo antes de que yo entendiera ese comentario. Como Mel conocía el valor numérico de cada código de operación, y asignaba sus propias direcciones en el tambor, cada instrucción que escribía también podía considerarse una constante numérica. Podía tomar una instrucción “add” anterior, digamos, y multiplicarla por algo, si tenía el valor numérico correcto. Su código no era fácil de modificar para nadie más.

Si comparabas los programas optimizados a mano por Mel con el mismo código generado por el ensamblador optimizador, el de Mel siempre funcionaba más rápido. Esto era porque el método “top-down” de diseño de programas no había sido inventado todavía, y Mel no lo hubiera usado de todos modos. Él escribía en primer lugar las partes internas de los bucles de su programa, así que podía escoger antes las direcciones optimas en el tambor. El ensamblador optimizador no era suficientemente inteligente para hacerlo de esa manera.

Mel nunca escribía bucles de retardo, incluso cuando la caprichosa Flexowriter requería un retardo entre caracteres de salida para funcionar bien. Él simplemente colocaba las instrucciones en el tambor de forma que cada sucesiva instrucción se pasaba del cabezal de lectura cuando era necesario. El tambor tenía que dar otra vuelta completa para encontrar la siguiente instrucción. Él acuño un término inolvidable para este procedimiento. A pesar de que “óptimo” es un término absoluto, como “único”, es una práctica verbal común hacerlo relativo: “no tan óptimo” o “menos óptimo” o “no muy óptimo”. Mel llamaba a las direcciones con el máximo retardo las “más pésimas”.

Después de terminar el programa de blackjack y tenerlo funcionando, (“Incluso el inicializador está optimizado”, decía orgulloso) recibió una petición de cambio del departamento de ventas. El programa usaba un elegante (y optimizado) generador de números aleatorios para barajar las “cartas” y repartir el “mazo”, y algunos de los vendedores pensaban que era demasiado justo, ya que a veces los clientes perdían. Querían que Mel modificara el programa de forma que, al tocar un interruptor en la consola, cambiase las probabilidades y dejase ganar al cliente.

Mel se negó. Sentía que eso era eminentemente deshonesto, y lo era, y que afectaba a su integridad personal como programador, y lo hacía, así que se negó a hacerlo. El jefe de ventas habló con Mel, como también hizo el Gran Jefe y, por petición del jefe y algunos compañeros programadores, Mel finalmente se rindió y escribió el código, pero puso la condición al revés y, cuando el interruptor se activaba, el programa hacía trampas y ganaba siempre. Mel estaba encantado con esto. Afirmaba que su subconsciente era incontrolablemente ético, y se negó rotundamente a corregir el fallo.

Después de que Mel dejara la compañía por un mejor sueldo, el Gran Jefe me pidió mirar el código y ver si podía encontrar la condición e invertirla. A regañadientes, accedí a mirarlo. Trazar el código de Mel fue una verdadera aventura.

A menudo he sentido que la programación es una forma de arte, cuyo valor real solo puede ser apreciado por otra persona versada en el mismo arte arcano. Hay auténticas joyas y brillantes ideas ocultas a la vista y admiración humanas, a veces para siempre, por la propia naturaleza del proceso. Puedes aprender un montón de un individuo con solo leer su código, incluso en hexadecimal. Mel era, creo yo, un genio no reconocido.

Quizás mi mayor shock vino cuando encontré un inocente bucle que no tenía condición. Sin condición. Ninguna. El sentido común dice que tendría que ser un bucle infinito, donde el programa diera vueltas para siempre, incansablemente. Sin embargo, el flujo de control del programa pasaba a través suyo y llegaba al final sano y salvo. Me llevó dos semanas darme cuenta de por qué.

El RPC-4000 tenía una característica muy moderna llamada registro índice. Permitía al programador escribir un bucle que tenía dentro una instrucción indexada. Cada vez que se ejecutaba, el número contenido en el registro índice se sumaba a la dirección de esa instrucción, así que hacía referencia al siguiente dato de una serie. Solo había que incrementar el valor del registro índice en cada iteracción. Mel nunca lo usaba.

En vez de eso, cargaba la instrucción en un registro de la máquina, sumaba uno a su dirección, y la guardaba de vuelta. Luego ejecutaba la instrucción modificada directamente desde el registro. El bucle estaba escrito de forma que tenía en cuenta este tiempo de ejecución adicional. Justo cuando esta instrucción terminaba, la siguiente estaba bajo la cabeza lectora del tambor, lista para funcionar. Pero el bucle no tenía condición.

La pista vital vino cuando noté que el bit del registro índice, el que estaba entre la dirección y el código de operación en la instrucción codificada, estaba encendido. Sin embargo, Mel nunca usaba el registro índice, lo dejaba a cero todo el tiempo. Cuando la luz me iluminó casi me ciega.

Mel había colocado los datos con los que estaba trabajando cerca de la cima de la memoria, en las direcciones más grandes que las instrucciones podían direccionar, así que, después de que el último dato había sido manejado, incrementar la dirección de la instrucción hacía que se desbordara. El acarreo sumaba uno al código de operación, convirtiéndolo en la siguiente instrucción del juego de instrucciones: una instrucción de salto. Como era de esperar, la siguiente instrucción estaba en la dirección cero, y el programa seguía felizmente su camino.

No me he mantenido en contacto con Mel, así que no sé si alguna vez se rindió al cambio de tendencias que fue puliendo las técnicas de programación desde aquellos lejanos días. Me gusta pensar que no. De cualquier manera, estaba tan impresionado que dejé de buscar la dichosa condición y le dije al Gran Jefe que no había podido encontrarla. No pareció sorprendido.

Cuando dejé la compañia, el programa de blackjack todavía hacía trampas si encendías el interruptor, y creo que así es como debe ser. No me sentía cómodo hackeando el código de un Verdadero Programador.

No voy a hacer comentarios porque, ante esto, cualquiera se quedaría sin palabras. Cabe preguntarse si es una historia real. A primera vista parece una invención. Hoy en día, en la época de los lenguajes interpretados, poca gente puede creerse que haya alguien capaz de programar escribiendo código directamente en hexadecimal, y encima haciendo mejores optimizaciones que las de cualquier ensamblador.

Sin embargo, parece que Mel es un personaje real. Su nombre es Mel Kaye, y trabajó realmente en la Royal McBee Corporation. Existen hojas de codificación con su nombre, como podéis ver aquí. Por lo visto, en el manual del LGP-21 había un ejemplo de la técnica que Mel usaba. Aquí se puede ver mejor la hoja de codificación. Se aprecia cómo, en la codificación de las instrucciones aparece el código de operación a la izquierda, en los bits altos, y la dirección a la derecha, en los bajos, así que si se desbordara la dirección, afectaría al código de operación, tal como cuenta la historia. Si os fijáis en la fecha, la hoja es de 1956, 27 años antes de que Ed Nather posteara la historia en Usenet, lo cual entra dentro de lo creíble teniendo en cuenta que la historia está contada después de que Ed dejara la compañía. Aquí está la salida impresa de un programa de blackjack de la Royal McBee que podría ser el de Mel. Aquí hay más información. Parece ser que Mel murió en 2008 de una enfermedad hepática. Lástima. Un genio menos en el mundo.

Según la Wikipedia, los ordenadores de la Royal McBee estaban fabricados por Librascope y la documentación del programa de blackjack estaba firmada por Mel Kaye de Librascope Inc. Parece ser que en 1956 algunos ingenieros de Librascope fueron transferidos a la nómina de la Royal McBee. El nombre de uno de ellos era Mel Kaye. Aquí hay una foto de mural de varios instructores de Librascope dando clase a nuevos programadores del LGP-30. El que está de pie a la derecha del todo es Mel Kaye. Aquí hay una descripción del programa de blackjack escrita por Mel Kaye. Según esa descripción, el programa se cargaba en la dirección 00000, lo que encaja con el lugar hacia el que se dirigía el salto cuando la dirección se desbordaba, según la historia.

En este artículo de la Wikipedia (en inglés) hay una muy buena descripción de la máquina inicial, el LGP-30, según la cual, tiene las características que dice la historia, incluidas las válvulas de vacío y la memoria de tambor. También explica el problema del retardo por el giro del tambor. Si queréis ver una foto de la “maravilla”, aquí hay una. Y el manual de programación está aquí. Se puede ver que la instrucción de salto tenía el código 10 y la anterior, de código 9, era para leer del tambor (aunque de una forma un poco peculiar) de manera que es creíble que si la dirección de la instrucción se desborda, se convierta en un salto, tal como cuenta la historia. Parece ser que el LGP-30 era la máquina que estaba usando el meteorólogo Edward Lorenz cuando descubrió el efecto mariposa.

No sé vosotros, pero yo ya estoy convencido de que la historia es real.

EOF

Anuncios