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.