1  Uma Breve Apresentação da História dos Computadores e Linguagens de Programação

1.1 Motivação

Mas, afinal, o que é um computador? Precisamos mesmo saber a resposta para começar a programar? Na verdade, não. Porém, entender como um computador funciona nos torna bons programadores. Definir o que é um computador pode ser mais complicado do que parece. Veremos que a ideia de “computador” mudou muito ao longo da história, sempre ligada à necessidade de contar. Antes de mergulhar na história, vamos explorar diferentes respostas para essa pergunta.

Logo no começo das aulas de 2025, na matéria MAC115 - Introdução à Computação para Ciências Exatas e Tecnologia, fizemos uma pergunta simples aos alunos: “O que é um computador?”. Anotamos as respostas (ver Apêndice A) e apesar de algumas respostas engraçadas, como “um robô que vai controlar os humanos um dia”, notamos que a maioria dos alunos pensava em coisas parecidas:

  1. Um computador é um objeto físico; uma máquina ou dispositivo.
  2. Ele é capaz de processar informações ou dados.
  3. É como uma calculadora, só que mais moderna.

Essas ideias mostram um pouco do que um computador faz, mas não explicam tudo o que ele é.

1.2 Computadores Precisam Existir?

O Professor Douglas Hartree (1897–1958), no seu livro “Calculating instruments and machines”, diz que computadores podem ser vistos de dois ângulos: anatômico (do que são feitos) e fisiológico (como funcionam). Tentar definir um computador pelas suas partes não seria suficiente, já que as peças dos computadores mudaram muito ao longo dos anos, então usar a anatomia para defini-los não funcionaria.

Na mesma época, o Professor Arthur L. Samuel propõe uma definição funcional do que é um computador. Segundo Samuel, um computador é “um dispositivo de processamento de informações ou dados que aceita dados em uma forma e os entrega em uma forma alterada”. Esta concepção técnica concorda com o que os alunos pensam. No entanto, essa definição nos leva a um questionamento mais profundo: será que computadores precisam necessariamente existir como dispositivos ou máquinas físicas, ou podemos conceber computação para além do aspecto material?

Se perguntássemos para uma pessoa na rua o que ela acha que é um computador, é bem provável que ela diria que é uma “máquina” ou um “dispositivo”. De fato, nas respostas que coletamos, essa ideia aparece com frequência. No entanto, os computadores modernos foram criados a partir de um modelo matemático abstrato, chamado Máquina de Turing.

Quando criança, aos 11 anos, Alan Mathison Turing escreveu uma carta para seus pais, Julius Mathison Turing e Ethel Sara Stoney Turing, contando sua ideia de como fazer uma máquina de escrever. Alan Turing não inventou a máquina de escrever, mas usou essa ideia para criar a Máquina de Turing: um modelo matemático de computação que manipula símbolos numa fita infinita, seguindo regras bem definidas. Esse modelo deu origem aos computadores modernos que, segundo John A. Robinson, nada mais são do que “manifestações físicas de uma mesma abstração lógica: a máquina universal de Turing.” Então, não. Computadores não precisam existir.

1.3 Ábacos, Máquinas de Calcular e Quase-Computadores

É aqui que a gente começa a falar da história da computação. Nós, humanos, somos muito criativos. Estamos sempre criando ferramentas para nos ajudar. Existem evidências arqueológicas que sugerem que os humanos praticam a contagem há pelo menos 50.000 anos. A contagem era usada por povos antigos para controlar dados sociais e econômicos, como o número de pessoas no grupo, animais, propriedades ou dívidas. Então, não é surpresa que os humanos tenham inventado ferramentas para ajudar nesse processo. Em 2700–2300 AC, os humanos criaram o ábaco: uma ferramenta para fazer contas mais rápido.

Ao longo dos séculos, outras ferramentas foram criadas para ajudar nisso. Um exemplo é a régua de cálculo, do século XVII, que fazia a mesma coisa que o ábaco, mas usando propriedades da funções logarítmicas. Os primeiros computadores eram como versões mais modernas dessas ferramentas, ou seja, máquinas de calcular. O engenho diferencial (1820) de Charles Babbage, uma máquina idealizada, mas não construída, é um exemplo de máquina de calcular feita para calcular funções polinomiais.

O inglês Charles Babbage era matemático, filósofo, inventor e engenheiro mecânico, e é considerado por muitos como o “pai do computador”. Esse título é por causa de outra máquina que ele idealizou. O engenho analítico (1840), diferente de todas as máquinas da época, marcou a transição da aritmética mecanizada para a computação de propósito geral. Essa máquina seria programada por meio de cartões perfurados e incorporaria diversos recursos posteriormente adotados em computadores modernos, como controle sequencial, estruturas de ramificação e mecanismos de repetição (laços).

Durante a criação do engenho analítico, a condessa de Lovelace, Augusta Ada Byron King (filha do poeta Lord Byron), criou um algoritmo para calcular a sequência dos números de Bernoulli, e por isso é considerada a primeira programadora. Hoje em dia, a figura de Ada é usada como inspiração para aumentar a presença de mulheres na computação, que era bem maior algumas décadas atrás.

Até então todas as máquinas desenvolvidas eram estritamente mecânicas. O Z2 foi um dos primeiros exemplos de um computador digital operado eletricamente, construído com relés eletromecânicos, e foi criado pelo engenheiro civil Konrad Zuse em 1940 na Alemanha. Mas, foi a partir da invenção das válvulas termiônicas (tubos de vácuo) que damos o primeiro salto na era dos computadores digitais. As válvulas eram dispositivos totalmente elétricos que geravam corrente elétrica a partir do fenômeno de emissão termiônica e foram inventadas pelo físico John Ambrose Fleming em 1904.

O Z3, sucessor do Z2, também foi desenvolvido por Zuse e é considerado o primeiro computador digital programável e totalmente automático do mundo. Konrad Zuse também foi responsável pelo design do Plankalkül, a primeira linguagem de programação de alto nível, ou seja, mais próxima da linguagem humana e mais distante da linguagem de máquina. Embora esta linguagem nunca tenha sido implementada na época, ela introduziu conceitos fundamentais da programação moderna, como tipos de dados e estruturas de controle.

Máquinas como o Z3, Colossus e o ENIAC foram construídas manualmente, usando circuitos contendo relés ou válvulas e frequentemente usavam cartões perfurados ou fita de papel perfurada para entrada e como principal meio de armazenamento. A maioria das máquinas desse período não possuía a capacidade de armazenar e modificar programas (com exceção do Z3). No ENIAC, um “programa” era definido pela configuração de seus cabos de conexão e interruptores, característica que distingue essas máquinas dos computadores modernos. A programação nessa época era exercida majoritariamente por mulheres, porém essa predominância foi gradualmente diminuindo com o passar dos anos.

1.4 O Nascimento da Computação Moderna

Até o momento, todas as máquinas (Babbage, Zuse, Colossus) seguiam o mesmo design proposto por Babbage: construíam-se máquinas para realizar cálculos e, então, organizavam-se instruções codificadas em alguma outra forma, armazenadas separadamente, para fazê-las funcionar. A grande mudança de paradigma ocorreu em 1945 com as ideias de Alan Turing e John von Neumann. Ambos perceberam que os programas deveriam ser armazenados da mesma forma que os dados. O Manchester Baby foi o primeiro computador eletrônico de programa armazenado do mundo e executou seu primeiro programa em 21 de junho de 1948. A arquitetura de von Neumann marca o início da era dos computadores modernos. Desde então, avanços foram feitos para torná-los mais rápidos, menores e fáceis de usar, porém seu cerne permanece o mesmo: a universalidade inerente ao computador de programa armazenado.

Na mesma década, Kathleen Booth, trabalhando no mesmo lugar que von Neumann, desenvolveu a primeira linguagem assembly—uma linguagem de programação muito próximo da linguagem de máquina. Porém, programar em assembly demandava um esforço intelectual considerável. As linguagens que surgiram posteriormente representaram tentativas de abstrair a linguagem de máquina para uma linguagem de alto nível, mais próxima da linguagem natural, humana. Embora diversas linguagens tenham sido criadas nos anos seguintes, foi apenas em 1954 que surgiu a primeira linguagem amplamente adotada: FORTRAN, desenvolvida na IBM por uma equipe liderada por John Backus. Atualmente, mais de 70 anos depois, FORTRAN ainda é utilizada para classificar a lista dos TOP500 supercomputadores mais rápidos do mundo.

A partir de 1955, a tecnologia dos transistores revolucionou a computação ao substituir os tubos de vácuo no design de computadores. Os transistores apresentavam vantagens significativas: eram menores e consumiam menos energia, consequentemente gerando menos calor que seus predecessores. O marco dessa transição foi o TRADIC Phase One, concluído em 1954, considerado o primeiro computador totalmente transistorizado.

A evolução tecnológica prosseguiu com a invenção dos circuitos integrados em 1958 por Jack Kilby, que posteriormente foi reconhecido com o Prêmio Nobel nos anos 2000 por essa contribuição. Um circuito integrado consiste em um conjunto de circuitos eletrônicos compostos por diversos componentes (transistores, resistores e capacitores) e suas interconexões. Esses componentes são minuciosamente gravados em uma pequena peça plana, conhecida como “chip”, fabricada com material semicondutor—inicialmente germânio e, atualmente, silício.

O período compreendido entre o final da década de 1960 e o final dos anos 1970 foi marcado pelo surgimento de diversas linguagens de programação, bem como pela consolidação dos principais paradigmas que conhecemos hoje. Simula, criada pelos cientistas da computação noruegueses Ole-Johan Dahl e Kristen Nygaard, destacou-se como a primeira linguagem projetada especificamente para suportar a programação orientada a objetos. Simultaneamente, Dennis Ritchie e Ken Thompson desenvolviam nos Bell Labs, entre 1969 e 1973, a linguagem C, voltada para programação de sistemas. É importante ressaltar que o desenvolvimento da linguagem C esteve intrinsecamente ligado ao sistema operacional UNIX, já que C foi criada justamente para facilitar a portabilidade deste sistema entre diferentes plataformas de hardware. Nesse mesmo contexto de inovação, a linguagem ML, concebida pelo cientista britânico Robin Milner, emergiu como pioneira entre as linguagens de programação funcional com tipagem estática.

Em termos de hardware, o microprocessador permitiu o último grande salto na história da computação. Sua evolução só foi possível graças aos circuitos integrados MOS (CMOS), que permitiram a progressiva miniaturização dos transistores. Atualmente, já somos capazes de produzir transistores com dimensões da ordem de 50 nanômetros, o que é surpreendente quando consideramos que o raio de um átomo de silício é de aproximadamente 0,13 nanômetros.

Por outro lado, a evolução das linguagens de programação foi particularmente marcante nos anos 1990, impulsionada pelo rápido crescimento da Internet. Nesse período, a produtividade dos programadores tornou-se algo importante, o que levou ao surgimento de diversas linguagens de desenvolvimento rápido de aplicativos (RAD). Essas linguagens eram acompanhadas por ambientes de desenvolvimento integrados (IDEs) e recursos de coleta de lixo. Como resultado dessa tendência, surgiram linguagens como Python, Lua, R, Ruby, Java, JavaScript e PHP.

A crescente popularização de novas linguagens de programação foi impulsionada pelos aplicativos mobile. Celulares e dispositivos móveis tornaram-se cada vez mais presentes no cotidiano das pessoas, aumentando significativamente a demanda por aplicativos. Alguns exemplos dessas linguagens incluem Dart, Kotlin, TypeScript e Swift.

Em 2012, surge a linguagem que será estudada nesta disciplina: Julia. Propondo-se a ser rápida e produtiva, Julia une o desempenho de linguagens antigas, com a produtividade de linguagens recentes. Foi desenvolvida por Jeff Bezanson, Stefan Karpinski, Viral B. Shah e Alan Edelman. O site https://julialang.org/benchmarks/ apresenta um benchmark comparativo de diferentes linguagens na resolução de alguns algoritmos. Pode-se observar que Julia demonstra desempenho equivalente ao da linguagem C.