As primeiras máquinas

[<] [>] [sumário]


 


Os primeiros computadores eletromecânicos

[topo]

A partir da década de 1930 alguns cientistas começaram a trabalhar com dispositivos de cálculo com algum tipo de sistema de controle automático. Já se dispunha da tecnologia necessária para se construir aquela estrutura imaginada por Babbage. Surgiram os primeiros computadores mecânicos e eletromecânicos e muitos projetos de computadores eletrônicos feitos posteriormente sofreram muitas influências dessas primeiras máquinas. Pode-se dividir esta primeira etapa em 3 partes:

    1. o trabalho do alemão Konrad Zuse;
    2. a produção, pelos laboratórios da Bell Telephone, de uma série de computadores baseados em tecnologia de relés e os projetos de Howard Aiken em Harvard;
    3. os projetos de computadores eletromecânicos de pequeno e grande porte da IBM .

 

Konrad Zuse

[topo]

Konrad Zuse (1910-1995) foi o primeiro a desenvolver máquinas de cálculo controladas automaticamente. Esse engenheiro civil percebeu rapidamente que um dos aspectos mais onerosos ao se fazerem longos cálculos com dispositivos mecânicos era guardar os resultados intermediários para depois utilizá-los nos lugares apropriados nos passos seguintes 64. Em 1934, depois de várias idéias e tentativas, Zuse chegou à conclusão que um calculador automático somente necessitaria de três unidades básicas: uma controladora, uma memória e um dispositivo de cálculo para a aritmética. Ele desenvolveu o seu Z1, em 1936, um computador construído inteiramente com peças mecânicas e que usava uma fita de película cinematográfica para as instruções que controlavam a máquina.

Em 1938, antes mesmo de terminar o Z1, um aluno de Zuse, Helmut Schreyer, construiu uma parte do Z1 usando válvulas. Em função da situação de pré-guerra, Zuse teve de abandonar essa linha de desenvolvimento - seriam necessárias 1000 válvulas, o que era impossível naquele momento - e continuou o Z2 usando tecnologia baseada em relés.

Esses dois primeiros modelos eram somente para teste: "tinham todas as características do computador posterior, mas não trabalhavam satisfatoriamente. O Z3 foi terminado em 1941 e foi o primeiro modelo totalmente operacional" §1e 83. O Z3, como a maioria das máquinas dessa primeira geração, usava dois mecanismos separados para as funções aritméticas e tinha uma unidade especial para conversão de números na notação decimal para a binária. Em termos de velocidade podia ser comparado ao MARK I, discutido mais à frente, que foi terminado dois anos após o Z3. O Z3 executava três a quatro adições por segundo e multiplicava dois números em quatro ou cinco segundos. Nunca chegou a ser usado para grandes problemas em função de possuir uma memória de tamanho limitado. Foi destruído, junto com a casa de Zuse, por um bombardeio em 1944.

O Z4 começou a ser desenvolvido quase que simultaneamente ao final do trabalho do Z3. Era essencialmente a mesma máquina, com maior capacidade de memória e mais rápida. Por causa do avanço das tropas aliadas, o trabalho do Z4 foi interrompido quase ao seu final e a máquina ficou escondida em uma pequena cidade da Bavária chamada Hinterstein Em 1950, na Suíça, Zuse reconstruiu o seu Z4, e fundou uma empresa de computadores, absorvida depois pela Siemens. As máquinas de Zuse tiveram pouco impacto no desenvolvimento geral da Computação pelo absoluto desconhecimento delas até um pouco depois da guerra 83.

 

As máquinas da Bell e as máquinas de Harvard

[topo]

Por volta de 1937, enquanto Turing desenvolvia a idéia da sua "Máquina Universal" e formalizava o conceito do que é computar e do que é um algoritmo, nos Estados Unidos dois outros matemáticos também consideravam o problema da computação: Howard Aiken, em Harvard, cujo trabalho daria seus frutos em 1944, e George Stibitz, nos laboratórios da Bell Telephones. Eles procuravam componentes eletromecânicos que pudessem ser usados na computação de cálculos.

Nos últimos anos da década de 1930 os problemas envolvendo cálculos com números complexos (aqueles com partes imaginárias, envolvendo raízes negativas) no projeto de equipamentos telefônicos começaram a dificultar o crescimento da Cia. Bell Telephone. As pesquisas da empresa então começaram a ser direcionadas à descoberta de mecanismos que pudessem satisfazer essa necessidade cada vez mais crescente de cálculos mais rápidos. Stibitz demonstrou que relés podiam ser utilizados para executar operações aritméticas. A partir de 1938, juntamente com S. B. Willians começou a implementar suas idéias, e em 1939 estava pronto o seu Modelo I. Seus outros 'Modelos' chegaram até o número VI, terminado em 1950 - tendo estado em uso até 1961 -, e juntamente com os computadores K do Dr. Zuse foram os primeiros computadores de código binário, baseados em relés69.

Ao mesmo tempo, nos Laboratórios de Computação de Harvard, Howard Aiken e engenheiros da IBM começaram a desenvolver um outro tipo de máquinas eletromecânicas, não totalmente baseada nos relés, já incorporando uma nova tecnologia que seria amplamente utilizada mais tarde: as memórias de núcleo de ferrite. Ao término de sua primeira versão, em 1943, o IBM Automatic Sequence Controlled Calculator, comumente chamado de Harvard Mark I, tinha uma série de novas capacidades: modificava instruções dinamicamente baseando-se nos resultados obtidos durante o processamento, possuía unidades para decidir qual o melhor algoritmo para execução de um cálculo através do argumento de uma função, testava o conteúdo de registradores, etc. Quando terminado em 1944, foi imediatamente adotado pela marinha americana, para fins militares. Novas versões foram produzidas até 1952.

 

A participação da IBM

[topo]

As máquinas de calcular mecânicas produzidas por empresas como a IBM não tinham linha de produção até a entrada dessas empresas no mercado de computadores propriamente dito. Eram equipamentos para auxiliar tarefas computacionais, que variaram desde as tabuladoras de Hollerith até tabuladoras para cálculos científicos como as produzidas por L.J. Comrie na Inglaterra ou Wallace J. Eckert nos Estados Unidos. Em 1935 a IBM começou a produzir suas séries 602, 602A até 605, calculadoras baseadas em relés que produziam em altas velocidades - como Babbage imaginou - tabelas de vários tipos , com alta confiabilidade. Uma posterior evolução foi a possibilidade dessas máquinas poderem ser programadas através de painéis de controle ('plugboards') para ler um cartão, executar até 60 diferentes cálculos aritméticos, e perfurar o resultados no próprio cartão de leitura. Outras empresas como a Remington Rand produziram equipamentos semelhantes80.

Depois do sucesso do Mark I em Harvard, no qual teve grande participação com o laboratório em Endcott, a IBM lançou-se na produção do Selective Sequence Electronic Calculator (SSEC), sob o comando de Frank Hamilton, que pertenceu ao grupo de Aiken, em Harvard. Terminado em 1947, atraiu um importante grupo de pesquisadores que buscavam o aprimoramento da capacidade de cálculo e cujas soluções apontavam para um conceito decisivo para os computadores: o de programa armazenado. O último computador eletromecânico produzido foi o CPC, Card-Programmed Electronic Calculator, modelos I e II que finalizaram a série 70033.

 


O início da era da computação eletrônica

[topo]

Durante os anos de 1936 a 1939, "John Vincent Atanasoff, com John Berry, desenvolveu a máquina que agora é chamada de ABC (Atanasoff-Berry Computer), na Universidade de Iowa, EUA, como uma máquina dedicada especialmente à solução de conjuntos de equações lineares na Física. Embora sendo um dos primeiros exemplos de calculadora eletrônica, o ABC propiciou o desenvolvimento dos primeiros conceitos que iriam aparecer nos computadores modernos: a unidade aritmética eletrônica e a memória de leitura e gravação"34.

Ocupa também um importante lugar na História da Computação o computador ENIAC: esta máquina e a equipe que a projetou e a construiu serão responsáveis por um grande avanço no desenvolvimento dos computadores eletrônicos. No início da Segunda Guerra as necessidades de melhores tabelas de cálculo para as trajetórias de tiros tornaram-se imperativas, pois os analisadores diferenciais estavam no seu limite. Nessa época foi então montado, na Moore School of Electrical Engineering da Universidade da Pensilvânia (Filadelfia, EUA), uma grupo de pesquisa para o desenvolvimento de projetos eletrônicos relacionados ao futuro radar. Entre eles, J. Presper Eckert, Joseph Chedaker e Kite Sharpless logo se envolveram na produção de circuitos eletrônicos usados como contadores. Eckert (1919-1995) e um pouco mais tarde John Mauchly (1907-1980), físico, e Herman H. Goldstine, matemático, tornaram-se os principais protagonistas na construção do Electronic Numerical Integrator and Computer, o primeiro computador onde cada unidade era composta de válvulas eletrônicas e relés.

Em 1945 John von Neumann ingressou como consultor na equipe da Universidade da Pensilvânia, iniciando um trabalho sobre projetos de computadores, que foi fundamental nos 40 anos que se seguiram. Em 30 de junho de 1945 ele publicou o First Draft of a Report on the EDIVAC, que estabeleceu o paradigma de projetos de computadores para várias gerações seguintes de máquinas. Esta arquitetura ficou conhecida com o nome de "arquitetura de von Neumann", e entre outras coisas incluía o conceito de programa armazenado. John von Neumann foi o responsável pela criação do código a ser usado (base para os futuros código a serem desenvolvidos) no ENIAC e elaborou o projeto lógico do dispositivo eletrônico para executá-lo. O ENIAC começou a operar em 1943, tendo sido terminado totalmente em 1946, encerrando suas operações em 1955.

Enquanto isso, na Inglaterra, o grande esforço era decifrar o código secreto de guerra germânico. Um grupo especial formado por cientistas e matemáticos reuniu-se em Bletchley Park, um lugar entre as Universidades de Cambridge e Oxforf, para tentar construir uma máquina capaz de decodificar o alfabeto produzido pela versão germânica de um dispositivo inventado nos Estados Unidos, o ENIGMA35. A equipe era liderada pelo prof. T. H. Flowers, sendo o prof. M. H. A. Newman o responsável pelos requisitos que levariam, em 1943, à construção do computador digital eletrônico COLOSSUS§2. O trabalho do grupo de Betchley foi enormemente influenciado pelos resultados sobre computabilidade obtidos por Alan Turing, que trabalhava no departamento de comunicação criado pelo governo britânico em função da guerra, com a missão de treinamento em lógica matemática e logo alocado também para os esforços de decifrar o código secreto alemão. O COLOSSUS acabou não sendo conhecido em sua época por duas razões. A primeira é não ter sido ele um computador para uso geral, mas sim projetado especialmente para decodificar mensagens secretas. A segunda: a existência desta máquina somente foi revelada a partir de 1970, sendo que seus algoritmos de decodificação são ainda secretos.

Ainda na Inglaterra, após o fim da guerra, Turing uniu-se ao centro de pesquisas do National Physical Laboratory, onde rapidamente elaborou o projeto básico do Automatic Computing Engine (ACE), que iniciou operações em 1950.

Um importante aspecto do desenvolvimento dos computadores foi a produção de dispositivos chamados de 'memória'. Desde Konrad Zuse, a construção de computadores que pudessem ter seus programas armazenados preocupou os cientistas e foi um fator determinante nas primeiras arquiteturas. Desde as memórias mecânicas de Zuse, passando pelas memórias térmicas - utilizadas somente experimentalmente - de A. D. Booth, pelos sistemas de linha de retardo baseados em mercúrio de Willian Shockley, da Bell - aperfeiçoada por Presper Eckert - utilizados no ENIAC, pelas memórias eletrostáticas de Willians até os núcleos magnéticos de ferrita, um árduo caminho foi percorrido. A memória de núcleos magnéticos acabou preponderando, tendo sido utlizada primeiramente em uma máquina de teste no MIT e mais tarde no computador conhecido como Whirlwind. O uso das memórias de núcleo magnético aumentaram excepcionalmente a performance dos computadores, podendo ser consideradas como um divisor de águas no desenvolvimento dos mesmos.

Importantes também nesse primeiro período foram duas grandes revoluções tecnológicas: o emprego de válvulas para tornar o computador mais rápido, confiável e de uso geral, e o conceito de programa armazenado. Von Neumann, um dos envolvidos no projeto do ENIAC, foi para Princeton construir a sua própria versão do EDVAC (Electronic Discrete Variable Automatic Computer), que tinha sido projetado por Eckert e Mauchly na Pensilvânia§3. Era evidente para von Neumann que a programação de computadores com um grande número de chaves e cabos era lenta e pouco flexível. Ele começou a perceber que o programa poderia ser representado em forma digital na memória do computador, juntamente com os dados. Seu projeto básico, hoje conhecido como máquina de von Neumann, foi utilizado no EDSAC, o primeiro computador de programa armazenado. Esta técnica de usar uma "memória de armazenamento" assim como a "transferência de controle por condição", que permitiam parar e reiniciar o processamento a qualquer instante, abriu enorme perspectiva para a programação de computadores. O elemento chave dessa arquitetura era a unidade central de processamento, que permitia a coordenação de todas as funções do computador através de uma única fonte. Em 1951, o UNIVAC I (Universal Automatic Calculator), construído pela Remington-Rand, tornou-se o primeiro computador comercialmente disponível que utilizava esses conceitos§4.

Esta primeira geração de computadores caracterizou-se pelo fato de que as instruções de operação eram produzidas para tarefas específicas. Cada máquina tinha um programa em código binário diferente que indicava o fluxo das operações. Isto dificultava a programação e limitava a versatilidade desses primeiros computadores.

Na figura que se segue há um pequeno resumo desses primeiros tempos da computação eletrônica, tomando como referência o ensaio de Arthur W. Burks15.

 

Figura:desenvolvimento do hardware e software nos primeiros tempos da Computação


As primeiras linguagens

[topo]

Atendo-se às premissas iniciais - de se destacar neste trabalho a evolução dos conceitos e idéias ao longo da História da Computação - não se pretende aqui uma descrição exaustiva da evolução das linguagens de programação. Depois de algumas considerações teóricas iniciais, serão vistas as motivações e as primeiras tentativas de se estabelecer um código que pudesse ser lido e processado pelos primeiros computadores.

 

Alguns aspectos teóricos

[topo]

Um dos pontos fundamentais do projeto formalista de Hilbert para a solução de problemas matemáticos era descobrir um procedimento efetivo (ou mecânico) para verificar a validade de proposições matemáticas. Depois do Teorema de Gödel evidenciou-se que tal proposta é irrealizável, mas todos os estudos em torno desse projeto de Hilbert e dos resultados de Gödel propiciaram, entre outras coisas, um adequada caracterização do termo efetivamente computável, através da Máquina de Turing e das funções lambda-definíveis de Church e Kleene. Tornou-se claro o que é um procedimento efetivo, tornando-se claro ao mesmo tempo o que é um problema computável.

Um procedimento efetivo é uma sequência finita de instruções que podem ser executadas por um agente computacional, seja ele homem ou não. Propriedades: (i)a descrição deve ser finita; (ii)parte de um certo número de dados, pertencente a conjuntos específicos de objetos, e espera-se que produza um certo número de resultados que mantenham relação específica com os dados; (iii)supõe-se que exista um agente computacional - humano, eletrônico, mecânico, etc. - que execute as instruções do procedimento; (iv)cada instrução deve ser bem definida; (v)as instruções devem ser tão simples que poderiam ser executadas por alguém usando lápis e papel, em um espaço de tempo finito. Esse procedimento efetivo também é chamado de algoritmo. Programas de computadores que terminam sua execução, fornecido qualquer conjunto específico de dados de entrada, são algoritmos.

A descrição finita do algoritmo deve ser feita através de uma determinada linguagem. Esta linguagem algoritmica deve pertencer a um conjunto não ambíguo de uma linguagem natural, tal como Francês ou Inglês, ou de uma linguagem artificial como FORTRAN ou LISP. As frases da linguagem descreverão as operações a serem executadas. A forma ou formato de procedimentos efetivos em uma linguagem algoritmica qualquer é especificada por um conjunto de regras chamada regras de sintaxe, cujas propriedades estão acima enumeradas11. Esta sintaxe refere-se aos programas corretamente escritos nela e o relacionamento entre os símbolos e frases que ocorrem nesses programas. Alguns altores a divedem em ser concreta e abstrata55. A concreta envolve (i) o reconhecimento de textos (sequências de caracteres) corretamente escritos de acordo com as especificações da linguagem e (ii) a colocação dos textos, de maneira não ambígua, dentro das frases que compõe o programa. A sintaxe abstrata lida com as estruturas de frases do programa. Portanto a sintaxe refere-se à forma dos programas: como expressões, comandos e declarações podem ser justapostos para compor um programa. Uma linguagem de programação torna-se assim, entre outras coisas, uma notação formal para a descrição de um algoritmo, entendo-se por notação formal um simbolismo que não tenha as imprecisões nem a variabilidade de uma linguagem natural, que possibilite rigor nas definições e demonstrações sobre os procedimentos.

Uma linguagem de programação necessita ainda de outros requisitos. Deve ser universal, i.e., qualquer problema que tenha solução por computador pode ser escrito com ela. Qualquer linguagem em que se possa definir uma função recursiva será universal. Na prática deve ser apta a resolver, no mínimo, os problemas da área para a qual foi projetada§5. E uma característica fundamental: ser implementável em computador, isto é, deve ser possível executar qualquer procedimento bem formado na linguagem48.

Uma linguagem de programação também possui uma semântica. A semântica de um programa irá depender exclusivamente do que se deseja causar§6 objetivamente quando o programa for executado por um agente computacional, eletrônico ou não. Os computadores atualmente são máquinas complexas. Quando estão executando programas, luzes se acendem, cabeçotes dos discos movem-se, corrente elétrica flui pelos circuitos, letras aparecem na tela ou são impressas, e assim por diante. Um programa controla todos esses 'fenômenos' através de sua semântica. E se são consideradas as linguagens de programação de alto nível, que não controlam diretamente esses detalhes de ordem física, falar de semântica signifca falar das características que tornam tais linguagens implementáveis, independentemente de ser este ou aquele computador, isto é, quais as características da execução do programa que são comuns a todas as implementações? Portanto a semântica é uma entidade abstrata: ela modela o que o programa quer causar quando é executado, independente do seu uso nesse ou naquele computador. A semântica de uma linguagem de programação é a mesma semântica de todos os programas escritos nela55.

A evolução das linguagens de programação chegou até esses conceitos por caminhos e esforços muitas vezes paralelos. Alguns informatas buscam caminhos para projetar linguagens que combinem uma grande generalidade de usos (aplicações matemáticas e científicas, gráficas, comerciais, etc.) com simplicidade e eficiência. Isto levou ao desenvolvimento de diferentes paradigmas - estilos e objetivos - de programação como o imperativo, funcional, orientado a objeto, lógico, etc. Outros buscaram e buscam caminhos para expressar a sintaxe e a semântica, esta última talvez a parte mais importante dentro do assunto linguagens de programação e que levou ao surgimento de diversas linhas: a semântica algébrica, a denotacional, a de ações, etc.

 

Desenvolvimentos anteriores a 1940

[topo]

Mas antes de se entrar nesse mundo das linguagens, como eram anteriormente especificados os algoritmos? Os mais antigos algoritmos escritos que se conhecem são os da velha Mesopotâmia. Eram sequências de cálculos sobre conjuntos particulares de dados e não uma abstração§7 de procedimento como entendido na programação atual39. Na civilização grega, vários algoritmos não triviais foram estudados, como por exemplo o de Euclides. A descrição era ainda informal.

A notação matemática começou a evoluir efetivamente a partir dos séculos XIII e XIV e notações para relações funcionais tiveram tido um bom desenvolvimento. Na Computação, Babbage e Lady Lovelace elaboraram, entre outros, um programa para o cálculo dos números de Bernoulli54. Era na verdade uma espécie de programa em linguagem de máquina, como nos primórdios dos computadores digitais na década de 1940.

Em 1914, Leonardo Torres e Quevedo usaram uma linguagem natural para descrever um pequeno programa para seu autômato hipotético. Helmut Schreeyer fez uma descrição análoga em 1939 para a máquina que construía juntamente com Zuse.

O próprio Alan M. Turing, para tratar do problema da indecidibilidade de Hilbert construiu uma linguagem muito primitiva para sua máquina. Nela só havia comandos para ler, testa uma condição e escrever símbolos sobre uma fita, movendo para a direita ou esquerda uma cabeça de leitura e gravação. Conforme Knuth38, as 'tabelas' de Turing (como Alan Turing chamava sua linguagem) "representaram a notação de mais alto nível para uma descrição precisa de algoritmo que foram desenvolvidas antes da nossa história começar - exceto talvez pela notação-l de Alonzo Church (que representa um 'approach' inteiramente diferente para o cálculo) ".

 

As primeiras tentativas

[topo]

Nos primeiros tempos da computação propriamente dita os programas eram escritos em código de máquina e colocados diretamente no computador por meio de cabos e fios. Por exemplo:

0000 0001 0110 1110

0100 0000 0001 0010

1100 0000 0000 1101

Segundo Grace Murray Hopper§8, como curiosidade, "a frase mais frequente que nós ouvíamos era que a única maneira de se programar em um computador era em octal"77. Em 1946, junto com Howard Aiken, era assim que ela programava o Mark I.

Percebeu-se claramente que os programas em código de máquina eram extremamente difíceis de editar e modificar, e quase impossíveis de se compreender. A comunidade computacional logo entendeu que era necessário inventar uma notação simbólica para tornar os programas mais fáceis de escrever. Nesta evolução as instruções acima ficam com o formato:

LOAD X

ADD R1 R2

JUMPZ H

Uma vez feito o programa dessa maneira, o programador o prepararia para ser executado, 'escrevendo' manualmente (em painéis, através de um emaranhado de cabos e 'plugs') as instruções no correspondente código de máquina. Este processo foi chamado de assembling. O que depois se queria fazer era com que a própria máquina executasse essa operação.

Mas mesmo quando programava com esses códigos de operação mnemônicos (também chamados de linguagem de montagem), o programador ainda estava trabalhando em termos dos conjuntos de instruções da máquina, isto é, os algoritmos eram expressos em termos de instruções muito primitivas (detalhes sobre registradores, endereços, saltos, etc.). Daí a denominação linguagens de baixo nível. A busca de linguagens que pudessem permitir que os algoritmos fossem expressos em termos análogos à idéia elaborada na mente do programador fez com que aparecessem os primeiros compiladores e começaram a surgir as chamadas linguagens de alto nível.

Claramente percebem-se duas principais tendências nestes anos pioneiros: aqueles que procuravam saber o que era possível implementar e os que estavam preocupados com o que era possível escrever. Estes últimos criaram estruturas conceituais - iteração, tipos de dados, recursividade, etc. - importantes no processo de programação e que foram depois objetos de estudo na Teoria da Computação. Naturalmente foram precisos muitos anos para que estas duas tendências se juntassem para formar uma síntese adequada.

 

Konrad Zuse e seu 'Plancalculus'

[topo]

Depois de salvar o Z4 das bombas dos aliados e mudar-se para a pequena vila Hintesrtein nos Alpes, Konrad Zuse percebeu que ainda não existia uma notação formal para a descrição de algoritmos e começou a trabalhar em uma. O resultado foi uma linguagem chamada Plankalkül (program calculus), uma extensão do cálculo proposicional e de predicado de Hilbert. Em uma monografia sobre o Plankalkül, em 1945, Zuse começava dizendo: "A missão do Plancalculus é fornecer um descrição formal pura de qualquer procedimento computacional". O Plancalculus incluía alguns conceitos fundamentais da programação: tipos de dados, estrutura de dados hierárquicos, atribuição, iteração, etc. Ele pensou inclusive em usar o Plancalculus como base de uma linguagem de programação que pudesse ser traduzida por uma máquina. "Pode-se resumir sua idéia dizendo que o Plankalkül incorporou muitas idéias extremamente importantes, mas faltou-lhe uma sintaxe amigável para expressar programas em um formato legível e facilmente editável". Como complementação de seu trabalho desenvolveu algoritmos para ordenação, teste de conectividade de grafos, para aritmética de inteiros (inclusive raiz quadrada) e até um jogo de xadrez, entre outros. Infelizmente a maior parte destas coisas permaneceu desconhecida até 1972, a não ser por alguns extratos aparecidos em 1948 e 1959, quando seu trabalho chamou a atenção de alguns leitores ingleses. "É interessante especular sobre o que teria acontecido se ele tivesse publicado tudo imediatamente; teriam as pessoas sido capazes de entender idéias tão radicais?"38.

 

O diagrama de fluxos

[topo]

Em Princeton, do outro lado do Atlântico, Herman H. Goldstine e John von Neumann (figura) estavam preocupados com o mesmo problema: como se poderiam representar algoritmos de uma maneira precisa, em uma linguagem de mais alto nível que a de máquina. Eles propuseram então uma representação pictórica, através de caixas unidas por setas, que chamaram de fluxoogramas. Eles descreveram fluxogramas que continham uma caixa denominada "caixa de anotação (especificação)". Nesta caixa descreviam-se certos fatos sobre o resultado de uma computação (o efeito por ela provocado). O conteúdo desta caixa deveria ser confrontado com as operações descritas pelo fluxograma, possibilitando uma verificação da consistência entre o fluxograma e as intenções do programador expressas através das anotações. Com von Neumann e Goldstine encontra-se também a primeira referência à corretude de programas.
A ênfase era no poder de cálculo - e não na expressividade das estruturas como Zuse - e foi largamente difundido entre as pessoas envolvidas com computadores na época. "Este fato, acompanhado da excelente qualidade de apresentação e pelo pretígio de von Neumann, significaram que seu trabalho teve um enorme impacto, tornando-se fundamento para técnicas de programação em todo o mundo". O conceito matemático de igualdade foi substituído pelo de atribuição38.

 

A contribuição de Haskell

[topo]

Haskell B. Curry, contemporâneo de Goldstine e von Neumann, após uma experiência com um programa complexo no ENIAC sugeriu uma notação mais compacta que a deles. Na prática não obteve sucesso pela maneira estranha com que analisava e dividia os problemas. O principal ponto de interesse no trabalho de Curry, no entanto, não foi a sua linguagem de programação, mas os algoritmos que ele analisou para conversão de parte desses em código de máquina. Com isso ele proporcionou uma descrição recursiva de um procedimento para converter expressões aritméticas claras em um código de máquina apropriado, sendo por isso a primeira pessoa a descrever a fase de geração de código de um compilador38.

 


Interpretadores algébricos e linguagens intermediárias

[topo]

Em 1951, promovidas pela Marinha americana, houve uma série de três conferências, e naquela que tratava sobre manipulação de dados e computação automática apareceu um trabalho de John Mauchly, o Short Order Code. Codificado para o computador BINAC em 1949 por William F. Schmitt, foi recodificado pelo mesmo em 1950 para o UNIVAC e usava dois dígitos para representar alguns símbolos, ao invés do usual código binário. Era na verdade uma espécie de interpretador algébrico: o programa percorria cada linha de representação de código, da direita para a esquerda, desviava para as chamadas subrotinas, executava-as e ia para a próxima instrução.

Arthur W. Burks e colegas, na Universidade de Michigan, investigando o processo de passar alguns problemas de processamento de dados descritos em uma linguagem comum para a 'linguagem interna' de um computador, esboçou uma 'linguagem intermediária' que seria o passo anterior de uma 'linguagem interna' do computador, e que tinha um alto nível de abstração14.

Heinz Rutishauser, colaborador de Zuse no Z4 publicou em 1952 um trabalho descrevendo um computador hipotético e uma linguagem algébrica simples, junto com os fluxogramas de von Neumann para o que seriam dois 'compiladores'§9 para essa linguagem. Um para decodificar todos os loops enquanto o outro produzia código compacto através de registradores de índice. Como o Short Code, o programador deveria reservar manualmente as localizações de memória para variáveis e constantes. Um trabalho semelhante apareceu na Itália, na tese de dissertação de Corrado Böhm, que desenvolveu uma linguagem algébrica e o primeiro compilador para ela na própria linguagem, que reconhecia precedência de operações.

 


Os primeiros 'compiladores'

[topo]

Conforme Knuth e Trabb38, o termo compilador não era ainda utilizado nessa época. Na verdade falavam sobre programação automática. No início da programação em linguagem de máquina foram desenvolvidas subrotinas de uso comum para entrada e saída, para aritmética de ponto flutuante e funções transcedentais. Junto com a idéia de um endereçamento realocável - pois tais subrotinas seriam usadas em diferentes partes de um programa - foram criadas rotinas de montagem para facilitar a tarefa de uso das subrotinas e de endereçamento relativo, idéia desenvolvida por M. V. Wilkes. Para isso foi inventada uma pseudo linguagem de máquina. Uma rotina interpretativa iria processar estas instruções, emulando um computador hipotético26 e 38. Este é o sentido do termo 'compilador' até aqui usado e que ainda seguirá mais abaixo.

AUTOCODE foi o primeiro 'compilador' real, que tomava uma declaração algébrica e a traduzia em linguagem de máquina. Seu desconhecido autor, Alick E. Glennie, das forças armadas da Inglaterra, declarava em Cambridge, em 1953 sua motivação para elaborá-lo: "A dificuldade da programação tornou-se a principal dificuldade para o uso das máquinas. Aiken expressou sua opinião dizendo que a solução para esta dificuldade deveria ser buscada pela construção de uma máquina especial para codificar(...) Para tornar isto fácil deve-se elaborar um código compreensível. Isto somente pode ser feito melhorando-se a notação da programação"38. John Backus77 discute esta distinção que Knuth faz, citando J. Halcomb Laning, Jr. e Niel Zierler como os inventores do primeiro 'compilador' algébrico, para o computador Whirlwind. Como esta, são muitas as discussões ainda hoje sobre quem foi o pioneiro no assunto. De qualquer maneira estes primeiros sistemas denominados genericamente de programação automática (acima citado) eram muito lentos e não fizeram muito sucesso, embora tivessem sido fundamentais para preparar a base do desenvolvimento que se seguiu.

Este veio com o A-0, agora sim o primeiro compilador propriamente dito, desenvolvido por Grace Murray Hopper e equipe, aprimorado para A-1 e A-2 subsequentemente. O próximo passo seria o A-3, desenvolvido em 1955, produzido ao mesmo tempo com o tradutor algébrico AT-3, mais tarde chamado MATH-MATIC.

Em 1952 a IBM construía o computador 701 e em 1953 foi montada uma equipe liderada por John Backus para desenvolver um código automático que facilitasse a programação. O resultado foi o Speedcoding. Backus tornou-se uma das principais figuras na história da evolução das linguagens de programação, tendo um papel fundamental no desenvolvimento dos grandes compiladores que viriam a partir do ano de 1955 como o FORTRAN e o ALGOL, além do estabelecimento da moderna notação formal para a descrição sintática de linguagens de programação, denominada BNF, Backus Normal Form.

 


Notas

§1. Quer dizer, tinha o controle automático das suas operações.

§2. Tornado operacional em 1944, decodificando mensagens para ajudar nos planos do desembarque do dia D, ainda nesse ano.

§3. Esse projeto foi seriamente afetado quando eles deixaram a Universidade da Pensilvânia e foram fundar sua própria empresa na Filadelfia. Após uma série de fusões esta companhia tornou-se a atual Unisys Corporation.

§4. Eckert e Mauchly afirmaram que já tinham tido estas idéias antes de von Neumann, e Konrad Zuze afirmou o mesmo.

§5. Uma linguagem com somente tipos numéricos e arrays deve resolver naturalmente problemas numéricos.

§6. A maioria dos livros ao falar de semântica usa a palavra behavior, de difícil tradução. Pode-se dizer que é um conjunto de regras que determinam a ordem nas quais as operações do programa irão executar, quais serão executadas primeiro e quando se encerrarão.

§7. Uma abstração é um modo de pensar pelo qual nos concentramos em idéias gerais ao invés das manifestações específicas destas idéias.(...) Na programação, a abstração refere-se à distinção que fazemos entre: (a) o que um pedaço de programa faz e (b) como ele é implementado. Uma linguagem de programação em sentido próprio consiste de construções que são (em última instância) abstrações do código de máquina 76. Exemplos típicos de abstrações são as funções e procedimentos.

§8. Nome importante no desenvolvimento histórico das linguagens de programação. Ela desenvolveu programas para o Mark I, o 1o computador digital automático, um dos precursores do computador moderno; esteve envolvida na construção do UNIVAC e trabalhou no primeiro compilador que se tem notícia, o A-2, e em uma das primeiras linguagens matemáticas, originalmente chamada A-3 e depois MATH-MATIC. Em 1955 trabalhou na equipe que elaborou as primeiras especificações para uma linguagem de uso comercial, originalmente chamada B-0, depois FLOW-MATIC, que forneceu inúmeras características para o COBOL.

§9. Os termos interpretador e compilador na linguagem da computação têm um sentido técnico específico, que na época citada ainda não correspondiam ao atual significado.

[topo]