Programação em Binário Absoluto
Os primeiros programadores escreviam em binário absoluto: cada instrução e endereço em dígitos binários crus. Uma única instrução poderia se parecer com 01100101 00001010 - código de instrução e endereço de memória em binário.
O Problema do Código Espagueti
Quando um erro exigia a inserção de uma nova instrução, os programadores enfrentaram um dilema. Inserir no lugar significava que todos os endereços de instrução subsequentes se deslocariam para a frente - exigindo que o programador atualizasse cada referência de endereço na programação inteira. Catastrófico.
A solução: substituir a instrução imediatamente antes do ponto de inserção com um salto para a memória vazia. Nesse local vazio: escreva a instrução substituída, adicione as novas instruções, em seguida, salte de volta. Quando os erros apareceram nas correções, aplique a mesma trapaça novamente usando outros espaços de memória vazios.
Resultado: o caminho de execução através do programa pulava para o que parecia ser locais aleatórios. Hamming chamou isso de 'uma lata de espaguete'. O fluxo de controle, desenhado no papel, parecia exatamente como espaguete enrolado.
As Rutas de Escape
Dois melhoramentos imediatos: notação octal (agrupando dígitos binários em conjuntos de 3) e hexadecimal (em grupos de 4, usando A-F para valores acima de 9). Esses reduziram os erros de digitação, mas não resolveram o problema fundamental do endereço.
Assembléia simbólica (por exemplo, o SAP - Symbolic Assembly Program - e SOAP - Symbolic Optimizing Assembly Program no IBM 650) permitiu que os programadores escrevessem nomes de instruções (ADD, MOVE) e rótulos de endereço simbólicos em vez de binários. O compilador traduzia para binário no tempo de entrada, gerenciando automaticamente as atribuições de endereço.
SOAP realizou uma otimização adicional: ele organizou as instruções no tambor giratório de modo que a próxima instrução chegasse na cabeça de leitura exatamente quando a anterior estava concluindo - codificação com latência mínima. O SOAP até compilou a si mesmo: o programa A processava como dados para produzir B, B executado em A para medir quanto a autocompilação o melhorou.
Bibliotecas e Código Relocável
Hamming observou que a ideia de software reutilizável (bibliotecas matemáticas) surgiu muito cedo - Babbage a concebeu. O problema: uma biblioteca de endereços absolutos exigia que cada rotina ocupasse as mesmas localizações de memória a cada vez que era usada. Quando a biblioteca total ficava muito grande, os programas competiam pelos mesmos endereços.
A solução: código relocável. O assembleiro gera instruções que referenciam memória relativamente - deslocamentos a partir de um endereço de base - em vez de endereços absolutos. Um linkador resolve os endereços finais no tempo de carregamento.
Os relatórios inéditos de Von Neumann (largamente distribuídos) descreveram as truques de programação necessários. O primeiro livro de programação publicado (Wilkes, Wheeler & Gill, EDSAC, 1951) codificou essas técnicas.
A Divisão no Design de Linguagem
FORTRAN (1957, IBM) e ALGOL (1958, comitê internacional) representam duas filosofias de design que produziram resultados radicalmente diferentes.
FORTRAN
John Backus liderou o projeto FORTRAN (FORmula TRANslation) na IBM. O objetivo de design: tornar o linguagem fácil de usar para cientistas e engenheiros. O FORTRAN aceitava a notação matemática que se sentia natural para seus usuários: A = B + C * D em vez de ADD B, C; STORE T; MULTIPLY T, D; STORE A.
O FORTRAN sobreviveu a 60+ anos. Continua em uso ativo em computação científica, dinâmica de fluidos, modelagem climática e física computacional. Hamming notou essa durabilidade como prova de um design bem-sucedido.
ALGOL
ALGOL (Linguagem Algoritmos) foi desenhado por um comité de lógicos e cientistas da computação com o objetivo de rigor matemático: uma linguagem limpa lógica e formalmente definida. A notação Backus-Naur Form (BNF) para descrever gramáticas foi inventada para especificar o ALGOL.
O ALGOL falhou na prática. Apesar de sua elegância lógica e de sua enorme influência no design de linguagens subsequentes (Pascal, C e quase todas as linguagens modernas descendem dos conceitos gramaticais do ALGOL), o ALGOL em si nunca foi amplamente implantado. O veredicto de Hamming: lógica e inutilizável para humanos.
A Hierarquia das Linguagens
Hamming descreveu uma hierarquia natural da linguagem de máquina até a linguagem de montagem, linguagens de alto nível e, finalmente, uma 'linguagem orientada a problemas' próxima de como os praticantes pensam sobre seu domínio de problemas. Cada nível adiciona a legibilidade humana ao custo da eficiência da máquina.
Os Quatro Critérios de Design de Linguagem de Hamming
Hamming extraiu a lição do FORTRAN contra o ALGOL em quatro critérios para uma linguagem de programação bem-sucedida:
1. Fácil de aprender - um novato pode se tornar produtivo rapidamente
2. Fácil de usar - tarefas rotineiras requerem poucas cerimônias
3. Fácil de depurar - erros produzem mensagens significativas e localizáveis
4. Fácil de usar subrotinas - reuso e abstração não requerem esforço heroico
Ele adicionou uma observação estrutural: a linguagem humana carrega cerca de 60% de redundância; a linguagem escrita cerca de 40%. Linguagens de baixa redundância (como APL) produzem belas linhas de um só golpe que os especialistas encontram belas e os iniciantes encontram opacos - e que contêm erros indetectáveis quando um único caractere muda o significado.
A implicação: uma linguagem projetada para elegância lógica otimiza para o leitor errado. O programador é humano; os humanos precisam de redundância para detectar erros e comunicar intenção.
Design psicológico vs design lógico de linguagem
Hamming voltou ao contraste entre FORTRAN e ALGOL como uma lição sobre as dinâmicas institucionais e humanas, não apenas sobre o design de linguagem.
O FORTRAN foi projetado psicologicamente - para os humanos que usariam, especificamente cientistas que pensavam em notação matemática. O ALGOL foi projetado logicamente - para correção formal e elegância teórica.
O paradoxo identificado por Hamming: uma linguagem correta logicamente que os humanos resistem falha; uma linguagem projetada pragmaticamente que os humanos adotam tem sucesso, mesmo que seja mais suja em termos lógicos.
Ele citou APL como o caso extremo: elegante logicamente, expressível em uma linha, com seu próprio conjunto de caracteres especiais. Os especialistas adoravam. Os programadores normais achavam que não eram legíveis. Um único caractere alterado poderia transformar silenciosamente o significado de um programa. O APL tem uma pequena comunidade devotada e quase zero uso mainstream.
A argumentação de redundância humana: a linguagem falada é ~60% redundante (contexto repetido, palavras clarificadoras, estrutura previsível). A linguagem escrita ~40% redundante. Essa redundância serve para detecção de erros - os humanos são ineficazes, então a linguagem evoluiu para carregar informações repetidas o suficiente para detectar e corrigir erros. Uma linguagem de baixa redundância remove essa rede de segurança.
A hierarquia do compilador
Hamming descreveu a camada de compilador/interpretador: um programa pode ler uma linguagem de alto nível e traduzi-la para uma de baixo nível. Empilhe essas camadas - cada uma traduz para o nível abaixo. No topo: uma linguagem específica do domínio que os especialistas em uma área (biologia, finanças, física) escrevem naturalmente. No fundo: código de máquina. Cada transição é um compilador ou interpretador.
Previsão de sobrevivência de linguagem
Até 1993, Hamming havia observado muitos idiomas prosperarem e falharem. FORTRAN (1957) sobreviveu. ALGOL (1958) falhou. COBOL (1959) sobreviveu décadas em computação empresarial. LISP (1958) sobreviveu na pesquisa de IA. PL/I (1964) tentou unificar tudo e falhou.
O Padrão Recorrente
O capítulo de história de software de Hamming contém uma estrutura recorrente:
1. Uma limitação dolorosa existe (endereços absolutos, notação binária, código inmanutenável)
2. Alguém inventa uma camada de abstração que esconde a limitação
3. A abstração permite uma escala maior, o que cria novas limitações dolorosas
4. Repita
Binário → octal/hex → montagem simbólica → FORTRAN → programação estruturada → linguagens orientadas a objetos → linguagens específicas de domínio. Cada camada resolve a dor mais aguda do predecessor, enquanto introduz uma nova classe de problemas.
O problema do código espagueti (endereços absolutos) levou à montagem simbólica. Grandes programas em assembly levaram a FORTRAN. Grandes programas em FORTRAN levaram à programação estruturada e então à orientação a objetos. A aula de Hamming terminou antes dessas transições mais tarde, mas o padrão continua.
A lição para engenheiros de Hamming: você sempre está resolvendo a dor exposta pela abstração anterior. Entender a camada em que você está atualmente requer saber por que a camada abaixo dela existe.