Você está na página 1de 32

Autobiografia

Arndt von Staa

2021
Minha história - 1

1. Introdução

Nesta autobiografia apresento lances da minha vida profissional acoplada à evolução


da computação, em especial, a que ocorreu na PUC-Rio.
Iniciei minhas atividades de computação em 1962, com um Burroughs B-205,
o primeiro computador visando ciência e engenharia e instalado no Brasil em 1960. Em
1962 ainda não se cogitava criar disciplinas ou mesmo cursos de informática, sequer
existia o termo “Informática”, adotado na PUC-Rio a partir do final de 1967. Cabe
mencionar que até o início de 1964 não existia qualquer programa formal de pós-
graduação no Brasil*.
O B-205 era uma máquina de 1ª. geração. Na minha vida profissional passei
por sucessivas gerações, máquinas, linguagens e infraestruturas de programação até
2018 quando me aposentei. Acredito que este texto possa ser interessante para quem
deseja ver a evolução da computação e a da academia voltada para Informática,
embora seja a partir de uma ótica pessoal minha.

2. Preâmbulo

Desde pequeno sempre quis ser engenheiro mecânico. Em 1961, com 18 anos, iniciei
meus estudos de Engenharia Mecânica na PUC-Rio. Neste ano e no início de 1962 eu
não tinha oportunidade para realizar estágios devido ao serviço militar obrigatório
que estava prestando. Em 1962 negociei um estágio, a ocorrer no início de 1963, em
uma fábrica de ferramentas industriais situada em Nova Friburgo. Tinha, também, a
intenção de procurar estágios em engenharia mecânica no Rio de Janeiro a partir de
março de 1963. Consequentemente, no segundo semestre de 1962 passei a ter muito
tempo livre.
Naquela época o curso de Engenharia da PUC (EPUC – Escola Politécnica da
Universidade Católica) funcionava como um colégio. As disciplinas de cada semestre
eram preestabelecidas e o horário das aulas era das 7 às 12. No início do segundo
semestre, o Pe. Amaral (uma espécie de Decano de Ciência e Tecnologia, obs. não
existia o CTC – Centro Técnico Científico) me encontrou sem fazer nada no corredor e
me convidou a participar em um curso de programação que iria ser oferecido às tardes.
O curso visava o computador B-205 instalado no CPD – Centro de Processamento de
Dados - da PUC-Rio. Este foi o primeiro computador instalado em uma universidade
na América Latina e visando a ser usado exclusivamente por engenheiros e
pesquisadores. Fui fazer esse curso, menos por querer ser programador, e mais por
interesse no que fazia aquela máquina enorme cheia de lampadinhas, que produzia
umas fitas perfuradas de papel cinza, e que se via na vitrine do ITUC – Instituto de
Tecnologia da Universidade Católica. Naquela época o ITUC era um enorme espaço
vazio que foi lentamente sendo “loteado” para diversos laboratórios de ensino e

* Segundo um dos diretores do FUNTEC/BNDE, a primeira defesa de dissertação de mestrado no Brasil


ocorreu em 1965 no Departamento de Engenharia Mecânica da PUC-Rio.

1
Arndt von Staa Minha história

pesquisa em engenharia*. Um dos primeiros desses “lotes” foi o CPD. Mais tarde esse
“lote” virou a Capela da PUC e, atualmente, 2016, é ocupado pela Empresa Júnior.
A eletrônica do B205 era valvulada, aquelas lampadinhas que emitiam uma
luz vermelha (procure na Wikipedia uma explicação do que são válvulas eletrônicas).
Outro conjunto de pequenas lâmpadas representava o conteúdo dos registradores
utilizados pelo computador (adicionador e sua extensão, dado corrente indo ou vindo
da memória, endereço da instrução corrente e indexador). A memória era um tambor
magnético (imagine um cilindro com 20 trilhas magnéticas, cada uma contendo 200
números) capaz de armazenar 4000 números de 10 dígitos decimais. Havia mais 4
trilhas, cada uma com 10 cópias repetidas de blocos contendo 20 números cada uma.
Essas trilhas ofereciam um acesso 10 vezes mais rápido aos dados e instruções, porém
limitavam código e dados em cada trilha a 20 elementos. O processamento de uma
adição levava em torno de 2,5 milésimos de segundo (hoje requerem em torno de nano
segundos). O computador era BCD (binary coded decimal), ou seja, para o usuário
parecia ser uma máquina decimal, enquanto que a eletrônica era binária. Cada dígito
decimal requer 4 bits, portanto os hexadecimais A, B, C, D, E e F eram combinações
proibidas e faziam a máquina parar caso fossem observados ao realizar algum
processamento. Mais detalhes sobre a história da aquisição podem ser encontrados em
Neves, Byington e Staa; “El B-205 em la PUC-Rio”, Núcleo de Memória da PUC-Rio.
De 1954 (primeiro computador comercial no mundo) até hoje ocorreu uma
evolução vertiginosa e absolutamente imprevisível de como criar circuitos eletrônicos
de alta confiabilidade, alta velocidade, e altamente compactados (integrados). Hoje em
dia toda a eletrônica dos potentíssimos computadores está contida em um ou mais
chips de circuito fortemente integrado medindo cerca de 1 cm por 1 cm e contendo
milhões de transistores. O B-205 pesava mais de uma tonelada. Um celular com muito
mais poder computacional (1.000.000 vezes mais?) e memória contendo vários Gbytes
pesa quanto? Além disso, celulares cabem num bolso e não requerem refrigeração. Já
o B-205 ocupava uma sala de bom tamanho e precisava-se mantê-la refrigerada a 20
graus Celsius. Contribuíram para esse desenvolvimento vertiginoso a pesquisa em
física, química, projeto e produção de circuitos integrados e, também em software,
entre outros em bancos de dados, redes, infraestrutura, linguagens de programação, e
processos de desenvolvimento de sistemas.

3. Programando o B-205

O objetivo do B-205 era disponibilizar um ambiente para cálculo de engenharia e


pesquisa. Certamente não deveria ser usado para processar dados administrativos. O
CPD tinha um professor como diretor, um técnico de manutenção, uma secretária e
uma equipe técnica toda formada por alunos da PUC. Éramos mais de 10 alunos que
desenvolviam ou adaptavam programas. Um excelente laboratório “hands on”.
Programava-se esse computador em linguagem de máquina. Não havia
assembler nem qualquer linguagem simbólica (ex. Fortran, Cobol, C++, Lua). Também

* Cabe mencionar que uma parcela significativa dos laboratórios que cursávamos eram os do IME _ Instituto
Militar de Engenharia.

2
Arndt von Staa Minha história

não havia sistema operacional. Cabia ao programador dizer onde, endereço físico, as
instruções e os dados iriam residir na memória. Por exemplo, a sequência de operações
a partir do endereço 1000:
1000 641000 buscar conteúdo do endereço 1000
1001 741001 somar conteúdo do endereço 1001
1002 121000 armazenar resultado da soma no endereço 1000 resultaria em
endereço 1000 contendo 1382001, obviamente destruindo o programa devido à
alteração do conteúdo no endereço 1000.
Como instruções, dados e endereços são números (como ainda são em todos
os computadores digitais modernos ou não), pode-se usá-los como valores aritméticos.
Em Fortran, C, etc. o código acima seria escrito A = A + B e o programador deixou de
saber onde ficavam os dados (A e B) e A jamais estaria no espaço do código, impedindo
assim utilizar instruções como se fossem números (mentira, sabendo como Fortran ou
outras linguagens geram código, pode-se perfeitamente alterar o código em execução).
Muitos não sabem que computadores armazenam somente números em um vetor de
números e acham que endereços são algo do tipo A, idAluno etc., quando na realidade
são formas simbólicas de batizar locais físicos onde ficam as instruções e os dados
desejados. Da mesma forma não sabem que a operação “+” é um número seguido de
números indicando onde estão os dados a serem usados e para onde vai o resultado
da soma. Letras e outros símbolos também são números que o equipamento de
visualização converte para a representação visual. Muitos também não sabem que
memória nada mais é que um enorme vetor (array) de bytes, possivelmente
particionado em blocos de memória virtual que delimitam o que pode ser acessado
por determinado programa residente em memória (i.e. processo - o termo usado
atualmente).
Em resumo, antes de programar tinha-se que fazer uma espécie de mapa de
memória. Era necessário saber o endereço real de cada instrução e de cada dado.
Acessos e ramificações referenciavam endereços reais. Devido à escassez de memória,
muitos endereços eram reutilizados, o que costumava dar uma enorme dor de cabeça
ao manter e ao diagnosticar a causa dos erros de processamento. Caso fosse necessário
inserir ou retirar uma instrução ou dado, era necessário redefinir quase todos os
endereços usados, além de precisar-se verificar se havia células reutilizadas.
Para programar uma coisa dessas, era necessário fazer primeiro uma espécie
de programação simbólica em papel a ser traduzida à mão para a linguagem de
máquina totalmente numérica. Cabe salientar que hoje em dia memória continua
sendo um baita vetor de bytes, sendo que a alocação das instruções e dos dados é
realizada pela linguagem de programação simbólica utilizada (ex. assembler, C,
python etc.) e pelo sistema operacional. Evidentemente, para reduzir o retrabalho
inútil, o texto pseudo simbólico, escrito em um formulário de papel, precisava estar
correto antes da tradução à mão para código executável acessando corretamente os
dados. Isso, por sua vez, implicava a necessidade de uma revisão muito cuidadosa do
código pseudo simbólico antes de fazer a tradução. Essa revisão deveria assegurar que
o programa pseudo simbólico estivesse (quase) correto. A revisão era feita aos pares,
ou por trincas, usando uma forma primitiva de walkthrough acompanhado por um
arremedo de “prova da corretude”. Pois é, muitas das técnicas de programação

3
Arndt von Staa Minha história

modernas descritas em inúmeros livros, já eram utilizadas de forma artesanal nos


primórdios da computação.
O computador continha elementos eletrônicos (mais de 3000 válvulas – duplos
tríodos e outras), diodos (estado sólido), resistências funcionando como fusíveis e
outros. Um tríodo pode estar no estado conduzindo, ou não conduzindo, dependendo
do estado de um controle elétrico. Constitui, portanto, a alma de um circuito binário.
Hoje em dia cada tríodo corresponde a um transistor. Em computadores de 2ª. geração
vê-se os transistores. Nos de 3ª. geração em diante eles estão escondidos em circuitos
integrados e se consegue vê-los somente com potentes microscópios. Além disso, a
eletrônica continha ainda inúmeros diodos, resistências, capacitores, indutores e
outros. Tudo isso queimava com certa frequência (no nosso caso, cerca de 1 vez a cada
48 horas). Hoje em dia substitui-se o chip, ou a placa de circuito impresso que o
contém. Além disso, circuitos modernos muito raramente “queimam”. Quando a
máquina parava devido a uma falha eletrônica provocada por um ou mais
componentes eletrônicos queimados, tornava-se necessário descobrir, com rapidez,
onde se encontrava a causa da falha. Tínhamos o esquema lógico de todo o circuito
eletrônico. Esse esquema ocupava um caderno bem grosso de folhas de tamanho
aproximadamente A2. O esquema lógico referenciava o componente físico que
continha cada fragmento do circuito lógico. Um componente físico era uma caixa com
8 válvulas (lembre-se: cada dígito decimal requer 4 bits…), vários diodos e resistências.
O esquema indicava também o jeitão da cobrinha verde a ser exibida em um
osciloscópio (procure na Wikipedia o que é um osciloscópio) caso tudo estivesse
correto. Uma vez ocorrido um defeito, imaginava-se, com base no mau
comportamento observado*, onde o circuito poderia ter quebrado. Ia-se ao caderno de
circuitos e com um osciloscópio confirmava-se se o componente em questão gerava a
cobrinha documentada ou não. Se não estivesse correta, trocava-se o componente e
verificava-se se agora estava tudo OK. Isso era feito por meio da execução de um
programa de teste do hardware (uma versão primitiva de teste automatizado). Caso o
componente candidato a culpado estivesse mostrando a cobrinha correta, era
necessário imaginar outro lugar (i.e., formular uma outra hipótese), até descobrir onde
estava o defeito. Hoje em dia isso seria chamado de debugging. Tirava-se o componente
que continha o circuito defeituoso, punha-se um igual já testado no lugar e ligava-se o
computador na esperança que tudo estivesse resolvido. Componentes defeituosos
eram consertados e testados na sala de manutenção e ficavam guardados lá até que
um similar desse defeito.
Circuito de computador é uma coisa que possui uma lógica bem definida. É
feita de circuitos relativamente simples AND, NAND, OR, NOT, TOGGLE (memória
de um bit) entre outros. Entendida a lógica passa a ser fácil entender o funcionamento
da máquina. Na realidade, para quem conserta falhas de circuito, não interessa saber
o porquê dos elementos eletrônicos. O que interessa é a lógica. Compreendida a lógica
pode-se consertar, e até mesmo mudar ou adicionar instruções.

* Resistências, quando queimam, produzem uma fumacinha azul com um cheiro acre intenso. É possível
proteger o circuito envolvendo uma válvula com uma resistência dessas. Logo, quando uma válvula
queimava podia-se “cheirar” onde se encontrava o defeito.

4
Arndt von Staa Minha história

Com pouca memória disponível, vale a pena dispor-se de operações mais


complexas. O indexador (o B-205 foi o primeiro computador a dispor de um
indexador) somente sabia reduzir uma unidade, quando chegava a zero ou negativo
ramificava para um endereço dado. Lendo a documentação do hardware, descobri
que, com um pouco de lógica a mais, era possível criar uma instrução capaz de reduzir
o indexador usando valores entre 1 e 99. Isso era útil, pois um cartão possuía 80
colunas. Perguntei ao diretor se eu poderia fazer a alteração. Ele permitiu. Muni-me
de uma pistola de soldar, de diodos e fios, e adicionei três instruções. Para a minha
alegria funcionaram! Para alguém acostumado com modernos circuitos de altíssima
integração, isso soa como maluquice, e é. Para mim, mero estudante de engenharia
MECÂNICA, foi uma oportunidade ímpar para aprender como funciona um
computador (os de hoje funcionam assim também, só que usam circuitos altamente
integrados contidos em chips) e, principalmente, a lógica que está por trás de tudo.
Como aprendiz de programação participei do desenvolvimento e da operação
de um sistema de simulação do controle da geração realizada por uma rede de usinas
hidroelétricas. O cliente era Furnas, e a especificação, usando fluxogramas, foi feita por
uma empresa de engenharia canadense. O desenvolvedor chefe, Jacques Cohen, havia
feito uma pós-graduação no exterior. Mais tarde, em virtude da saída do Jacques,
passei a manter e ampliar esse sistema.
Também para Furnas, adaptamos um sistema de load flow que, dadas as
características geográficas e de engenharia da rede de distribuição elétrica, calcula a
estabilidade esperada dessa rede, bem como sua capacidade de transmitir energia útil.
Essa rede interliga usinas e centros de consumo de energia. Esses dois sistemas
formaram a semente do moderno controle do grid de energia elétrica que hoje interliga
todos os geradores e consumidores do país.
Seguindo as instruções de um engenheiro civil, desenvolvi um programa para
calcular a resistência à flambagem (ver na Wikipedia) das colunas da ponte da
Amizade em Itaipu. Seguindo as instruções de um médico radiologista, desenvolvi um
programa para calcular a intensidade e o posicionamento dos elementos de um
aparelho de radioterapia, de modo que somente a pequena região cancerosa do
paciente fosse “queimada”. Os muitos outros programas não valem a pena serem
mencionados. Todos esses programas foram desenvolvidos em colaboração com o
cliente. Isso seria uma forma primitiva de desenvolvimento ágil?
A saída do computador era, ou uma máquina de escrever de martelinhos, ou
uma tabuladora IBM 407. A 407 usava circuitos baseados em relés e era programada
usando um painel cheio de furinhos nos quais se enfiavam fios e que eram encostados
a uma matriz de contatos elétricos que, por sua vez se conectavam a relés. A máquina
de escrever era terrivelmente lenta, além de falhar com frequência. A tabuladora
imprimia linhas de até 120 caracteres e também processava cartões perfurados. Na
época era considerada extremamente veloz (aproximadamente 100 linhas por minuto).
A programação usando o painel podia até fazer contas, ou seja, a tabuladora era na
realidade um computador eletromecânico. Para nós bastava que imprimisse as saídas
geradas pelo B-205. Um problema era imprimir letras. Fazia-se o computador gerar 40
dígitos (no cartão o corpo numérico) e 40 zonas (no cartão a zona 1 eram as letras de A
a I, a 2 as letras de J a R e a 3 as letras de S a Z e mais o “/”). Superpondo dígitos e

5
Arndt von Staa Minha história

zonas podia-se fazer a impressora imprimir as correspondentes letras. Programar esses


painéis requeria um tanto de arte e paciência. Aprendi a programar isso e passei a ser
o único programador de painéis da equipe.
Ah, antes que me esqueça, consegui me formar Engenheiro Mecânico no final
de 1965, apesar de inúmeras vezes achar muito mais interessante programar, testar ou
consertar programas ou hardware, do que assistir a monótonas aulas (preleções) de
engenharia. Em um semestre também fui campeão de totó…

4. Programando o B-200
Em 1964 foi instalado um B-200 no CPD. Visava aplicações administrativas. Era uma
máquina transistorizada provida de 4096 bytes de memória (mais tarde ampliado para
8192 bytes) em núcleo de ferrite (a Wikipedia explica o que é memória de núcleos de
ferrite). Núcleo de ferrite era (ainda é) uma coisa muito cara além de ocupar muito
espaço e requerer bastante energia. As primeiras memórias custavam cerca de 0,50
dólares o byte, no final da era de memória de núcleo de ferrite o custo havia caído para
cerca de 0,25 dólares. Considerando uma inflação americana de 800% de 1950 até 2020
tem-se uma ideia de como atualizar o custo. Um mega byte 1.000.000 * 0,25 dá, em
preços aproximados de hoje, cerca de 250.000 dólares! A título de estimar a evolução,
quantos mega bytes tem o teu celular? Quanto custam os celulares?
O B-200 era bem menor e um pouco mais rápido do que o B-205 e processava
cartões ao invés de fita perfurada. Já vinha com um assembler, ou seja, era bem mais
simples de programar. O grande problema era que cada instrução usava 12 bytes (A +
B → C era programado em uma única instrução). A consequência disso é que era
necessário controlar com muito cuidado e rigor o espaço de memória ocupado pelos
programas e dados, o que levava ao reuso de endereços para variadas finalidades. Na
realidade eu não gostava desse computador.
Eu, ainda estudante, já era o chefe do setor de programação e tinha uma
pequena equipe de programadores (estudantes de engenharia ou de economia). Nós
desenvolvemos uma folha de pagamentos para uma grande empresa japonesa. Neste
trabalho aprendi que é muito difícil fazer clientes contarem a história completa do que
querem que seja feito, bem como contarem as restrições que deveriam ser respeitadas.
Quando, depois de semanas de suor, entregávamos uma versão do programa, o cliente
testava e vinha com o comentário, o cálculo do INSS (ou o que era na época) não está
correto. Qual o problema, a fórmula usada está correta segundo a lei. É que falta
considerar os casos de empregados que pagam alimentos (sustentam os filhos tidos com as
mulheres de quem se separou). Muda-se o cadastro, muda-se o cálculo de descontos,
arruma-se tudo para caber na memória e apresenta-se o programa modificado ao
cliente. Feito novo teste, vem a resposta: Não está correto, um empregado pode pagar mais
de um alimento (havia um com mais de 3). Repete-se tudo e recebe-se o veredicto: Não
está correto. Brasileiro usa uma fórmula, japonês contratado no Brasil outra, finalmente japonês
contratado no Japão usa uma terceira. A nossa paciência e a memória do computador
esgotaram. Protestamos, mudamos a especificação para: “é obrigação do cliente
informar, a cada mês, o percentual de desconto INSS de cada empregado”. Ou seja,
desde que se desenvolve sistemas de software, por mais primitivos que fossem, é

6
Arndt von Staa Minha história

necessário dispor de uma especificação completa e correta, ou pagar a penalidade de


ter que realizar retrabalho, muitas vezes demorado e custoso.
Neste projeto aprendi, também, a importância do planejamento, a necessidade
da definição precisa e completa de todas as interfaces dos fragmentos de software e
das regras de conduta do desenvolvimento (processo?), assegurar a observação do
plano e o cumprimento das regras de conduta por todos os membros da equipe. No
início da era de desenvolvimento de programas em equipe, cada um trabalhava como
lhe apetecia. Quando terminava e tentava integrar com os programas de outros, nada
dava certo. Escrever de novo? De jeito nenhum! Então escrevia-se uma gambiarra para
conseguir integrar. Onde é que ocorriam os defeitos? Nas gambiarras. Aprendi que
gambiarras devem ser evitadas a todo o custo (infelizmente, hoje em dia ainda tem
gente que usa gambiarras ao integrar componentes). Ou seja, vale a pena pensar, com
rigor e antes iniciar o desenvolvimento de um sistema, quais as interfaces que existem,
o que cada trecho (módulo?) de programa deve fazer, que dados precisa receber, qual
a confiabilidade desses dados, e que resultados produzirá.

5. Intermezzo

Como havia dito, eu queria ser e atuar como engenheiro mecânico. Além disso, para
mim programação de aplicações administrativas não tinha graça alguma.
Provavelmente eu teria dificuldade em encontrar algum emprego aceitável visando
programação para engenharia. Engenheiros típicos usavam réguas de cálculo
(Wikipedia) e nem sabiam o que um computador poderia fazer. Então, voltei a querer
aprofundar-me em engenharia. Consegui uma bolsa do DAAD (Alemanha, Deutscher
Akademischer Austausch Dienst) e outra do Itamaraty para fazer um curso de
extensão em Stuttgart, na área de automação do processo fabril e de manejo do
estoque. Embarquei no navio (avião era proibitivamente caro em 1966) e fui para lá em
março de 1966. Matriculei-me em um curso de automação da operação de estoque,
outro de máquinas ferramenta dirigidas por controle numérico, outro de
transformação plástica de materiais e, finalmente, um divertido curso de ferramentas
e processos de produção usando estamparia não convencional. Estamparia usando
grossas chapas de aço inoxidável (talheres, vasilhames e apetrechos hospitalares) é
muito mais complicado do que estampar a lataria de um carro.
Naquela época, na Alemanha era proibido estudante estrangeiro fazer provas
na universidade. De maneira geral, provas e as aulas não tinham relação alguma.
Durante alguns anos o estudante assistia aulas e estudava a correspondente matéria
por conta própria e usando livros. Ao fim de alguns anos o estudante marcava os
vários exames que precisava fazer para conseguir um diploma. Depois de muito brigar
com a burocracia da universidade, recebi uma autorização especial permitindo que
fizesse exames, desde que não aplicasse para obter qualquer tipo de diploma. Fiz os
exames e fui bem-sucedido. Descobri, também, que era o único estudante naquela
universidade que já havia trabalhado intensivamente com computadores em
aplicações de engenharia. Na época, a universidade de lá usava computadores
somente para processamento administrativo, evidentemente, nesses CPDs alunos não
entram.

7
Arndt von Staa Minha história

Como sabia programar e entendia um pouco de eletrônica digital, o professor


de máquinas ferramenta de controle numérico ficou espantado. Ficou mais ainda
quando fiz os exames das disciplinas dele. Convidou-me fazer um doutorado em
máquinas ferramenta de controle numérico. Naquela época isso era um avançadíssimo
assunto de pesquisa. Hoje qualquer fábrica maiorzinha possui algumas dessas
máquinas. Declinei por motivos pessoais.
Durante o ano e meio que estive fora, fiquei imaginando como desenvolver
programas que aprendessem. O exemplo não poderia ser mais trivial: um jogo da
velha comum. Ou seja, eu passava as muitas horas vagas projetando na cabeça
programas capazes de aprender, corrigir aprendizado errado e, para economizar
memória, jogar fora o aprendizado que se tornasse inútil.
Retornei da Alemanha em setembro de 1967. Fui procurar emprego em
engenharia mecânica inovadora tanto no Rio de Janeiro, como em São Paulo. Somente
me ofereceram posições para engenheiro vendedor. Não era esse tipo de trabalho que
almejava, embora pagassem bem. Fui visitar meus amigos que permaneceram na PUC-
Rio. Contaram que a PUC passou a operar no regime de créditos, sendo as disciplinas
ordenadas por pré-requisitos. Também falaram das ideias de transformar a PUC em
uma universidade de pesquisa. No fim dessas conversas me perguntaram se eu queria
fazer parte de um departamento de computação a ser criado, porém, se eu quisesse
trabalhar na PUC, teria que fazer um doutorado no exterior. Isso era a opção que
interessava. Em outubro de 1967 fui admitido na PUC como Associado de Pesquisa.
Bootstrap é criar alguma coisa com ela mesmo. Desenvolve-se uma solução
pequena e possivelmente mal-acabada (um protótipo). Com essa solução desenvolve-
se uma nova, mais bem-acabada e, se necessário, vai-se repetindo. O programa de pós-
graduação do DI foi criado em modo bootstrap. Em outubro de 1967 iniciamos um
protótipo de programa de mestrado em computação ainda no Departamento de
Matemática. Éramos 5 estudantes que, em outubro de 1967, iniciaram o “curso de
mestrado protótipo”. O objetivo era estarmos preparados para atuarmos como
professores de cursos de programação para estudantes de engenharia e, também, de
um programa de mestrado a iniciar em março de 1968. Cada um recebeu um assunto
a estudar com afinco e ensiná-lo aos outros. Coube a mim aprender o livro 1 do Knuth
– Data Structures e ensinar seu conteúdo aos meus colegas. Sobrou pouco tempo para
programar.
Um dos problemas que havia era a falta de afinidade da computação com
matemática pura, o que era o assunto preferido do Departamento de Matemática. Foi
proposta a criação de um departamento voltado só para computação separado da
Matemática. Tornou-se necessário dar um nome a esse departamento. Depois de
muitas discussões escolhemos o termo Informática por ser mais abrangente do que
Ciência da Computação. A partir de janeiro de 1968 tínhamos o nosso departamento e
não era mais necessário estudar tudo o que existia na álgebra envolvendo números
imaginários. Passou a ser importante saber criar software. Além disso, já havia turma
de mestrandos a iniciar em março der 1968. Detalhes de como iniciou o programa de
pós-graduação podem ser encontrados no site do DI/PUC-Rio na aba História.

8
Arndt von Staa Minha história

6. Programando o IBM-1130

Quando voltei da Alemanha já havia sido instalado um IBM 1130 na PUC-Rio. Vários
desses computadores foram instalados em diversas universidades sob os auspícios do
BNDE (o S foi inventado mais tarde).
O IBM 1130 era uma máquina muito simpática. Possuía teclado, uma
impressora tipo máquina de escrever elétrica, disco (de muito baixa capacidade), um
sistema operacional primitivo, Fortran e Assembler. Além disso, possuía uma leitora
a perfuradora de cartões, impressora de linha razoavelmente rápida e uma plotadora.
Essa máquina foi instalada em 1966. O circuito era de baixa integração, ou seja, não se
viam mais transistores, pois estavam encapsulados em chips contendo alguns poucos
transistores. Uma placa de circuito continha vários chips. Nunca mais foi possível
adicionar instruções…
O IBM 1130 podia ser entendido como uma estação de trabalho em que, ao
invés de um display, havia uma máquina de escrever. Apesar de primitivo, isso
permitia desenvolver programas interativos.
Desenvolvi o programa que aprende a jogar o jogo da velha. Obviamente em
assembler, Fortran é para quem não tem coragem de programar coisas complexas... Só
Assembler permite o controle total da máquina. O programa funcionou a contento. Foi
distribuído para diversas universidades e parece que agradou. Muitos achavam
divertido que o programa xingava de “Burro!” os que cometiam erros grosseiros.

7. Programando o IBM 7044

No final de dezembro de 1967 iniciou a instalação do IBM 7044. Era um computador


de grande porte, mas já em fase de extinção. Nos Estados Unidos vinha sendo
substituído por computadores IBM 360 ou de outras marcas. Entretanto, ainda havia
diversas universidades americanas e canadenses que usavam IBM 7044 ou IBM 7094
(um irmão mais poderoso). A linguagem Fortran foi desenvolvida para essa máquina
com o objetivo de gerar programas quase tão eficientes como os desenvolvidos em
assembler por um programador talentoso. Isso explica algumas das características
estranhas dessa linguagem.
Para instalar e operar o 7044 foi criado o Rio Datacentro, ou seja, o RDC. Uma
máquina desse porte requer uma infraestrutura administrativa envolvendo várias
pessoas. Além disso, a máquina deveria servir a toda a universidade, além de
processar serviços para clientes. Evidentemente, isso não é atividade para um
departamento de ensino e pesquisa, embora a proximidade do RDC com o
Departamento de Informática seja bastante intensa.
O 7044 era de 2ª. geração. A memória, núcleo de ferrite, era de 32K de palavras
de 36 bits (corresponde a aproximadamente 192 K bytes). O circuito era de baixa
integração, ou seja, era possível contar os transistores e outros elementos eletrônicos
que existiam em uma placa. Na época era o computador mais potente visando ensino
e pesquisa instalado no Brasil. Possuía Assembler, Fortran e Cobol além de muitas
outras coisas. O treinamento dos primeiros operadores do RDC foi realizado na

9
Arndt von Staa Minha história

Universidade de Waterloo, Canadá. Nasceu aí a forte amizade do DI com Waterloo e,


mais tarde, desta com brasileiros de variadas universidades e interesses.
O 7044 tornou-se parcialmente operacional em janeiro de 1968 e destinava-se
ao ensino de programação Fortran a todos os alunos do CTC (Centro Técnico e
Científico) a partir de março de 1968 e, também, a todos os alunos de pós-graduação
de variados departamentos que necessitassem de acesso a um computador. Destinava-
se, ainda, a apoiar a pós-graduação em Informática.
Para viabilizar isso, havíamos adquirido um sistema Watfor da Universidade
de Waterloo. Esse era um compilador Fortran acompanhado de um supervisor
simples, era rápido, gerava um código pouco eficiente, mas correto, e destinava-se a
ser usado principalmente por alunos de graduação. Operava em modo de cafeteria:
entre na fila, entregue os cartões do programa, compile e execute o programa, continue
andando, tire o resultado da impressora, continue andando e, finalmente, pegue de
volta os cartões. A seguir verifique se, por acaso, funcionou corretamente. Caso tenha
falhado o aluno teria que o corrigir. O modo de correção usado pela maioria dos
alunos: Ah, acho que esse é o erro no código. Vai na perfuradora altera o programa e repete.
Continua errado. Debugging na base da achologia em geral, e por muito tempo, resulta
em: continua não funcionando.
Alunos mais espertos já sabiam que trabalhar dessa forma (tentativa e erro)
dificilmente dá um resultado satisfatório, apesar do enorme tempo dedicado ao
programa. Esses alunos espertos preferem examinar com vagar e cuidado a listagem,
procurando identificar o erro de código que pode explicar os erros e acertos da
execução. Depois de convencer-se que essa causa explica tudo, corrigem os cartões, e
passam na cafeteria, frequentemente podem ir fazer outra coisa, pois o programa terá
funcionado corretamente. Quem chega a um resultado satisfatório mais rapidamente?
Aquele que pensa antes de começar, ou aquele que digita e compila rapidamente? Esse
problema de disciplina ao desenvolver, testar e depurar programas foi exacerbado
com o advento das estações de trabalho e dos compiladores e depuradores rápidos.
Nós tínhamos dois problemas. O primeiro é que uma das máquinas do
conjunto 7044 veio errada. A saída impressa, a leitura e perfuração de cartões era
realizada num computador IBM 1401 ligado ao 7044. A fonte elétrica para esse
computador ficava na caixa que continha a leitora e perfuradora de cartões.
Infelizmente, veio o modelo errado: o sem a fonte. Consequentemente, o 1401 não pôde
ser usado, e entrada e saída somente podiam ser realizadas através das fitas
magnéticas ligadas diretamente ao 7044. Felizmente, a IBM tinha um 1401 instalado no
centro. Inventamos o terminal Kombi. Cartões perfurados e fitas magnéticas de saída
eram levados, por uma Kombi, para o centro da cidade. No dia seguinte traziam de
volta uma fita magnética com o que estava nos cartões enviados, e uma listagem do
que se encontrava na fita de saída enviada.
O segundo problema era que nem o sistema operacional (IBSYS) nem o Watfor
controlavam tempo de processamento, embora existisse um relógio que podia ser
consultado por programa. Não controlar o tempo de execução causa um enorme
problema. Muitos programas, principalmente os de alunos entram em loop,
consequentemente ficariam ocupando “eternamente” o computador. Então era

10
Arndt von Staa Minha história

necessário dispor de uma rotina de contabilidade que controlasse tempo de


processamento, número de linhas impressas e de cartões perfurados. Impressão era
feita em formulário contínuo bastante caro, então também precisava ser racionado.
Essa rotina seria adicionada ao sistema operacional IBSYS. Sobrou para mim
desenvolver essa rotina.
Existia um exemplo, em Assembler, de uma rotina de contabilidade, sem
comentários e com variáveis do tipo A, B, C, … Como entender isso? Como funciona
e o que faz o IBSYS? E o Watfor? Nunca havia visto código de um sistema operacional.
O programa tinha que estar pronto no início de março e já estávamos em janeiro.
Estudei, e acho que entendi, a rotina exemplo. Escrevi uma nova rotina de
contabilidade, obedecendo às regras básicas de boa engenharia de software. Usei
técnicas formais rústicas para mostrar que o programa poderia funcionar
corretamente. Perfurei os cartões, obtive uma listagem no 1130. Fiz as revisões e
correções cuidadosas dos cartões e entreguei os cartões ao motorista da Kombi. No dia
seguinte, a rotina foi compilada e executada. A fita de saída gerada foi para a cidade.
No dia seguinte recebi a listagem da compilação. Continha erros. Revisei, corrigi e
compilei mais uma vez. Recebi de volta zero erros e pus para rodar. Compilei e
executei, sem saber o que estava acontecendo (somente via as fitas magnéticas se
mexendo) e lampadinhas piscando. Funcionou, com pequenos erros. Corrigidos esses,
o programa estava funcionando corretamente. No entretempo chegou a leitora
perfuradora correta e agora podíamos dar partida no uso da cafeteria. Isso tudo
ocorreu antes do final de fevereiro. É raro ter-se que programar às cegas. Aprendi que
era possível dar certo, mas requer muita disciplina e uso de técnicas que hoje seriam
chamadas formais (leves). Na época essas eram bem rudimentares e ad hoc. Afinal,
Hoare ainda não tinha escrito os seus livros. Bem mais tarde usei a mesma abordagem
para desenvolver um sistema bem mais complicado para o COBRA-700.
Usei o 7044 para desenvolver inúmeros exemplos de estruturas de dados que
existiam no livro do Knuth. Assim assegurava que não falasse coisas erradas em sala
de aula. Eram coisas que hoje em dia fazem parte do dia a dia tais como pilha, lista,
árvore, tabela de símbolos usando hashing e outros. Entretanto, em 1967 isso tudo era
novidade.
Fortran não é recursivo. Porém, o prof Furtado precisava de uma linguagem
de programação recursiva. Descobrimos como funcionava o protocolo de chamada de
sub-rotinas usado pelo Fortran e demos para um mestrando desenvolver uma
gambiarra que implementasse a recursão, mesmo que limitada. É claro que eu também
desenvolvi a minha versão e, é claro, que gostava mais dela. Desenvolvi um programa
para simplificação simbólica de expressões algébricas. Esse programa, além de outros
macetes, tinha um particularmente interessante. Era possível fornecer uma lista de
regras de simplificação (patterns), por exemplo sin( X )**2 + cos( X )**2 ==
1, onde X podia ser uma expressão qualquer. O programa era capaz de verificar a
igualdade de expressões, mesmo que os nomes das variáveis fossem diferentes,
encontrar estruturas de simplificação na expressão objeto, aplicar a simplificação e
repetir até que nenhuma simplificação pudesse mais ser realizada. Era divertido
escrever expressões bem complicadas que resultavam sempre em 1 ou 0. Quase

11
Arndt von Staa Minha história

ninguém acertava usando algebrismos manuais. Infelizmente não guardei os cartões


nem a listagem do código quando saí para o doutorado.
De janeiro a março de 1969, junto com o prof. Lucena e o Raphael Barbosa da
Silva, passei um período (um term de pouco menos que 4 meses) na Universidade de
Waterloo. O objetivo era cursar algumas disciplinas cujos créditos seriam transferidos
para o mestrado protótipo que estávamos criando e lecionando na PUC. Para o espanto
de todos os professores de lá, desenvolvemos, em pouco mais de um mês, um
compilador de Fortran para assembler 7044. Como era exercício, esse compilador foi
escrito em Fortran.

7.1. Programas que aprendem

Além de cursar algumas disciplinas, comecei a trabalhar no que seria minha


dissertação de mestrado: aprendizado em máquinas com recursos limitados. O tema,
o esboço da solução e o programa demonstração foram aprovados em Waterloo. O
exemplo era: um jogo da velha tridimensional capaz de aprender, corrigir e, se uma
jogada deixasse de ser usada por muito tempo, esquecer o que aprendera. Como não
existiam terminais interativos, desenvolvi o programa no IBM 360/75 da Universidade
de Waterloo usando a linguagem PL/1 e de modo que o programa jogasse pelos dois
jogadores. Interessante foi observar a curva de aprendizado. Durante algum tempo
nada era aprendido, até que, por acaso, um ganhasse um jogo. Daí para a frente a
rapidez do aprendizado (número de ações aprendidas) é sempre crescente até se
estabilizar (assintótico?).
A estrutura de memória do aprendizado era um grafo n-ário em que cada nó
correspondia a um dos possíveis estados do tabuleiro. Para cada saída a partir de um
nó (jogada a ser realizada), existia uma probabilidade. Probabilidade positiva indicava
que era bom jogar isso, negativa indicava que se deveria evitar isso. Quanto maior a
probabilidade, maior a certeza quanto à decisão. O aprendizado se dava através da
adição de nós no grafo e de aumentar ou diminuir os pesos das arestas de saída em
cada nó conforme o resultado de cada jogo. O valor a ser usado para corrigir as
probabilidades nas arestas das árvores diminuía conforme se regredia do nó final para
a origem da árvore. Ao jogar buscava-se a lista de saída no nó corrente e escolhia-se
aleatoriamente, entre as maiores positivas, uma das que tivesse um peso dentro de um
pequeno limite de variação. Assim evitava-se que o sistema jogasse sempre a mesma
coisa e se tornasse monótono. Além disso, algumas vezes escolhia-se um ramo com
peso menor com o objetivo de aprender mais variações de jogadas. Trazendo para os
dias atuais, o tal grafo se assemelha a uma versão bem rudimentar de rede neural. Isso
em 1969, quando esse assunto não era conhecido. Acabei dando um seminário de
inteligência artificial no DI. Porém, por achar que IA não tinha futuro (requeria
máquinas muito mais poderosas do que as existentes). Nunca mais toquei nesse
assunto.

7.2. Compilador de compiladores

Depois de voltar do Canadá, desenvolvi, obviamente em macro-assembler, um filtro


léxico. Esse é um analisador léxico convencional criado a partir de uma especificação

12
Arndt von Staa Minha história

redigida em linguagem regular, com uma tabela de símbolos dividida em quatro


segmentos. Um, constante e pré-definido, continha os operadores (+, =, etc.) e símbolos
especiais (do, if, while, etc) e um id correspondente. O segundo recebia, a partir de
alguma forma de declarar na linguagem de programação sendo criada, os símbolos do
programa sendo analisado, criando um id único para cada um deles. O terceiro
continha as declarações de funções próprias da linguagem de programação e
respectivos nomes junto com a lista de tipos dos parâmetros. O quarto recebia
declarações de funções do desenvolvedor definidas na linguagem de programação em
uso, junto com a lista de tipos dos parâmetros. Adicionando-se o tipo aos nomes,
resolvia-se o problema do controle de tipos (igualdade de tipos) dos parâmetros ao
analisar o programa e gerar o código correto no que toca o uso de tipos. Não era feita
a conversão de tipo dado para tipo esperado. Basta o id conter a identificação do
elemento, de que tabela e do seu tipo e sabe-se verificar se a parte em análise está
correta do ponto de vista dos tipos sendo manipulados. Converte-se assim um
programa simbólico extenso em uma curta sequência de ids (números), e válido do
ponto de vista dos tipos usados.
Agora que o problema da análise léxica estava resolvido, que tal desenvolver
um tradutor genérico T capaz de transformar um programa escrito em uma linguagem
L, traduzindo-o para o código de uma máquina hipotética H? Cabe observar que a
“máquina” hipotética pode ser outra linguagem. Dispondo do interpretador (ou
compilador) de H podemos executar o programa gerado. Usando uma linguagem T
podemos escrever um programa capaz de gerar o código H a partir de L. Suponha
agora que a definição da linguagem T contenha patterns (uma estrutura sintática de L
e que pode aparecer em um programa escrito em L e respectivo código H gerado) que
reconhecem parte da linguagem L e gerassem o correspondente código H. Agora
podemos escrever um programa em T usando e abusando dos patterns disponíveis.
Podemos levar isso ao limite e escrever um analisador exclusivamente usando patterns.
Obviamente esses patterns definem a sintaxe de L. Agora associa-se a cada pattern como
gerar o respectivo código em H. Pronto, temos um analisador sintático de alguma
linguagem L e o correspondente gerador de código para alguma linguagem (ou
máquina) H. A linguagem T em que se escreve os patterns e respectivos corpos é
constante e, na realidade, corresponde a um compilador de compiladores, uma vez
que pode gerar uma infinidade de compiladores de algum L para algum H. Essa é a
teoria básica de um compilador de compiladores. Cabe observar que na época SLR,
LALR e similares não eram conhecidos.
Se os patterns geram Fortran, então dado um programa escrito em T teremos
como resultado um programa Fortran equivalente a L, desde a geração acoplada aos
patterns esteja correta. Esse compilador de compiladores, COMCOM, foi usado pelo
prof. Furtado e por muitos alunos. Como foi escrito em assembler, deixou de existir
quando o RDC trocou o 7044 por um IBM 370/165. Pelo menos tenho uma longa
listagem do código fonte, mas não tenho mais o 7044 capaz de executar o programa.
Lição aprendida, não use linguagens que não possam ser usadas em qualquer
máquina, por mais divertido que seja usar linguagens especiais. Por outro lado, ainda
não existia a linguagem C e, além disso, as linguagens existentes na época, não
permitiam portar programas entre diferentes tipos de máquina. Exceções eram Cobol

13
Arndt von Staa Minha história

e, com restrições, Fortran. Ambas dificultam o amplo controle sobre estruturas de


dados complexas.

8. IBM 360/75 em Waterloo

Em janeiro de 1971 comecei o doutorado na Universidade de Waterloo e defendia tese


em outubro de 1974. A tese foi teórica e girava em torno do problema: como
desenvolver programas usando bibliotecas de componentes, tipos de dados como
variáveis (definidos por um nome e pelas operações que eram capazes de processar) e
tratamento de exceções.
A tese visava resolver o problema do reuso generalizado de módulos (tipos)
em variados níveis de abstração, coisa inexistente na época. A linguagem Simula 67
apoiava parte dessas propriedades e serviu de inspiração para a pesquisa. Um módulo,
chamado de tipo, era uma corotina e os serviços eram prestados por pontos de retorno.
Mais tarde esses pontos de retorno viraram funções para facilitar a passagem de
parâmetros. O objetivo de variáveis do tipo tipo é resolver o problema modularidade
em que cada módulo implementa exatamente um tipo, ou, melhor, uma intenção,
tendo uma interface coesa e exata (nem mais nem menos) da correta implementação
da intenção do tipo. Por exemplo, estruturas de dados possivelmente aninhadas,
tornando precisos os parâmetros e operações capazes de realizar. Em outras palavras,
como especificar e criar módulos completos e que apresentam na sua interface todas
as funcionalidades coerentes com sua intenção. Ou seja, a especificação é precisa e a
implementação envolve todas e somente as funções em acordo com a intenção do
módulo. Cada tipo define as operações ou funções capaz de processar. Por exemplo, a
um tipo pilha pode-se associar funções tais como empilha, desempilha, testa-vazio, cria e
destrói uma específica pilha. Como é um tipo, podemos agora trabalhar com uma
variável do tipo pilha, possivelmente armazenando valores do tipo árvore (ocorre em
alguns compiladores), ou do tipo grafo, ou do tipo diagrama-estruturado. Em resumo, a
minha tese gravitava em torno dos fundamentos do que hoje em dia chamamos de
linguagens orientadas a objetos, e o que hoje é chamado de técnicas formais leves para
poder verificar a corretude dos programas escritos da forma proposta. Isso permite
criar e entender programas organizados em níveis de abstração, por exemplo o tipo
aluno implementa tudo o que se deve e/ou pode fazer computacionalmente com ele.
Por sua vez cada instância de aluno pode conter variáveis de outros tipos, por exemplo,
endereço, curso, histórico-escolar.
Um grande susto que levei foi a publicação de CLU pouco antes da minha
defesa. Felizmente, a banca achou que meu trabalho foi desenvolvido de forma
independente e que era substancialmente diferente de CLU. Infelizmente, nunca
consegui implementar uma linguagem e seu compilador visando essa concepção de
linguagem. Faltaram alunos com interesse, ou coragem, de enfrentar esse desafio. Para
mim faltou tempo. Perguntei ao meu orientador como transformar a tese em alguns
papers. Ele respondeu que o que deveria escrever era um livro. Fazer isso com um autor
no Brasil outro no Canadá seria virtualmente impossível, não existiam redes, nem
processadores de texto. Nunca foi escrito, se tivesse sido, talvez eu teria ficado
famoso…

14
Arndt von Staa Minha história

A minha caligrafia é horrível. De vez em quando nem eu consigo decifrar o


que escrevi. Eu não tinha a menor ideia de como resolver o problema de redigir o texto
formatado da tese, sem erro de datilografia e de acordo com os padrões exigidos pela
universidade, isso tudo usando uma máquina de escrever. Felizmente, a universidade
possuía vários terminais remotos, tipo teclado mais máquina de escrever elétrica que
interagiam com o computador central. Isso permitiria escrever, corrigir e no final
formatar à mão e imprimir no terminal. Um trabalho insano, demorado e pouco
confiável, em particular quando se observa a realidade – cada fragmento de texto passa
por várias alterações no decorrer da escrita e composição com outros fragmentos.
Manter a formatação padronizada é um trabalho hercúleo.
Um dia o Centro de Processamento de Dados anunciou que tinha adquirido
uma cadeia de impressão com 240 caracteres, que poderia ser usada em uma das
impressoras de linha disponíveis. A cadeia possuía maiúsculas, minúsculas, diferentes
sublinhados, diferentes acentos, números, cantos e linhas de caixas retangulares e sei
lá o que mais. Imprimir, quando necessário, alguma coisa sublinhada requeria
imprimir n vezes cada linha. A primeira com o texto a segunda com os acentos e a
terceira com os sublinhados, sempre respeitando a formatação do texto. Cabe observar
que impressoras laser ou de agulhas não existiam na época, nem existia alguém que
tivesse a ideia de desenvolver algo do gênero. Além disso o CPD não possuía um
programa para usar essa cadeia para escrever textos adequadamente formatados. Ou
melhor, o programa que existia para o IBM 360/75 era pouco confiável (dava erro com
frequência), difícil de usar, e cheio de restrições. Comecei a programar um formatador
em PL/1. Depois de um mês e meio com quase nenhum progresso abandonei a ideia.
Meu colega de sala sugeriu que aprendesse SPITBOL, um dialeto de SNOBOL, um
processador de strings, muito eficiente e fácil de usar. Em três semanas eu tinha um
formatador extremamente flexível, dirigido por declarações de formato de blocos de
texto, relativamente fácil de usar, e que não falhava. Para a alegria do meu orientador
escrevia as seções da tese sendo elaborada usando este formatador. É claro que a
versão final também. Trouxe o programa para a PUC que tinha um 370/165. Várias
teses em Waterloo foram escritas com ele. Inúmeros trabalhos e dissertações na PUC,
bem como o meu livro Engenharia de Programas foram escritos com ele. Por ter sido
escrito em SPITBOL, o formatador deixou de ser utilizado quando a PUC substituiu o
IBM 370/165 por um CDC. Hoje em dia é um aplicativo desnecessário, Word, LATEX
e similares resolvem o problema de forma muito melhor.

9. IBM 370/165 e CDC no RDC da PUC

Praticamente não usei esses computadores. Só usava o 370 para gerar textos
formatados com meu formatador.

10. PC com DOS

Nos anos 1980 ocorreu uma grande mudança na computação. Aparecerem as estações
de trabalho e os computadores pessoais. Isso teve um enorme impacto na forma de
programar e de ensinar programação. Óbvio que software para computadores de

15
Arndt von Staa Minha história

grande porte continuava sendo desenvolvido, mas as condições para fazer isso
tornaram-se bastante diferentes.
Em 1982 surgiram os PC IBM. Antes haviam surgido os Apple I e II e o
MacIntosh, mas esses eram muito caros, difíceis de usar em ensino de programação, e
difíceis comprar no Brasil por causa da reserva de mercado. No caso dos PCs existiam
muitas “fábricas”, o contrabando era significativo e a pirataria de software também.
Cabe lembrar que estávamos na era da Lei de Informática, que proibia a importação
de computadores médios e pequenos, além de dificultar a aquisição de software.
O CNPq doou estações SUN para algumas universidades, entre elas a PUC.
Agora tínhamos correio eletrônico, embora lento e um tanto complicado de usar. Toda
a minha correspondência internacional começou a ser feita com elas. A rede que
interligava essas estações nas universidades brasileiras (ainda não internet) era
coordenada pela USP.
Conexões entre computadores internacionais eram feitas através do LNCC
usando uma rede IBM. Essa conexão permitia transferir arquivos de um PC para
algum outro lugar espalhado pelo mundo desde que ligado à rede IBM, mais tarde
Bitnet, uma rede que interligava instituições de ensino e/ou pesquisa. O protocolo da
Internet ainda não existia. Ligações ponto a ponto usando linhas telefônicas privadas
eram comuns. Na PUC havia um (note: um) PC ligado através de uma linha privada a
um computador do LNCC. Passando um endereço Bitnet, informava-se para onde a
mensagem deveria ser passada. Dessa forma, conseguia-se enviar mensagens para
computadores em várias universidades no mundo, desde que estivessem ligados à
essa rede. Com isso passou a ser possível transmitir, de forma precária, arquivos da
PUC para a UCLA. No início dos anos 80 fui membro da Comissão de Programa do
ICSE. Um dia apareceu pelo correio (funcionava muito bem naquela época) um
envelopão contendo vários artigos a serem examinados. Depois de examinar,
precisava-se escrever um parecer para cada um deles. Gravei os pareceres escritos em
WordStar (editor de texto para PCs) em um arquivo contido num disquete, levei para
o PC ligado ao LNCC, dei o endereço do destinatário e despachei. Depois de alguns
minutos a transmissão foi concluída, aparentemente sem erro.
Existiam diversos processadores de linguagens para os PCs: entre eles Fortran,
C (novidade!), Pascal e Modula (outra novidade). Existiam diversos aplicativos, ex.
WordStar, VisiCalc, compositores de texto tipo Ventura da XEROX. Este era o melhor
compositor de textos existente na época e já trabalhava com janelas, mouse e outras
“modernidades”, (pena que a XEROX vendeu o Ventura para a Corel que o
pessimizou). Em resumo, PCs eram ótimos para ensino e o uso cotidiano simples.

10.1. Mosaico

Fora da PUC eu ensinava para empresas Análise Estruturada e Projeto Estruturado.


Desenvolver um diagrama de fluxo de dados ou um de estrutura é muito aborrecido.
Traduzi-lo para código é complicado e confuso. Era comum ser preciso desenhar três
vezes: esboço, rascunho cheio de remendos e versão final. Manter a coerência entre
projeto e código após alterações era extremamente trabalhoso.

16
Arndt von Staa Minha história

Para reduzir esse problema desenvolvi, em Pascal, um editor semi gráfico que
permitia editar estruturas de programas (projeto estruturado). Observei que se fossem
adicionados fragmentos de código aos blocos da estrutura, podia-se gerar o programa
final através da linearização dessas estruturas. Manutenção da coerência passou a ser
subproduto da alteração. O efeito era como se o programa final fosse construído a
partir de uma coleção de pequenos fragmentos de código coerentes com o projeto. Essa
ferramenta, Mosaico, servia para projetar a estrutura do código das funções, sendo que
um programa passou a ser uma coletânea de funções interdependentes. Cada função
tinha um objetivo simples e bem definido. Também permitia o empacotamento de
estruturas de código em módulos (semelhantes à programação orientada a objetos) o
que facilitava a modularização. A linearização transformava isso em um programa,
possivelmente extenso, corretamente endentado, com comentários úteis escritos pelo
programador e que estavam no lugar certo. Podia-se também adicionar assertivas –
código composto por expressões lógicas que permitem verificar se os dados e
estruturas de dados satisfaziam a sua especificação lógica. Isso permitia verificar ao
executar se o processamento estava correto. Ao linearizar era possível gerar código
com ou sem essas assertivas. Ótimo instrumento para teste, pois o programa com
assertivas executáveis, embora mais lento, acusa um erro pouco depois de cometê-lo,
facilitando significativamente o debugging.
Essa ferramenta, Mosaico, foi apresentada a uma empresa que resolveu
comercializá-la. Infelizmente, o modelo de negócio escolhido não era bom. Esse tipo
de ferramenta requer que se pense antes de escrever. Porém poucos programadores
sabiam (sabem?), ou queriam (querem?), fazer isso. A maioria gostava (ainda gosta?)
de sair escrevendo código sem pensar na sua organização (arquitetura e interfaces) e
no que cada fragmento deveria fazer. Ou seja, o foco não deveria ser a ferramenta, e
sim, ensinar a pensar para poder usá-la de forma proveitosa. A excessivamente baixa
rentabilidade da venda desse software levou a empresa a fechar o setor que
desenvolvia o Mosaico.

10.2. Talisman

Depois da falha do Mosaico, criei a minha empresa, Staa Informática, e iniciei um


projeto bem mais ambicioso: Talisman. A escolha desse nome tem nada de mágica.
Tinha que ser um nome não utilizado no setor de computação e que pudesse ser lido
e entendido por todos os idiomas europeus e americanos. Uma curiosidade, escrevi
um artigo sobre o Talisman junto com o prof. Lucena e que foi publicado na Divisão
Siberiana da Academia Russa de Ciências em Novosibirsk, obviamente escrito em
russo e usando letras em cirílico. Ilegível para nós. Não dá nem para saber quem são
os autores…
Talisman tinha por objetivo permitir a edição e integração de uma variedade
linguagens de representação gráficas e/ou textuais redigidas em uma variedade de
linguagens definidas pelo gerente do ambiente de desenvolvimento, usadas pelos
projetistas e desenvolvedores, permitir a interligação entre elementos de diferentes
representações, mesmo que fossem de diferentes linguagens de representação, dispor
de um dicionário de dados eficiente e virtualmente ilimitado coerente com o sistema
desenvolvido e mantido. Definir a geração de código para cada elemento de uma

17
Arndt von Staa Minha história

representação, permitir a geração de código compilável, a verificação da corretude


estrutural das diferentes representações, ter uma interface gráfica bem primitiva
(Windows ainda não existia).
A arquitetura de Talisman é de uma coletânea de meta interpretadores
dirigidos por uma sofisticada base de conhecimento, e que podia ser configurada ao
bel prazer do gerente do ambiente de desenvolvimento e/ou usuário, criando
linguagens de representação e ou alterando linguagens existentes. Permitia redigir
também os transformadores (tradutores) capazes de transformar representações para
outras, possivelmente código compilável. Também era possível verificar, com
limitações, a corretude estrutural das representações e das interdependências entre
representações, mesmo se estas fossem de linguagens diferentes.
Talisman é uma estrutura de interpretadores com linguagens específicas para
lipos de representação e relacionamentos. Isso permite especificar e implementar os
mais variados ambientes de desenvolvimento de software. Essas especificações são
armazenadas em uma base de conhecimento. Talisman foi desenvolvido em C,
inicialmente usando Mosaico. Quando passou a ter suficiente funcionalidade para
criar, manter estruturas modulares e gerar o código dos corresponentes programas,
convertemos as bases de dados de Mosaico para as do Talisman e agora
desenvolvimento e manutenção passaram a ser feitas com o próprio Talisman. Isso é
outro exemplo de bootstrap.
Como já foi mencionado, Talisman permite ao usuário definir um sistema e os
seus programas usando uma variedade de linguagens de representação, entre elas
diagramas de fluxo de dados, diagramas de máquina de estados, diagramas entidade
e relacionamento, diagramas de estrutura de programas, diagrama de tarefas de
desenvolvimento, e quantas outras que o usuário definisse e considerasse útil para seu
trabalho. Permite, também, a geração de código em diferentes linguagens de
programação. Associando fragmentos de código aos elementos e às arestas dos
diagramas, pode-se transformar o conjunto de diagramas em código compilável e
executável. Todos os diagramas podem ser combinados um com os outros, mesmo que
sejam de diferentes tipos. Usualmente, o desenvolvimento é “top down” usando
transformações e linguagens com diferentes objetivos e graus de abstração. Uso
Talisman até hoje. A última versão compilada é de 1996 e tem funcionado zero falhas
desde então.
O conjunto de diagramas pode também ser gerado “bottom up”. Ou seja,
primeiro se escreve o código e depois organiza-se ele, com muito esforço, em acordo
com as linguagens de representação de nível mais alto a serem utilizadas. Engenharia
reversa dá muito trabalho, pois exige a correção de diversos elementos para que o todo
faça sentido. Um aluno desenvolveu, como exame de qualificação, um conversor de
Pascal existente para C todo projetado usando um protótipo do Talisman. O programa
destinava-se a gerar tabelas LALR a partir de uma especificação formal da linguagem
de programação para analisadores da gramática da linguagem objeto. Foi um belo
exercício de engenharia reversa com o qual aprendemos muita coisa relativa a como
realizar isso de modo semiautomático, produzindo projetos e código satisfazendo
regras de boa engenharia de software. As poucas vezes em que pratiquei engenharia
reversa o resultado final foi satisfatório, embora muito árduo de realizar, uma vez que

18
Arndt von Staa Minha história

precisava identificar e reduzir os erros existentes de modo que passasse a ser possível
fazer manutenção “top down”. Porém sempre foi grande o trabalho de correção
estrutural ao produzir o código reengenheirado. Isso mostra que corrigir erros
estruturais depois de desenvolver e testar tende a ser muito caro e demorado.
Muitas das linguagens usadas em Engenharia de Software são gráficas. É
necessário, então, implementar um editor gráfico genérico e poder especializá-lo
usando a linguagem de especificação do Talisman. Definem-se os elementos gráficos,
caixa, bola, etc. Define-se o conjunto de todos os tipos de objeto permitidos,
considerando a totalidade de linguagens de representação manipuláveis. Para cada
linguagem, definem-se os tipos de objeto permitidos para cada um dos tipos de
elementos gráficos. Um mesmo objeto pode ser compartilhado em diferentes
linguagens e podem-se estabelecer relacionamentos, gráficos e/ou lógicos, com
objetos de outras linguagens.
Talisman é todo dirigido pelo tipo dos dados, consequentemente ao navegar
por uma ligação de uma linguagem para outra, é automaticamente trocada a
linguagem de representação em uso (os editores estão vinculados à linguagem em
uso). Por exemplo, um registro contido em um depósito de dados referenciado em um
fluxo de dados pode corresponder a uma instância de uma entidade em um diagrama
entidade e relacionamentos, ou, dependendo do nível de abstração corresponder a
uma tabela em um banco de dados. Também os elementos são tratados com respeito
ao seu tipo. Quando se quer escrever uma string, usa-se um formatador, quando se
deseja escrever um texto, usa-se outro, embora exista uma única implementação para
as duas formas. As relações sabem o tipo do objeto destino, permitindo disparar os
geradores de código apropriados.
Diagramas servem para pouco, a menos que exista uma sucessão deles que
culmine em código. Como são usados para especificar, e/ou projetar, é desejável poder
associar comentários, e código quando desejável e possível. Portanto, necessita-se de
um meta-editor que possa ser especializado para a cada linguagem de representação e
suas necessidades específicas. O conteúdo de um objeto pode consistir por diversos
fragmentos de texto, referências gráficas, e constantes textuais. Por exemplo, em um
while, tem se a expressão condicional, o código do corpo e o código final. Porém, o
corpo pode ser complexo, então este precisa ser linearizado antes de colocar o fecho
do corpo do while. Baseado nesse exemplo e outros, conclui-se que os editores devem
ser genéricos e poder ser especializados através de uma linguagem que configure
como editar, linearizar, verificar, etc. Finalmente, podem existir relacionamentos entre
objetos de diferentes linguagens. A solução foi, através de diferentes relacionamentos,
qualquer objeto pode relacionar-se com uma variedade de outros objetos cada qual
pertencente a uma ou mais linguagens de design. Como os objetos têm um tipo, cada
relação estabelece o tipo de origem e o tipo de destino permitido e a respectiva contra-
relação. Isso faz com que, por construção, as estruturas de referências estão válidas do
ponto de vista dos tipos utilizados.
Talisman permite, de forma atabalhoada, começar com uma arquitetura,
refiná-la para um conjunto de classes, essas para conjuntos de métodos etc. No fim
lineariza-se tudo e obtém-se um programa pronto para ser compilado. Infelizmente, a
integração com compiladores é fraca, portanto identificar onde, no projeto em

19
Arndt von Staa Minha história

Talisman, foi cometido um erro de sintaxe acusado por um determinado compilador


requer um tanto de habilidade. O mesmo vale para erros encontrados por intermédio
de debuggers.
Talisman foi desenvolvido a partir de 1988, e concluído em 1993, para PCs
convencionais operando com DOS e usando a linguagem C. Tudo bem primitivo, a
começar pela memória útil de somente 702K bytes. Dados e código tinham que caber
nisso. Talisman contém vários componentes: um sistema de janelas bem primitivo (não
existia Windows). O sistema de janelas permitia abrir janelas de qualquer tamanho em
qualquer lugar, mas obedecia a uma estrutura pilha. Possuía editor, verificador e
linearizador gráfico genérico (dirigido por uma linguagem de especificação de
gráficos). Possuía uma linguagem, compilador e interpretador usados para definir
como editar, verificar, linearizar e exportar o conteúdo textual de objetos.
Possuía uma base de dados NoSQL (o termo não existia na época, tampouco
existiam pacotes prontos) para armazenar os projetos sendo desenvolvidos. Usamos o
modelo de memória virtual segmentada definida no Multics. Um segmento é um
arquivo que contém páginas, que, por sua vez, contêm os elementos de dados. Um
simulador de memória virtual assegura que, do ponto de vista do usuário, o dado
desejado esteja sempre disponível em memória e que, se alterado, a página que o
contém seja gravada de volta no arquivo. Esse sistema traz várias vantagens: endereços
podem ser gravados uma vez que todos eles são relativos à origem do segmento. O
programador não precisa se preocupar onde estão e como trazer dados para a
memória, estes sempre estarão disponíveis atualizados na memória principal quando
se desejar acessá-los. Também não precisa se preocupar com gravar os dados, pois isso
será feito automaticamente sempre que uma página seja alterada. Além disso, resolve-
se o problema de tamanho de um projeto significativamente maior do que a memória
disponível. Essa solução é satisfatoriamente eficiente e procura automaticamente
trazer para memória as páginas relevantes em dado momento, i.e. o working set, e que
este esteja contido em poucas páginas, para caber na memória física. Os segmentos
podem estar em qualquer máquina acessível pela rede (Samba). Como os segmentos
têm uma estrutura genérica bem definida através do tipo das páginas, pode-se
desenvolver um verificador e um corretor do conteúdo de segmentos. Caso uma
página esteja errada decorrente, por exemplo, da falta de energia, é possível consertar
a base de dados com uma perda mínima de objetos.
Possui um editor de texto dirigido pela linguagem de linearização,
consequentemente fragmentos do texto editado podem advir de diferentes elementos
de projeto, escritos usando diferentes linguagens de representação e editáveis
respeitando a linguagem de representação que os gerou. Quando se salva um texto
editado, cada fragmento vai automaticamente para o objeto que o contém. O núcleo
do Talisman é portátil e completamente independente dos tipos de periféricos. Através
de driveres simplórios podem-se ligar os mais variados periféricos (repetindo,
Windows não existia). Como já mencionado, era fortemente comentado.
Uma das características desejada era que o sistema fosse dirigido pelos tipos
de dados dos elementos. Além disso, deveria poder adicionar, a qualquer momento,
novos relacionamentos, atributos, tipos de objeto, fragmentos de texto com semântica
própria sem precisar reconstruir as bases em uso. Usamos uma chave composta de

20
Arndt von Staa Minha história

modo que cada atributo tivesse a sua chave identificando o seu tipo. Dessa forma passa
a ser possível determinar como processar um atributo de objeto fornecendo
simplesmente a sua chave. Caso fosse adicionada uma nova relação ao conjunto de
relações disponíveis, é necessário somente informar as identificações das relações e
contra relações.
A base de dados foi desenvolvida inicialmente na forma clássica, ou seja, com
especificação e projeto mínimos. Foram usados mais de 3 meses para isso. Vivia dando
erro de execução. Refiz a base de dados usando uma estrutura formalmente
especificada. Cada elemento da estrutura possui uma definição formal. Cada função
possuía assertivas de entrada, as funções são pequenas. Desenvolvi junto um gerador
de teste estrutural, capaz de gerar dados e operações aleatórias e verificar a integridade
estrutural. Em menos de um mês ficou pronta, zero falhas desde 1993 (uso Talisman
até hoje).
Eu poderia falar muito ainda sobre o projeto Talisman, mas fico por aqui. A
maior parte do meu livro Programação Modular foi experimentalmente verificada
tendo o projeto Talisman sido usado como cobaia.

11. PC com Windows

Por volta de 1992 surgiu Windows 3. Para usá-lo era necessário ter um PC 386.
Carésimo. Comprei um e pude desfrutar de uma memória real bem maior e discos
com capacidade maior além de um controle de acesso a aplicativos dirigido pelos
hieróglifos modernos, conhecidos por ícones. Também foi possível interligar os
computadores que tinha em casa por uma rede local.
Em 1994 já era possível usar um e-mail mais genérico. Era possível baixar e
transmitir arquivos, mas tudo laborioso e lento. Também surgiu o WWW. Ainda
vagaroso, mas pelo menos facilitava várias coisas em especial baixar e transferir
artigos.
Em 1995 surgiu a Internet comercial no Brasil. Começou o desenvolvimento
de aplicativos que se aproveitavam da Internet. Não participei disso, pois estava com
a ideia fixa de desenvolver Talisman versão 5. Além disso era diretor do DI o que
tomava bastante tempo. Infelizmente, o projeto Talisman é grande demais para uma
pessoa só e os alunos têm hoje (justificavelmente?) outros interesses,
consequentemente o projeto acabou sendo suspenso.
Os computadores foram evoluindo cada vez mais. Surgiram redes de PCs e
similares em substituição a computadores de grande porte. No início de 2019 tornou-
se possível transformar a PUC em cerca de uma semana em uma universidade que
funcionava online, mesmo que de forma ainda incipiente. Do ponto de vista hardware
e software parece que está tudo bem. Do ponto de vista criação de disciplinas online e
satisfação dos alunos, ainda temos um bocado a aprender.

21
Arndt von Staa Minha história

12. Diretor do Departamento de Informática

Em março 1995 fui eleito Diretor do DI, cargo que ocupei, por dois mandatos, até
março de 1999. O período de 1995 a 1999 foi marcado por cinco eventos
transformadores e relevantes para o DI. A seguir relato esses eventos sem obedecer a
qualquer critério de ordenação.
Vários professores estavam envolvidos com projetos de pesquisa e
desenvolvimento contratados por empresas e que requeriam especializados recursos
computacionais além de software. Surgiu a ideia de criar laboratórios temáticos
envolvendo os grupos especializados e, dessa forma, ajudar no financiamento do DI.
Os laboratórios temáticos seriam utilizados para pesquisa e desenvolvimento
voltados para assuntos específicos a uma (ou poucas) área de pesquisa. Os laboratórios
deveriam ser autossustentados. Eles seriam custeados pelos projetos, ou instituições
de apoio à pesquisa. Em resumo, os laboratórios temáticos não deveriam utilizar
equipamentos de uso genérico, nem recursos financeiros da PUC ou do DI. Pelo
contrário, 4% do valor total (bruto, incluindo equipamentos) de cada contrato deveria
ser repassado para uma conta do DI (e 10% para a FPLF – Fundação Padre Leonel
Franca/PUC). Os recursos advindos do “imposto DI” e mais a participação nos lucros
dos cursos oferecidos pelo DI na CCE (Coordenação Central de Extensão), eram
utilizados para financiar a infraestrutura computacional dos professores, funcionários,
laboratórios de ensino e pesquisa genéricos e, ainda, financiar a assinatura de
periódicos e aquisição de livros para a biblioteca do DI. Observação, o DI tinha uma
das melhores bibliotecas do país voltadas para Informática. Também foram usados
para custear coisas mais prosaicas tais como giz, papel, XEROX e outros itens que a
PUC, devido a sérios problemas financeiros, não fornecia em volume suficiente. Nada
dos recursos recebidos dos laboratórios temáticos ou da CCE deveria ser direcionado
para professores, alunos ou funcionários do DI, exceto os explicitamente vinculados
aos projetos contratados. Esta política capacitou a criação de uma infraestrutura
essencial para um departamento de pesquisa bem qualificado, sem depender de
recursos PUC além dos necessários para manter a graduação. Outro efeito colateral foi
o de possibilitar que os projetos desenvolvidos nos laboratórios temáticos
financiassem alunos, corpo técnico e complementação salarial de professores, além da
aquisição e manutenção dos equipamentos especializados de que necessitassem.
Além das vantagens para professores e alunos, como esses projetos eram
usualmente de interesse de empresas, portanto deveriam gerar resultados úteis para o
contratante. Dessa forma assegurava-se que as pesquisas realizadas nos laboratórios
tivessem um forte viés aplicado. Dentre os mais de dez laboratórios existentes no DI,
menciono o TecGraf, atualmente um instituto da PUC, o LES – Laboratório de
Engenharia de Software e o LabLua – laboratório que mantém e evolui os
processadores da linguagem Lua reconhecida mundialmente. Observando os
resultados alcançados pode-se concluir que o conceito Laboratório Temático foi muito
bem-sucedido e extremamente útil ao DI. O conceito de laboratório temático acabou
influenciando vários outros departamentos do CTC a criarem estruturas similares.
Evidentemente, uma mudança dessas esbarra em muita resistência e inveja pelos que
não têm, não querem, ou não trabalham num laboratório temático.

22
Arndt von Staa Minha história

Devido à autonomia financeira alcançada, o DI foi capaz de criar uma


sofisticada infraestrutura de computação que beneficia todo o DI e as salas de aula
utilizadas por disciplinas do DI. Também viabilizou que a biblioteca, enquanto existiu
(o sistema de assinaturas da CAPES tornou-a desnecessária) , mantivesse assinaturas
de muitos periódicos além de evoluir o seu acervo de livros. Mas continuava o
problema de não termos uma boa infraestrutura computacional para ensino e que foi
resolvido somente em 1999.
Em 1996 o CNPq publicou um edital para a criação de incubadoras voltadas
para computação. Os professores José Alberto Sampaio Aranha (CTC) e Luiz de Castro
Martins (DI/TecGraf) criaram e submeteram o projeto InfoGene que veio a ser
aprovado pelo CNPq. O departamento de Engenharia Mecânica havia investido na
construção de um prédio para a sua incubadora, mas, devido à falta de recursos, não
conseguiu pô-lo em funcionamento. Com apoio da FPLF, o DI completou as
instalações desse prédio, hoje conhecido por Instituto Gênesis. Nele foi instalada a
incubadora InfoGene. Faltava aprovar os estatutos do Gênesis na universidade. Havia
resistência por parte de membros do Conselho Departamental que receavam que o
Gênesis se tornaria um sorvedouro de recursos financeiros. Coube a mim convencê-
los da importância de uma incubadora. No início somente empresas relacionadas com
Informática eram aprovadas. Pouco mais tarde passaram a ser aprovadas empresas
incubadas de diversos outros departamentos, tornando, assim, o Gênesis a incubadora
da PUC. Em 2004 fui agraciado com o prêmio “Memória Gênesis”.
O DI não tinha recursos para manter e evoluir sistematicamente o seu parque
de computadores nem a sua rede de computação usada na graduação e na pós-
graduação desvinculada dos laboratórios temáticos. O DI sequer tinha laboratórios de
ensino, em especial os voltados para a graduação e pós-graduação sem vínculo a
projetos. Havia um laboratório com poucos equipamentos que era gerido pelo RDC.
Depender de recursos esporádicos do governo ou da PUC estava começando a
dificultar a capacitação necessária para realizar o ensino de graduação. Para combater
essa deficiência, recomendávamos aos alunos que usassem equipamentos próprios
para poderem realizar os trabalhos práticos em casa. Na PUC havia para cada três
alunos de graduação pelo menos um com um PC em casa. Como o DI não tinha um
laboratório de graduação, e os do RDC eram poucos e deixavam bastante a desejar,
muitos alunos faziam trabalhos em grupo na casa de um dos felizes donos de PC.
Com base em uma legislação que permitia empresas fabricantes de
computadores direcionarem parte dos impostos para apoio a instituições de ensino e
pesquisa em computação, no final de 1999, a IBM doou ao DI/PUC cerca de 500 PCs.
Na época o prof. Marco Antônio Casanova era pesquisador da IBM e era responsável
por esta conta. Estas máquinas foram distribuídas entre outros ao DI, RDC, Gênesis, e
Empresa Júnior. No DI viabilizou a criação dos laboratórios de graduação e de pós-
graduação bem equipados.
O DI funcionava no quarto andar do prédio RDC. No quinto funcionava a
Fundação Padre Leonel Franca. Em virtude da diminuição significativa do número de
padres jesuítas residentes na PUC, a ordem procurou uma moradia menor do que a
que tinha na PUC. Com a liberação do prédio, hoje conhecido por FPLF – Fundação
Padre Leonel Franca, ele passaria a acomodar a FPLF, alguns laboratórios e

23
Arndt von Staa Minha história

departamentos, e um restaurante sofisticado. Tendo em vista a eminente desocupação


do quinto andar do prédio RDC, a existência de suficientes recursos em caixa e o anseio
de longa data por parte do corpo docente do DI de trabalhar em salas individuais,
propus fazer a reforma do quarto andar. A reforma do quinto andar seria realizada tão
logo a FPLF se mudasse para o prédio doado para a PUC. A reforma do quinto andar
foi realizada durante o mandato do prof. Daniel Schwabe 1999 a 2001.
Vencidas as resistências de alguns colegas e convencido o corpo docente do DI
que seria possível fazer a reforma em menos de dois meses e meio e entregar a obra no
prazo definido, iniciei o planejamento do processo de reforma junto com o engenheiro
que seria responsável por ela. Depois de mais de um mês planejando virtualmente o
dia a dia da reforma, iniciei a compra dos equipamentos e materiais necessários. Dessa
forma assegurava que a obra não iria sofrer delongas devido à falta de equipamentos
e/ou material. A obra iniciou no dia 19 de dezembro de 1998 e, para o espanto de
muitos, foi integralmente concluído e entregue no dia 28 de fevereiro de 1999, tal como
havia sido prometido. Em virtude dessa obra e a da realizada pelo prof. Daniel
Schwabe, temos hoje, como convém a um departamento que pleiteia ser de ponta, salas
individuas, salas de estudo, salas de aula e de reunião, uma infraestrutura elétrica e de
comunicação de dados poderosa e extremamente flexível. Este trabalho serve como
demonstração prática de que um planejamento meticuloso levando em conta todos os
aspectos do projeto, é uma forma de assegurar a satisfação tanto do aspecto técnico,
também o temporal e o financeiro.
O DI sediava o curso de Tecnologia em Informática, conhecido por P15. Havia
uma forte cisão entre o DI voltado à pós-graduação e (junto com o Departamento de
Engenharia Elétrica) à graduação em Engenharia de Computação. Enquanto a outra
parte era voltada ao P15. Embora o P15 da PUC gozasse de uma boa reputação e fosse
bem mais abrangente do que o projeto original criado pelo prof. Luiz de Castro
Martins, ele era desprezado por grande parte do corpo docente de pós-graduação. As
aulas do P15 ocorriam no final da tarde e à noite. Tinha uma administração própria,
tanto acadêmica como administrativa. Tinha um corpo docente de tempo parcial
próprio, em geral com baixa titulação, porém elevada experiência profissional em
computação. Além disso, os tecnólogos egressos do P15 em geral eram bem aceitos em
empresas, mas não o eram para a pós-graduação do DI. Em resumo, pode-se dizer que
o P15 era um corpo estranho no DI. Muitas universidades ofereciam cursos P15. As
universidades mais conceituadas haviam transformado ou estavam para transformar
o P15 em uma graduação plena em Sistemas de Informação ou em Ciência da
Computação. Na região do Rio de Janeiro havia um grande número de cursos P15, a
sua maioria de qualidade duvidosa, mas bem mais baratos que o da PUC. Resultou
disso uma queda acentuada de alunos cursando o P15. Depois de longas discussões,
houve a concordância de terminar o P15, criar uma graduação em Sistemas de
Informação cujo corpo docente seria em grande parte o corpo docente de pós-
graduação. Essa mudança foi aprovada pelo Conselho Universitário e implementada
em 1999, apesar da justificável insatisfação do antigo corpo docente do P15.
Em 2003 fui eleito mais uma vez para diretor do DI, posição que ocupei por
três mandatos até 2009. Totalizei então 10 anos como diretor do DI. O objetivo que

24
Arndt von Staa Minha história

persegui nesse segundo mandato foi consolidar mais ainda o viés acadêmico do DI. O
número de laboratórios temáticos cresceu e diversificou.
Há alguns anos a CAPES avaliava de forma pouco rigorosa os programas de
pós-graduação. Emitia conceitos de A a E. Desde o início até a alteração da forma de
avaliar o DI sempre recebeu o conceito A. Depois a CAPES passou a avaliar os
programas de pós-graduação de forma mais rigorosa e passou a dar conceitos
numéricos de 1 a 7. Exceto a primeira avaliação, em que ficamos com um 6, todas as
demais resultaram em 7.
Além de uma avaliação mais rigorosa, CNPq e CAPES passaram a exigir a
existência de Coordenadores de Pós-Graduação. Estes passaram a administrar
recursos, bolsas e programas de ensino, retirando, dessa forma, muitas das tarefas que
antes cabiam ao diretor do departamento.
Em virtude da saída, aposentadoria, falecimento e demissão de diversos
colegas, foi iniciada a renovação do quadro. Ao invés de reorientar e/ou fortalecer
grupos de pesquisa, a Congregação dos professores do DI preferiu assegurar a
manutenção do 7 da CAPES. Consequentemente, a busca de novos professores passou
a voltar-se para “publicadores”, isto é, para pessoas com um número grande de
publicações em periódicos e conferências de alto índice de impacto e com potencial de
continuar publicando.

13. Um pouco sobre programação correta

Nas seções anteriores identifiquei em linhas gerais os computadores nos quais escrevi
programas. A ênfase foi mostrar através de exemplos alguns dos problemas
encontrados ao desenvolver softwares de boa qualidade nestas máquinas. Nesta seção
falarei sobre a evolução das técnicas de garantia da qualidade dos programas, em
especial a qualidade por construção. Falarei também resumidamente alguns aspectos
de garantia da qualidade considerando a gestão do desenvolvimento.
Algumas preocupações que sempre tive são: o que é corretude? Como
desenvolver sistemas manuteníveis e corretos do ponto de vista dos seus usuários?
Como reduzir o custo de desenvolvimento e o de controle da qualidade de sistemas
corretos? Como reduzir os custos da evolução de sistemas, mantendo ou melhorando
a corretude?
Como já mencionei, no início era o caos, ou melhor programava-se em
linguagem de máquina. Especificação cuidadosa em geral não existia*, o que
evidentemente levava a alterações no que já havia sido feito. Para conseguir um
programa que fizesse o que se queria, e desenvolvê-lo com rapidez, era necessário, tal
como ainda o é hoje, procurar escrever programas corretos por construção. Há muito
tempo já se observava que os minutos a mais que se gastava demostrando que o
programa está correto antes de digitar a primeira linha, reduziam horas de teste,
depuração, reescrita e manutenção. Também possibilita estabelecer um processo de
programação que permitia desenvolver às cegas programas corretos.

* No caso do simulador da gestão de reservatórios hidroelétricos nós trabalhamos a partir de um fluxograma,

25
Arndt von Staa Minha história

Como demonstrar que o programa, ou um fragmento, está correto? No início


(1963), dado o código pseudo simbólico em papel usavam-se métodos similares a
walkthroughs, e somente depois de aprovado no walkthrough é que se partia para gerar
a fita de papel contendo o código e se executava o programa nela contido. Tal como
ainda hoje, descoberto um problema durante os testes, iniciava-se a procura da causa.
Para isso podia-se operar a máquina passo a passo, ou de breakpoint em breakpoint,
verificando a cada parada, se os registradores continham o que era esperado. Hoje em
dia utilizam-se debuggers que permitem verificar se variáveis selecionadas contêm o
valor esperado. Outro problema comum eram especificações incompletas ou
incorretas. Tal como hoje, isso leva a programas corretos com relação à especificação
anterior, mas que estão errados com relação à especificação atualizada e/ou com
relação aos interesses dos usuários variáveis no tempo.
Pode-se dizer que conceitualmente nada mudou de 1960 até hoje. O que
mudou foi a ordem de grandeza dos programas e a simplificação de se fazerem
alterações e verificações. O que faz um debugger? Essencialmente, permite acompanhar
execução instrução a instrução, ou blocos até chegar a um breakpoint. A grande
vantagem é que simplifica em muito o fato de ser realizado de forma simbólica e
permitir acompanhar a evolução dos valores de diversas e variáveis selecionadas.
Alguns até permitem que se altere o conteúdo de variáveis e/ou o código durante o
teste. Mesmo assim, gasta-se um bocado de tempo caminhando pelo programa.
Isso leva imediatamente à procura por uma solução para que se consiga chegar
próximo ao ideal do correto por construção. Um programa correto por construção é
um programa sem erro antes da primeira compilação, exceto os que o compilador é
capaz de detectar. Obviamente isso é um ideal, porém se o número de erros for
pequeno, o custo e o esforço para desenvolver, testar e manter diminui drasticamente.
Continua valendo a observação: o tempo gasto para se demonstrar que o programa
está correto, antes de executá-lo, é compensado significativamente pela redução de
trabalho de descoberta de erros, realizar a correção destes e retestar o programa. Isso
vale mesmo considerando os depuradores modernos.
No entanto, no início dos tempos da programação, não existiam técnicas
formais estabelecidas. Cada um inventava o seu jeito de mostrar que o programa a ser
testado tinha chance de estar correto antes mesmo de se partir para a sua execução.
Uma proposta de padronização da formalização foi publicada por Hoare no início dos
anos 1970. Havia um pequeno problema, a formulação e a prova da corretude eram
muito complicadas e dispendiosas. Estavam longe da competência do programador
mediano. Surge a pergunta: como criar uma forma quase igual, mas mais simples e
barata, mesmo que não tão precisa? Apareceu a ideia de usar assertivas de entrada e
de saída aplicadas a curtos fragmentos de código. Entre as assertivas, é relativamente
simples verificar-se a corretude usando uma forma de inspeção. O problema a resolver
passou a ser como escrever essas assertivas e assegurar que abranjam tudo o que
interessa ao código que englobam. Uma solução simples é escrever as assertivas como
comentários. Assim não se perde as assertivas de uma alteração para outra.
Que tal, na medida do possível, redigir assertivas como expressões lógicas que
indiquem o que deve valer para que um trecho de programa possa ser considerado
correto como parte do código? Caso sejam executáveis o efeito disso é que a parte do

26
Arndt von Staa Minha história

programa sob teste passa a se auto controlar durante a execução dos testes.
Evidentemente, assertivas incompletas deixam de identificar as falhas associadas à
incompletude delas. Em linguagens que permitem redigir-se código condicionalmente
compilável, pode-se deixar as assertivas no código final marcadas como código a ser
incluído somente quando se deseja testar o programa. Feito direito, isso permite testar
sem utilizar o debugger.
Assertivas de entrada e saída correspondem a uma especificação,
possivelmente parcial, do que o fragmento de código entre elas precisa receber e
produzir para que possa ser considerado estar correto. Se os fragmentos de código
controlado forem curtos, fica “fácil” demonstrar, antes de partir para digitação, que
esse código tem grande chance de estar correto. Isso reduz significativamente o custo
de teste e correção do programa. Medições informais mostraram que o custo do
desenvolvimento de um programa correto por construção, cai no entorno de 30%.
Nunca fiz uma medição rigorosa, por ser muito difícil fazer isso no contexto de
ambientes de produção.
Um problema correlato é como realizar os testes. Usualmente teste é realizado
submetendo-se o programa a dados artificias criados pelo testador. Evidentemente,
esses dados devem estar em concordância com a especificação. Além disso, é
necessário dizer quais os resultados esperados ao término de cada teste. O conjunto de
testes deve cobrir o código como um todo, além de cobrir condições de uso correto ou
incorreto do (fragmento de) programa sob teste. Porém deve-se testar também para
dados errados na expectativa de ver mensagens feitas pela instrumentação. Realizar
manualmente testes que satisfaçam esses requisitos é difícil, ou mesmo impossível,
considerando os custos. Mais uma vez surgem as técnicas formais. Que tal, ao invés
de digitar casos de teste inventados na hora, escrever um programa gerador de testes?
Para isso usam-se dados e resultados esperados a partir da especificação, levando em
conta dados válidos e não válidos. Para uma grande gama de programas isso é possível
ser feito. Mais uma vez temos redução de custos junto com o aumento da qualidade,
apesar do custo de desenvolver e depurar o gerador. Boa parte do Talisman foi
desenvolvida assim.
Isso explica a minha obsessão com relação ao uso de assertivas e técnicas de
geração de casos de teste. A literatura chama isso de “Técnicas formais leves”. No
papel, essa abordagem pode ser usada mesmo ao desenvolver programas escritos em
código de máquina. Era essencialmente isso que passei a fazer já desde os anos 1960.
Em 1973, durante o meu doutorado na U. Waterloo, dei parte de uma disciplina de
graduação gravitando em torno do desenvolvimento de software correto por
construção, em que eu mostrava o que são e como usar técnicas formais. Foi a primeira
vez que esse assunto foi abordado naquela universidade. Parece que pelo menos
alguns dos alunos entenderam…
Um segundo problema a infernizar a vida de quem desenvolve software são
especificações incompletas, incorretas ou evolutíveis. Infelizmente é quase impossível
evitar que especificações mudem no decorrer de ou após o desenvolvimento. Algumas
soluções usam técnicas formais ao especificar. No entanto, caso o software passe
frequentemente por novas versões, esta solução é excessivamente cara. Como são
utilizadas várias linguagens de representação, a complexidade e o grau de detalhe das

27
Arndt von Staa Minha história

assertivas acompanha o nível de detalhe de cada linguagem de representação. Além


disso assertivas podem ser escritas nos pontos cruciais dessas representações. Por
exemplo, ao projetar uma solução usando alguma linguagem de representação que
identifique processos (ex. DFD, máquina de estado, diagrama de estrutura, petri net)
pode-se identificar, o que deve ser verdade ao entrar, e o que deve ser verdade ao sair
de cada item da representação. Como essas linguagens são de alto nível de abstração,
essas assertivas também serão de alto nível de abstração, mas permitem verificar se a
especificação está conceitualmente correta do ponto de vista do processamento.
Infelizmente, na maioria das vezes as especificações são incompletas ou
mesmo incorretas quando se observa o que o conjunto de papéis de usuário* deseja.
Manter a integridade do conjunto de representações é trabalhoso e difícil de fazer. De
maneira geral técnicas de especificação formalizadas são ignoradas. Vem daí o meu
interesse de dispor de uma ferramenta que permita especificar em variadas linguagens
de representação, evidenciando as interdependências entre elas e, se possível usar
técnicas de geração e/ou de controle da integridade do conjunto. Essa é a ideia que
está por trás do projeto Talisman de que tanto falo em sala de aula. Infelizmente a
versão existente é muito precária, uma vez que foi escrita para operar num PC com 702
K de memória útil, sem usar Windows e sem uma noção clara do tudo que deve fazer.
Até o Windows 7 era possível utilizá-lo. A partir daí passou a ser necessário usar um
virtualizador de computador “nu” operando sob Windows 7. Além disso, ainda não
sabemos as características a serem observadas pelo conjunto de linguagens. Mesmo
assim, foi possível usar o Talisman para gerar, em menos de um ano, o conjunto de
todos os subsistemas requeridos por uma grande empresa de navegação.
Resumindo essa parte, O que interessa é assegurar que as especificações
estejam o mais próximo possível do ideal completo e corrueto considerando o que o
usuário deseja. Deve ainda permitir a evolução em níveis de abstração e facilitar a
alteração nos diferentes níveis de abstração, sem que isso desorganize o conjunto. Isso
requer uma boa componentização. Para sistemas pequenos essa abordagem
usualmente é pesada demais. Mas, para sistemas grandes, ou sistemas que precisam
ser zero erros (ex. grid elétrica, piloto automático), essa abordagem tem forte chance
de dar resultados satisfatórios a custos mais baixos do que os atuais.

14. Um pouco sobre o processo do desenvolvimento

Outro problema que afeta muito a qualidade e o custo do software é o processo de


desenvolvimento adotado. Uma equipe mal organizada, mal dirigida ou com controle
de qualidade precário, tende a produzir software com custos e prazos maiores do que
o necessário, além de ser de baixa qualidade e estar sujeito a uma manutenção corretiva
contínua e custosa. Um dos problemas é identificar o processo envolvendo um
conjunto de linguagens de representação. Outro problema é o grau de formalidade que
deveria ser adotado. O terceiro é a gerência de projeto. Uma observação
frequentemente mencionada é que a gerência deve ter a característica de uma
coordenação ao invés de uma de comando. A gerência deve se basear em planos

* Não interessa o que Maria ou João desejam, mas interessa o que o gerente e o caixa necessitam.

28
Arndt von Staa Minha história

factíveis, flexíveis e evolutíveis, considerando o estado do conhecimento que se tem


no momento a respeito da especificação, ou do projeto a ser desenvolvido.
No entanto, não basta ter um plano, precisa-se acompanhar o
desenvolvimento para saber se o plano está sendo observado. Ou seja, de pouco
adianta dispor de planos otimistas, infactíveis, ou cheios de lacunas. Na realidade, um
conjunto de planos é similar a um programa só que virtualmente impossível de testar,
uma vez que executar o plano corresponde a realizar o desenvolvimento. Para poder
produzir um plano factível, precisa-se de uma especificação realista. Infelizmente,
especificações evoluem à medida que os projetos são desenvolvidos. Alterações
podem corresponder a vultosos custos adicionais e a uma grande quantidade de
retrabalho (desenvolvimento e teste). Torna-se necessário aprender a planejar e definir
uma arquitetura, ou seja, quebrar o todo em componentes dos quis muitos não sofrerão
nenhuma ou poucas alterações. Para isso necessitam-se dados observados em projetos
já realizados. Esse é um tema que venho discutindo já desde 1980, evidentemente de
forma conceitual, uma vez que nunca atuei pessoalmente em um projeto “mundo
real”.
No início dos anos 1990 comecei a estudar o CMM – Capability Maturity Model
e o similar europeu SPICE. A grosso modo, estes modelos de processos vêm a ser um
conjunto de diretivas indicando um processo evolutivo de como criar e gerenciar
planos com cada vez mais precisão. Em 1996 orientei uma dissertação de mestrado que
abordava os três primeiros níveis do CMM. Em 1997 transformei essa dissertação junto
com outros dois alunos em um livro (Engenharia de Software com CMM, 1998)
explicando e exemplificando os 3 primeiros níveis do CMM. Uma curiosidade, no ano
1997 estive doente, tendo que ficar em regime de homecare durante vários meses. Eu
tinha um modem discado o que permitiu escrever o livro integralmente à distância. O
livro era uma versão comentada dos três primeiros níveis do CMM. Nos comentários
explicávamos o porquê da relevância das inúmeras práticas propostas pelo modelo.
Foi o primeiro livro a tratar desse assunto escrito em português.
Mais tarde a SOFTEX contactou a profa. Ana Regina Cavalcanti da Rocha
(COPPE) e que colaborou fortemente com a SOFTEX para criar o mps.br que vem a
ser uma adequação do CMMI (CMM versão 2) às condições brasileiras. O CMMI foi
adaptado por professores e alunos da UFRJ às condições brasileiras, levando ao
mps.br (Melhoria do Processo do Software) e à criação do SBQS – Simpósio Brasileiro
de Qualidade de Software dentro da SBC. Não participei diretamente do
desenvolvimento do MPS, mas creio ter influenciado a sua realização. A profa. Ana
Regina foi minha aluna de mestrado (Gerência de Projeto) e doutorado (qualidade de
software) assuntos fortemente relacionados com o mps.br.

15. Fim

Em 2018 eu me aposentei e virei Professor Emérito, ou seja, professor aposentado


merecedor de louvor. O principal motivo para isso: com 77 anos de idade e depois de
quase 60 anos de atividade em computação, ou melhor, em Engenharia de Software
no mundo real, eu cansei. Cansei de ter que reaprender coisas cujos conceitos são

29
Arndt von Staa Minha história

essencialmente os mesmos de n anos atrás, mas cuja forma de implementar muda a


cada poucos anos.
A evolução da computação está muito rápida e requer a frequente
aprendizagem de novos ambientes e linguagens de desenvolvimento de software.
Além disso, surgiu uma nova forma de tratar dados (data science). No fundo, exceto os
baseados em IA, todos os ambientes de desenvolvimento fazem a mesma coisa do
ponto de vista conceitual. Alguns são mais fáceis de usar, outros menos, considerando
o tipo de problema a resolver. Alguns são mais estáveis outros menos, considerando a
evolução real das necessidades dos usuários. Existem outras perguntas do mesmo
gênero. O que aprendi foi que avaliar Engenharia de Software na Universidade
dificilmente simula suficientemente bem o mundo real. Para fugir desse problema
procurei trabalhar junto com empresas. Os trabalhos mais bem-sucedidos foram as
colaborações com microempresas nascentes. Empresas grandes tendem a ter uma
equipe de desenvolvimento de software excessivamente arraigada com a forma de
trabalho que estão habituados a realizar,
O que mais gera problemas na atual forma de desenvolver software são as
milhares de bibliotecas, das quais uma boa parte não é confiável. Outro problema é a
aversão à padronização inerente aos desenvolvedores de software. Cabe observar que
o desenho técnico usado por engenheiros é único, padronizado, e usado igual no
mundo inteiro. Na realidade engenheiros têm problemas similares aos nossos:
máquinas evoluem ao serem criadas, prédios mudam ao serem construídos, linhas de
montagem evoluem à medida que são encontrados defeitos ou que o produto a gerar
muda. Porém, os desenhos técnicos são mantidos sempre atualizados, e procura-se
utilizar peças padronizadas.
Claro é difícil imaginar-se as diferentes necessidades do conjunto de potencias
usuários de componentes de software. Encontrar uma biblioteca adequada e confiável
passou a ser um problema relevante. Com acesso a vários sites de apoio, pode-se
resolver parcialmente esse problema. Evidentemente, isso traz consigo uma mudança
significativa de organização do trabalho. Além disso, a mistura de bibliotecas e
subsistemas leva a uma miscelânea de estilos de programação, potencialmente
gerando uma enorme confusão. Essa confusão torna os programas difíceis de ler,
compreender e manter, além de ser fonte de inúmeros defeitos.
Exemplos. Quais são as exceções geradas por rotinas de uma biblioteca de
terceiros? Quais são os requisitos de qualidade dos dados que transitam nas interfaces?
Como evoluem essas bibliotecas à medida que são atualizadas e ”melhoradas”? Como
desenvolver em condições reais, com celeridade, programas corretos, confiáveis,
adequados aos usuários e fáceis de manter? Como padronizar os ícones e as interfaces
com o usuário utilizadas em diversos aplicativos? Um exemplo, por que os sistemas
de streaming não apresentam a mesma interface? Alguns deles oferecem interfaces
diferentes para cada filme.
Na realidade, devido à possibilidade da interação, o usuário passou a ser parte
do sistema de processamento de dados. Uma interface humana mal projetada pode
pôr em risco a percepção da qualidade do sistema como um todo, mesmo que o
software seja de boa qualidade.

30
Arndt von Staa Minha história

O grande problema está na definição de qualidade. Qualidade tem ponto de


vista: pode ser da visão do usuário, pode ser da visão de confiabilidade absoluta (zero
erros), pode ser da visão de evolutibilidade e manutenibilidade, e várias outras. O meu
ideal é desenvolver junto com o software objetivo um sistema de realização de testes
automatizados, idealmente usando dados escolhidos de forma aleatória. Software é
desenvolvido, em primeiro lugar, para humanos lerem e compreenderem, logo é
fundamental existir informações complementares que expliquem o que e porque está
sendo escrito. O maior custo de um software longevo é a sua manutenção. O maior
custo do desenvolvimento é o teste e consequente correção. Que tal procurar
desenvolver sistemas de modo que eles se auto verifiquem, a baixo custo, e que estejam
corretos ao serem usados em produção. O que é necessário? Refletir antes de escrever
a primeira linha. Saber, em cada ponto, o que representa estar executando de forma
correta.

31

Você também pode gostar