COBOL 60 anos: As discussões técnicas do CODASYL

Photo by Zdeněk Macháček on Unsplash

Como foram as discussões dos participantes do CODASYL para definir a sintaxe e a semântica do Cobol tal como as conhecemos hoje?

Quem trabalha com o Cobol sabe que essa linguagem foi criada por um comitê chamado CODASYL (Committee on Data Systems Language). Mas os detalhes sobre os interesses políticos e comerciais de cada fabricante, além das discussões técnicas ficaram espalhadas em artigos, biografias e entrevistas de um ou outro participante.

Neste artigo tentarei consolidar o que eu li até agora sobre as discussões técnicas, os impasses e as “grandes polêmicas” que surgiram ao longo de 1959 para elaboração da especificação preliminar da linguagem. 

Missão de Curto Prazo

Em maio de 1959 o Departamento de Defesa dos EUA convidou cerca de 40 pessoas para uma reunião no Pentágono. Havia algo como 15 representantes de agências governamentais, 11 representantes da indústria usuária e 15 representantes dos fabricantes de computadores: Burroughs, GE, Honeywell, IBM, NCR, Philco, RCA, Remington Rand, Sylvania e ICT.

O objetivo era criar um comitê que trabalhasse no desenvolvimento de uma linguagem de programação que fosse comum a qualquer equipamento, barateando os custos de desenvolvimento e manutenção de sistemas.

Dessas primeiras reuniões no Pentágono saíram algumas das características esperadas dessa nova linguagem. Talvez a mais importante delas – muito influenciada pela consultoria prestada por Grace Hopper – era que a futura “linguagem comum” deveria ser baseada na língua inglesa, o que segundo ela permitiria que não-cientistas e não-engenheiros também pudessem adotá-la para desenvolvimento de soluções de negócio. Esse ponto é importante para entender algumas das discussões que comentarei mais adiante neste artigo.

Foram criados inicialmente dois subcomitês: um com tarefas de curto prazo e outro com tarefas de médio prazo. Um terceiro comitê com tarefas de longo prazo foi proposto, mas nunca foi instituído.

Uma das missões do comitê de curto prazo era avaliar as linguagens de programação existentes e apresentar em três meses um relatório com os pontos fortes e fracos de cada uma. Esse comitê era formado por:

  • Joseph Wegstein (presidente), da National Bureau of Standards
  • Coronel Alfred Ash, da Força Aérea dos EUA
  • Willian Carter, da Honeywell
  • Ben Cheydleur, da RCA
  • Mary Hawes, da Burroughs
  • Frances Holberton, do Laboratório de Matemática Aplicada
  • Jean Sammet, da Sylvania
  • Willian Selden, da IBM
  • E. F. Somers, da Sperry Rand

Esse grupo começou a se reunir por dois ou três dias a cada duas semamas, e decidiu focar a avaliação predominantemente em três linguagens mais ou menos consolidadas naquele momento:

  • FLOW-MATIC, criada por Grace Hopper na Sperry Rand;
  • COMTRAN, ainda em fase de desenvolvimento por Bob Bemer na IBM;
  • AIMACO, desenvolvida por Jack Jones na Força Aérea dos EUA.

A decisão de focar em três linguagens talvez tenha sido a primeira causa de divergências dentro do grupo, uma vez que RCA, Sylvania e Honeywell também tinham suas próprias linguagens em desenvolvimento.

O subcomitê, como já comentei, tinha como objetivo apresentar apenas um relatório com pontos fortes e fracos de cada linguagem; a ata da reunião que instituiu esse grupo não fala em presentar definições ou recomendações para o que eles chamavam de “futura linguagem de negócios comuns”, que era o objetivo final do CODASYL. Mas as nove pessoas desse subcomitê avançaram sobre esse tema e, em dezembro de 1959, mostraram as primeiras definições do que viria a ser o COBOL.

Obviamente, nove especialistas em programação discutindo vocabulário, regras sintáticas e regras semânticas de uma nova linguagem não aconteceria sem divergências e discordâncias. E foram muitas.

 Acervo Pessoal

ADD, SUBTRACT, MULTIPLY e DIVIDE… ou COMPUTE?

Algumas das polêmicas mais curiosas envolve a definição de operadores aritméticos.

Uma das premissas da nova linguagem era que pudesse ser adotada por não-cientistas e não-engenheiros, ou seja, por pessoas que não precisassem dominar o simbolismo matemático para construir programas.

Logo, parte do grupo queria que operações aritméticas fossem codificadas com verbos óbvios (somar, subtrair, multiplicar, dividir) ao invés de fórmulas. A outra parte do grupo achava que isso complicaria o processo de codificação (ao invés de simplificar) e defendia o uso de um verbo “computar” seguido de uma fórmula.

Após semanas de discussão, o relatório final recomendou as duas soluções.

DIVIDE INTO ou DIVIDE BY?

Ainda que as duas formas sejam gramaticalmente corretas na língua inglesa, a segunda (DIVIDE BY) é mais natural.

O problema é que já haviam decidido que operadores aritméticos deveriam deixar o resultado da operação na última variável mencionada (como, por exemplo, em ADD 1 TO CONTADOR).

Logo DIVIDE A BY B deveria deixar o quociente na variável B, o que pareceu confuso para parte do grupo que defendia o DIVIDE B INTO A.

A solução foi incluir a cláusula GIVING para que as duas formas pudessem ser adotadas.

DO ou PERFORM?

Jean Sammet, representante da Sylvania, contou em artigo de 1979 que havia um forte sentimento anti-IBM dentro do grupo, inclusive por parte dela. Curiosamente anos depois ela saiu da Sylvania e foi trabalhar para a IBM. Mas naquele momento a IBM defendia o uso do comando DO (adotado, por exemplo, no FORTRAN) para controle de loops.

A maioria era contra e defendia um verbo como PERFORM, ainda que não houvesse argumento técnico razoável para essa preferência.

No final, venceu o PERFORM.

IF-THEN ou COMPARE?

Aqui a discussão era sobre umas das premissas que vinham sendo adotadas pelo pessoal que trabalhava na parte de language statements: IF não é verbo, e o grupo havia decidido que todas as sentenças procedurais deveriam começar com um verbo imperativo (“mova”, “some”, “faça”…).

Essa era uma insistência, por exemplo, de Grace Hopper (que atuava como consultora do grupo), e seu argumento é de que a maioria dos idiomas começa sentenças imperativas com um verbo. Desta forma seria fácil, no futuro, disponibilizar a mesma linguagem adaptada ao francês, ao espanhol, ao alemão etc.

A solução via COMPARE, no entanto, exigiria a construção de frases muito maiores para fazer sentido em inglês.

Venceu a codificação mais simples.

GO TO sequence number?

 Computer History Museum

Todas as linguagens de programação naquela época estabeleciam que as linhas de um programa deveriam ser numeradas sequencialmente. Como cada linha era um cartão perfurado, numerar cada cartão permitia que o programa reordenado em caso de necessidade.

Algumas pessoas defendiam que a nova linguagem ficaria mais flexível se, além de permitir o uso de GO TO parágrafo, também permisse GO TO número-de-linha. Parte do grupo, porém acreditava que isso aumentaria a complexidade do compilador e comprometeria a mantenibilidade dos programas.

Felizmente venceu a opinião do segundo grupo.

Comando DEFINE?

Este comando permitiria ao programador criar um “verbo” em tempo de codificação. Não consegui encontrar (até agora) nenhum documento que mostre como seria sua sintaxe, mas a ideia é que seria possível codificar na PROCEDURE DIVISION algo como:

DEFINE FIX

E depois usar o verbo FIX, seguramente com alguns parâmetros, em algum outro ponto da PROCEDURE.

Haveria também a possibilidade de codificar algo como…

DEFINE SSN = SOCIAL-SECURITY-NUMBER

…e com isso, a partir desse ponto, o programa reconheceria tanto SSN como SOCIAL-SECURITY-NUMBER como nomes de uma mesma variável.

Esse recurso já existia na linguagem FLOW-MATIC, e parte do grupo queria mantê-lo, alegando que isso facilitava a operabilidade de um mesmo programa em diferentes equipamentos. Em contrapartida, a outra parte considerava complexo e tecnicamente inviável.

Como sempre, depois de muita discussão, concordaram em manter a recomendação pela existência do comando. Ele foi apresentado no relatório de dezembro de 1959, mas nunca foi implementado em nenhuma versão posterior do Cobol.

READ/WRITE sem OPEN?

Parte do grupo defendia que arquivos deveriam ser automaticamente abertos no primeiro comando READ ou WRITE desses arquivos. Mas isso implicaria aumentar a complexidade da implementação desses comandos nos compiladores, uma vez que a abertura (e o fechamento) de arquivos depende fortemente das facilidades de I-O oferecidas pelo hardware e pelo software básico de cada equipamento.

Essa última corrente saiu vencedora, e a especificação da linguagem estabeleceu a necessidade de comandos OPEN INPUT e OPEN OUTPUT antes dos READs e WRITEs correspondentes.

OCCURS?

Muito se discutiu sobre a possibilidade de fazer referências a variáveis com subscritos. Na prática, isso significava decidir se o Cobol permitiria ou não a criação de arrays. A Sylvania já possuía uma solução que funcionava bem com arrays tridimensionais e por isso sua representante, Jean Sammet, defendia sua adoção pela nova linguagem.

Outras pessoas, porém, acreditavam que o uso de arrays era desnecessário para a maioria dos “problemas de negócio” que essa linguagem genérica pretendia endereçar.

Prevaleceu a existência de arrays e seus subscritos.

Noise Words

Uma das marcas registradas do Cobol é a permissão para uso de palavras opcionais que não têm qualquer influência sobre a análise sintática de determinados comandos.

Por exemplo, no comando READ abaixo…

READ file-name RECORD INTO data-name 
    AT END imperatative-sentence

…as palavras RECORD e AT são opcionais, mas o programador teria (tem até hoje) a possibilidade de utilizá-las apenas para fins de legibilidade.

Essa foi a posição que prevaleceu, mas é interessante observar o quanto os especialistas do grupo se preocupavam com a autodocumentação do programa e sua mantenibilidade no futuro.

USAGE

Uma das grandes dificuldades técnicas enfrentadas pelo grupo foi definir a melhor forma de representação de dados na DATA DIVISION. A dúvida era se deveriam declarar dados como eles “aparecem” no mundo exterior (naquela época, relatórios, cartões, fitas de papel…) ou declará-los como eles são armazenados internamente (em memória e/ou outros meios magnéticos).

Existiam diferenças significativas entre os formatos adotados por cada equipamento. Representá-los como aparecem no mundo exterior (por exemplo, zzz.zzz.zz9,99) traria enormes dificuldades para a construção dos compiladores, pois cada equipamento deveria traduzir isso para o formato interno do computador que executaria o programa. Por outro lado, acrescentar possibilidades sintáticas que atendessem à necessidade de todos os fabricantes também parecia inviável.

A solução foi a criação da cláusula USAGE.

Basicamente essa cláusula diria se uma variável seria utilizada para cálculos (COMP) ou para exibição (DISPLAY). Isso diminuiria a complexidade dos compiladores na medida em que cada fabricante teria que traduzir para seus formatos internos apenas as variáveis USAGE COMP.

 Bank of IBM 729 magnetic tape drives at the Computer History Museum IBM 1401 exhibit. Author: Arnold Reinhold.

READ REVERSE

A ideia de criar uma linguagem “independente do equipamento” levou também a discussões curiosas.

Em determinado momento propuseram um comando READ REVERSE, que deveria ler o registro (ou bloco) anterior de uma fita magnética. Para alguns fabricantes isso não seria um problema, uma vez que seus equipamentos contavam com instruções de máquina para ler uma fita para trás. Outros, porém, não tinham esse recurso.

O consenso foi retirar esse comando da especificação final.

ENVIRONMENT DIVISION

Quando o grupo começou a trabalhar, a ideia era que um programa na nova linguagem seria formada por apenas duas divisões: DATA DIVISION e PROCEDURE DIVISION; dados e comandos.

À medida que foram surgindo desafios para viabilizar a “independência de máquinas”, foi necessário pensar numa maneira de permitir ao programador fornecer alguns parâmetros que ajustassem o programa ao ambiente onde seria compilado e processados.

Assim, surgiu a ENVIROMENT DIVISION (repare que na primeira recomendação da linguagem não existia IDENTIFICATION DIVISION).

O objetivo da ENVIRONMENT era permitir que um programa fosse portado de uma máquina para outra sofrendo apenas pequenas alterações de parâmetros nas seções, parágrafos e sentenças dessa divisão.

Na prática, porém, em muitas situações isso foi inviável. Muitos dos parâmetros da CONFIGURATION SECTION, como por exemplo SOURCE-COMPUTER e OBJECT-COMPUTE, são apenas documentacionais até hoje.

Conclusão

Essas foram apenas algumas das inúmeras controvérsias que surgiram durante os trabalhos do chamado “grupo de curto prazo”.

Em abril de 1960, o Departamento de Defesa publicou a versão final da especificação, Initial Specifications for a Common-Business Oriented Language (COBOL) for Programming Eletronic Digital Computers.

Em 1961 foram lançados os primeiros compiladores baseados nessa especificação. Em 1965 a especificação foi atualizada, e em 1968 e 1974 foram publicados os primeiros padrões “oficiais” com a chancela do American National Standard Institute (ANSI). Essas especificações são atualizadas até hoje, mas agora pela International Standard Organization (ISO). Você pode ver aqui algumas implementações da versão ISO/2002.

Fontes:

  • History of Programming Languages. Richard Wexelblat. Academic Press, maio de 2014.
  • Initial Specification for a Common-Business Oriented Language (COBOL) for Programming Eletronic Digital Computers. USA Departament of Defense. Abril de 1960.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *