Programación en binario absoluto
Los primeros programadores escribían en binario absoluto: cada instrucción y cada dirección en dígitos binarios puros. Una sola instrucción podría verse como 01100101 00001010 — código de instrucción y dirección de memoria en binario.
El problema del código espagueti
Cuando un error requería insertar una nueva instrucción, los programadores enfrentaban un dilema. Insertar en su lugar significaba que cada dirección de instrucción posterior se desplazaba por uno — requiriendo que el programador actualizara cada referencia de dirección en todo el programa. Catastrófico.
La solución: reemplazar la instrucción justo antes del punto de inserción con un salto a memoria vacía. En esa ubicación vacía: escribir la instrucción sobrescrita, añadir las nuevas instrucciones, luego saltar de vuelta. Cuando errores aparecían en las correcciones, aplicar el mismo truco de nuevo usando otra memoria vacía.
Resultado: la ruta de ejecución a través del programa saltaba a ubicaciones aparentemente aleatorias. Hamming llamó a esto 'una lata de espagueti.' La ruta del flujo de control, dibujada en papel, se veía exactamente como espagueti enredado.
Las rutas de escape
Dos mejoras inmediatas: notación octal (agrupar dígitos binarios en conjuntos de 3) y hexadecimal (grupos de 4, usando A–F para valores más allá de 9). Estas redujeron errores de escritura pero no resolvieron el problema fundamental de direcciones.
Ensamblador simbólico (p.ej. SAP de IBM — Programa de ensamblador simbólico — y SOAP — Programa de ensamblador optimizado simbólico en la IBM 650) permitía a los programadores escribir nombres de instrucciones (ADD, MOVE) y etiquetas de direcciones simbólicas en lugar de binario. El ensamblador traducía a binario en tiempo de entrada, gestionando automáticamente asignaciones de dirección.
SOAP realizaba una optimización adicional: dispuso instrucciones en el tambor rotatorio para que la siguiente instrucción llegara a la cabeza lectora justo cuando se completaba la anterior — codificación de latencia mínima. SOAP incluso se compilaba a sí mismo: el programa A se procesaba como datos para producir B, B se ejecutaba en A para medir cuánto auto-compilación lo mejoraba.
Bibliotecas y código relocalizable
Hamming notó que la idea de software reutilizable (bibliotecas matemáticas) llegó muy temprano — Babbage la había concebido. El problema: una biblioteca de dirección absoluta requería que cada rutina ocupara las mismas ubicaciones de memoria cada vez que se usaba. Cuando la biblioteca total crecía demasiado, los programas competían por las mismas direcciones.
La solución: código relocalizable. El ensamblador genera instrucciones que hacen referencia a memoria relativamente — desplazamientos desde una dirección base — en lugar de direcciones absolutas. Un enlazador resuelve las direcciones finales en tiempo de carga.
Los informes inéditos de von Neumann (ampliamente distribuidos) describían los trucos de programación necesarios. El primer libro de programación publicado (Wilkes, Wheeler & Gill, EDSAC, 1951) codificó estas técnicas.
La bifurcación del diseño de lenguaje
FORTRAN (1957, IBM) y ALGOL (1958, comité internacional) representan dos filosofías de diseño que produjeron resultados radicalmente diferentes.
FORTRAN
John Backus lideró el proyecto FORTRAN (FORmula TRANslation) en IBM. El objetivo del diseño: hacer el lenguaje fácil para que científicos e ingenieros lo usaran. FORTRAN aceptaba notación matemática que se sentía natural para sus usuarios: A = B + C * D en lugar de ADD B, C; STORE T; MULTIPLY T, D; STORE A.
FORTRAN sobrevivió más de 60 años. Permanece en uso activo en computación científica, dinámica de fluidos, modelado climático y física computacional. Hamming notó esta durabilidad como prueba de diseño exitoso.
ALGOL
ALGOL (Lenguaje ALGOrítmico) fue diseñado por un comité de lógicos y científicos de computadoras buscando rigor matemático: un lenguaje lógicamente limpio y formalmente definible. La notación Backus-Naur (BNF) para describir gramáticas fue inventada para especificar ALGOL.
ALGOL fracasó en la práctica. A pesar de su elegancia lógica e influencia enorme en diseño de lenguajes posteriores (Pascal, C, y casi cada lenguaje moderno desciende de los conceptos de gramática de ALGOL), ALGOL mismo nunca fue ampliamente desplegado. El veredicto de Hamming: lógicamente diseñado, humanamente inutilizable.
La jerarquía de lenguajes
Hamming describió una jerarquía natural de código máquina pasando por ensamblador, lenguajes de nivel superior, y finalmente un 'lenguaje orientado a problemas' cercano a cómo los profesionales piensan sobre su dominio de problema. Cada nivel añade legibilidad humana al costo de eficiencia de máquina.
Los cuatro criterios de diseño de lenguaje de Hamming
Hamming destilaba la lección de FORTRAN vs ALGOL en cuatro criterios para un lenguaje de programación exitoso:
1. Fácil de aprender — un novato puede volverse productivo rápidamente
2. Fácil de usar — las tareas rutinarias requieren mínima ceremonia
3. Fácil de depurar — los errores producen mensajes significativos y localizables
4. Fácil de usar subrutinas — la reutilización y abstracción no requieren esfuerzo heroico
Añadió una observación estructural: el lenguaje humano lleva aproximadamente 60% de redundancia; el lenguaje escrito aproximadamente 40%. Los lenguajes de baja redundancia (como APL) producen una línea elegante que expertos encuentran hermosa y principiantes encuentran opaca — y que contienen errores indetectables cuando un solo carácter cambia de significado.
La implicación: un lenguaje diseñado para elegancia lógica optimiza para el lector equivocado. El programador es humano; los humanos necesitan redundancia para detectar errores y comunicar intención.
Diseño de lenguaje psicológico vs lógico
Hamming regresaba al contraste FORTRAN/ALGOL como una lección en dinámicas institucionales y humanas, no solo en diseño de lenguaje.
FORTRAN fue diseñado psicológicamente — para los humanos que lo usarían, específicamente científicos que pensaban en notación matemática. ALGOL fue diseñado lógicamente — para corrección formal y elegancia teórica.
La paradoja que Hamming identificaba: un lenguaje lógicamente correcto al que los humanos resisten falla; un lenguaje diseñado pragmáticamente al que los humanos adoptan tiene éxito, incluso si es lógicamente más desordenado.
Citó APL como el caso extremo: lógicamente elegante, expresable en una línea, con su propio conjunto de caracteres especiales. Los expertos lo amaban. Los programadores normales lo encontraban ilegible. Un solo cambio de carácter podía transformar silenciosamente el significado de un programa. APL tiene una comunidad pequeña dedicada y casi cero uso principal.
El argumento de redundancia humana: el lenguaje hablado es ~60% redundante (contexto repetido, palabras aclaratorias, estructura predecible). El lenguaje escrito ~40% redundante. Esta redundancia sirve a la detección de errores — los humanos son poco confiables, así que el lenguaje evolucionó para llevar suficiente información repetida para detectar y corregir errores. Un lenguaje de baja redundancia elimina esta red de seguridad.
La jerarquía de compiladores
Hamming describía el apilamiento compilador/intérprete: un programa puede leer en un lenguaje de nivel superior y traducirlo a uno de nivel inferior. Apila estas capas — cada una traduce un nivel hacia abajo. En la parte superior: un lenguaje específico de dominio que expertos en un campo (biología, finanzas, física) escriben naturalmente. En la parte inferior: código máquina. Cada transición es un compilador o intérprete.
Prediciendo la supervivencia del lenguaje
Para 1993, Hamming había visto muchos lenguajes tener éxito y fracasar. FORTRAN (1957) sobrevivió. ALGOL (1958) fracasó. COBOL (1959) sobrevivió décadas en computación empresarial. LISP (1958) sobrevivió en investigación de IA. PL/I (1964) intentó unificar todo y fracasó.
El patrón recurrente
El capítulo de historia del software de Hamming contiene una estructura recurrente:
1. Existe una limitación dolorosa (direcciones absolutas, notación binaria, código inmantenible)
2. Alguien inventa una capa de abstracción que oculta la limitación
3. La abstracción habilita nueva escala, que crea nuevas limitaciones dolorosas
4. Repetir
Binario → octal/hex → ensamblador simbólico → FORTRAN → programación estructurada → lenguajes orientados a objetos → lenguajes específicos de dominio. Cada capa resuelve el dolor más agudo del predecesor mientras introduce una nueva clase de problema.
El problema del código espagueti (direcciones absolutas) llevó al ensamblador simbólico. Los grandes programas de ensamblador llevaron a FORTRAN. Los grandes programas de FORTRAN llevaron a programación estructurada y luego orientación a objetos. La conferencia de Hamming terminó antes de estas transiciones posteriores, pero el patrón continúa.
Su lección para ingenieros: siempre estás resolviendo el dolor expuesto por la abstracción anterior. Entender la capa en la que estás actualmente requiere saber por qué existe la capa de abajo.