DataGramaZero - Revista de Ciência da Informação - v.4  n.5   out/03                            ARTIGO 04

Ilusão de Abstração: homografia e ocultamento de informação *
Illusion of Abstraction: homography and information hiding
por Luiz Carlos Brito Paternostro

 
 
 

Resumo: O título não é uma "abstração" da obra nem da seqüência de letras com que foi escrito. Do mesmo modo, os nomes "sugestivos" dos comandos das linguagens ditas "de nível mais alto que o de máquina" são rótulos de múltipla função. Codificam, organizam e documentam. Daí vem, talvez, a idéia de que aqueles nomes são "abstrações" dos procedimentos que determinam ou que controlam na máquina ao serem executados e que representam como algoritmos. Mas a máquina tradutora (um computador alimentado com um programa montador, ou um compilador, por exemplo) não converte abstrações em concreções, mas sim códigos concretos em outros códigos concretos. A convergência de regimes de codificação diferentes em um mesmo símbolo é apenas homografia. Considerar os computadores como hierarquias de abstrações serve para justificar, em nome da independência de representação, a sonegação de informação sobre os detalhes de implementação e um não-saber embutido e reproduzido nas metodologias de projeto.
Palavras-chave: Ocultamento de Informação, Abstração de Dados, Homografia, Orientação a Objetos, Marginalidade Tecnológica, Modelagem de Dados

Abstract: Title is neither an "abstraction" of the work it entitles nor an "abstraction" of the sequence of letters it has been written with. Similarly, the "suggestive" names of commands in "higher than machine level" languages are multiple function labels. They are used to code, organize and document. There comes, maybe, the idea of "abstraction" from, i.e. the idea according to which those names are "abstractions" of the procedures they represent as algorithms and they determine or control in the machine when executed. Nevertheless, the translation machine (a computer fed with an assembler program, or a compiler, for instance) does not convert abstractions in concretions, rather it gets concrete code from concrete code. The convergence of different coding realms in the same symbol is just homography. Considering computers as hierarchies of abstractions serves to justify, in name of representation independence, information concealment about implementation details, and embedded and reproduced knowledgelessness in project methodologies.
Keywords: Information Hiding, Data Abstraction, Homography, Object Orientation, Technological Marginality, Data Modeling
 

Há toda uma tradição de pensamento que insiste sobre o caráter produtor - antes que reprodutor - do modelo e da representação. O que significa, entre outras coisas, reconhecer o modelo não somente como tradução operacional mas, também, como ocultamento instrumental. A classificação agrupa e, neste mesmo movimento, separa; também oculta, portanto. Representar, modelar e classificar, e isto vale para qualquer atividade, é representar, modelar e classificar o que interessa. "Não submetida a uma escolha toda 'vista' seria inesgotável pelo discurso"; "quem representa (...) corta e isola propositadamente" **.


Introdução
Abstração de dados e ocultamento de informação são conceitos afins, representativos de princípios de projeto de software - em particular dos projetos de interfaces - já há algum tempo consagrados, por exemplo, nas assim chamadas "linguagens de programação orientadas para objeto".

Quando um procedimento é encapsulado e, como uma caixa-preta, reduzido em sua aparência a um mero protocolo de entrada e saída [1], torna-se - ou deveria tornar-se - inacessível fora daquele protocolo. Às vezes, chama-se a isto "ocultamento de informação", expediente que facilitaria o intercâmbio entre caixas-pretas: bastaria [2] descrever seu protocolo para que uma ferramenta (função) se torne acessível ao sistema de caixas-pretas. E a inacessibilidade fora do protocolo, nos dizem, eliminaria as incompatibilidades que forçosamente ocorrem numa padronização frouxa e pouco documentada. A idéia é: ninguém vai fazer uso "ilegítimo"- isto é, "obscuro" - da ferramenta se for impossível ou, pelo menos, muito difícil fazê-lo.

"Especificar" implica geralmente inventariar ou descrever minuciosamente alguma coisa, como, por exemplo, quando Ravi Sethi diz que "um programa é a especificação de uma computação". [Sethi:1]

Logo descobrimos que não é necessariamente assim. Sethi define "abstração de dados" como uma "especificação abstrata", uma especificação "que nos fala do comportamento de um objeto independentemente de sua implementação; isto é, uma especificação abstrata nos diz o que um objeto faz independentemente de como funciona." [Sethi:173]

Bem, neste caso, nada se especifica relativamente ao mecanismo, apenas a certas funcionalidades, certas entradas e saídas. Sethi define então "representação concreta" (e não "especificação concreta"; por que será?):

"Uma representação concreta nos diz como um objeto é implementado, como seus dados estão dispostos numa máquina e como estes dados são manipulados através de suas operações." [Sethi:173].

E, em seguida:

"(...)a noção abstrata da seqüência de primos de 7 a 47 pode ser escrita concretamente como 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47 ou pode ser disposta em elementos consecutivos de um vetor, ou mantida em células de uma lista encadeada. As disposições no vetor e na lista encadeada são implementações concretas."

Até antes do exemplo, parecia que tínhamos, por um lado, "o que um objeto faz" e, por outro lado, "como o objeto faz": duas coisas distintas, duas representações. Podíamos até imaginar uma descrição "mais concreta" ou "mais abstrata" de cada uma das duas representações. Agora não, a partir do exemplo isto já não é mais possível. O exemplo introduziu uma hierarquia entre as duas representações, entre o supostamente "abstrato" (o que se faz) e o supostamente "concreto" (como se faz).

Também somos avisados de que, misteriosamente,

"(...) a criação de especificações verdadeiramente abstratas, ou abstração de dados, é um ideal raramente atingido. Ao invés disso, como sugerem as expressões ocultamento de implementação, encapsulamento e independência de representação, objetos são empacotados de forma que detalhes de uma representação concreta, tais como disposição de dados, não são visíveis desde o exterior." [Sethi:173]

Ou seja, que de fato se oculta o código, embora raramente se possa "especificar" para que é que ele serve.
A menos, é claro, que se leia o código e a documentação do projeto, pois "(...) técnicas como o ocultamento de informação não são substitutos para um projeto bem concebido. De fato, tornam mais crítica a elaboração de um bom projeto.(...) Infelizmente, a mais difícil tarefa ao projetar um programa é descobrir os módulos adequados, os objetos adequados, o ponto de vista adequado desde o qual considerar uma computação" [Sethi:175]

O que chamamos neste trabalho de "independência funcional", discutida mais abaixo, coincide em alguns pontos, mas somente nesses, com o princípio informal de "independência de representação", estabelecido por Sethi assim: "Um programa deve ser projetado de forma que a representação de um objeto possa ser mudada sem que isto afete o resto do programa." [Sethi:173]

O que este programa especifica, afinal? Uma "computação" (seguindo a definição de Sethi mencionada acima)? A "computação" independe, neste caso, de certos detalhes de implementação. O que se preserva, o que é invariante, então, em um conjunto de implementações alternativas de uma mesma "computação"? Certamente não é uma seqüência de comandos que realize uma tarefa, se esta foi considerada "concreta"; mas será uma seqüência de comandos para outra tarefa, considerada "abstrata" pelo programador. Assim, deve-se impedir a comunicação entre estruturas "concretas" e regular a comunicação entre as "abstratas".
Compartilhar mecanismos "concretos"? Nem pensar. Se a proliferação de dispositivos redundantes desconhecidos tornar uma estrutura mais complicada e consumidora de recursos do que seria razoável, tendo em vista um trabalho modesto de "computação", é caso de se comprar mais memória, mais poder de processamento e de, quem sabe, programar um gerenciador adequado. Ou, então, de se reelaborar o projeto, de se reescrever o código desde o início, não esquecendo de deixar, como sempre, o interior de cada objeto "concreto" bem escondido dos demais. E assim por diante. A maior garantia de compatibilidade seria a mais absoluta falta de comunicação entre os códigos "concretos", a miséria na abundância, tudo sob a supervisão por vezes transparente (isto é, oculta), se tudo correr bem, de um sistema operacional imenso e complicado.

A ingenuidade é, certamente, um importante fator de redução da complexidade das tarefas.

Não apenas os dispositivos deveriam desfrutar dos benefícios do ocultamento e encapsulamento de informação. Por que não pensarmos em sociedades orientadas a objetos? [3]
 
 

"Bom"design
O ocultamento (e encapsulamento) de informação e o uso de tipos abstratos de dados como necessidades técnicas e metodológicas do "bom" design aparecem enunciadas explicitamente, talvez pela primeira vez, em um texto famoso de D. L. Parnas, publicado em 1972 [Parnas(May72)]. Desde então, aqueles princípios se tornaram praticamente ubíqüos, tanto em aplicações práticas como em trabalhos teóricos.

Os esforços do software livre, do copyleft e outros, em sua defesa do conhecimento compartilhado e do direito de investigar e modificar o que se usa, de ir além da "especificação abstrata", poderiam ser vistos como um contra-movimento relativamente ao "bom" design, ainda que não se reconheçam nesse papel. Não devem ser meros acidentes os obstáculos que enfrentam as tentativas de "facilitar" o trabalho do leigo no uso das ferramentas livres. Conhecer , aprender e ensinar implicam, de fato, um esforço considerável que não pode ser transferido para a máquina. Estigmatizar a trabalhosa exposição de um problema difícil como "defeito de design", ou tentar ocultar o que não se pode - ou não se quer - explicar, isto não é, certamente, compatível com o que defende o movimento do software livre.

Assim, o ocultamento de informação tem uma face que se pretende meramente "racional" [4]. Corresponderia a um aperfeiçoamento na especificação, produção e documentação de sistemas, programas, linguagens, interfaces e outros dispositivos. Mas é aquela sua mesma face "racional" o que realiza a separação radical entre saber operar e saber construir. Nas entranhas das metodologias e estilos de projeto se veiculam e se reproduzem concepções especiosas [5] de "abstração", de "generalidade" e de "isomorfismo".
 
 

Tecnologia da marginalidade
A interface sendo o lugar da comunicação homem-máquina é, também, o lugar da dominação [6]. O ocultamento de informação e a abstração de dados transmutam a marginalidade tecnológica em tecnologia de projeto. Com a proliferação dos "níveis de abstração" no encadeamento dos módulos, a marginalidade pode ser "encapsulada", isto é, "abstraída", "escondida" para o usuário, "a quem não interessam tais detalhes".
Pois o que Parnas recomenda, como vimos, não é simplesmente a abstração, o ocultamento de informação [7] inter-módulos, o encapsulamento: faz-se a apologia da não-documentação dos procedimentos de construção. Preconizando a abstração de dados como fórmula de otimização, as metodologias de projeto institucionalizaram o não-saber constituinte como razão de eficiência [8].

Os manuais de operação são indispensáveis, mas não como documentação explicativa dos dispositivos. Funcionam como "códigos executáveis", por assim dizer, por leitores tratados como "processadores" de instruções. São descrições de protocolos, interfaces tradutoras, cujo estudo, por mais profundo que seja, não conduz além de sua própria desconexão com a ferramenta original. As "cripto-analogias portáteis" - isto é, comercializáveis sem desvendar o seu segredo - privilegiam o aspecto criptográfico das comunicações. As analogias e as semelhanças observáveis ocultam-se sob a forma de "cápsulas" executáveis pela máquina (i.e., não mais observáveis) e adquiríveis (existe, de fato, um mercado de "analogias", isto é, de chaves de decodificação automática, de funcionamento desconhecido ou, pela teoria, "oculto").

"Um [programa] monitor simples, ao contrário do que se acredita, não é difícil de se escrever. Há algum tempo [antes de 1982], adquiri um cartão de UCP S-100, baseado no [microprocessador] Z80, para um projeto de consultoria. O [programa] monitor que foi fornecido com o mesmo foi projetado para utilizar um terminal serial, o que não iria funcionar nesta aplicação em particular. Gastei várias horas tentando dissecar o monitor, mas consegui localizar apenas a parte do código que lidava com entrada e saída de console; o fabricante certamente não desejava que o seu [programa] monitor fosse dissecado pelo usuário. Assim, tive que começar da estaca zero para obter o monitor que fizesse o que eu precisava." [Dahmke:60-61]

Dahmke falava de um programa muito pequeno, de muito menos de dois Kbytes (uns dois mil caracteres, ou uma página de texto, com 80 colunas e 25 linhas), administrando um espaço de endereçamento de no máximo 64 Kbytes. Pode-se imaginar o que significa o "ocultamento de informação" para dispositivos maiores, mesmo para os sistemas operacionais de microcomputadores bem antigos. Em 1989, o Windows 3.0 da Microsoft já tinha mais de dois mil Kbytes de código administrando normalmente um ambiente multitarefa de quatro mil Kbytes de memória. Ainda que modularizados, parcialmente documentados e permanentemente investigados, os sistemas atuais são obrigados a conviver com uma imensa sobrecarga imposta pelas práticas consolidadas de sonegação de informação, deliberadas - como nas proibições legais de divulgação de detalhes sobre os dispositivos -, ou mais ou menos cegamente incorporadas aos próprios mecanismos e princípios de projeto, construção e uso.

É também do início dos anos 80 a dissolução da comunidade "hacker" do Laboratório de Inteligência Artificial do MIT e o início do movimento organizado do software livre. O desenvolvimento, por Richard Stallman e outros, do Projeto GNU surge como uma resposta da comunidade às imposições cada vez mais restritivas e imorais da indústria relativamente ao uso dos produtos licenciados.

"Os computadores modernos daquela época, como o VAX ou o 68020, têm os seus próprios sistemas operacionais, mas nenhum deles era software livre: você tinha que assinar um acordo de não divulgação [nondisclosure agreement], mesmo que fosse para obter uma cópia executável. Isto significava que o primeiro passo para se poder utilizar um computador era prometer não ajudar a seu vizinho. Uma comunidade cooperativa estava proibida. A regra estabelecida pelos donos do software proprietário era a de que 'se você compartilha com o seu vizinho, você é um pirata. Se desejar qualquer mudança, peça-nos para fazê-la'." [Ver o artigo "O Projeto GNU", de Richard Stallman em http://www.dgz.org.br/fev00/Art_04.htm ].

Nêmesis
Há muito tempo se vem repetindo que "(...) o 'ocultamento de informação' está baseado em um compromisso: o sistema promete suprir tudo que você necessita para escrever programas robustos, e você, em troca, promete não olhar o que há debaixo da superfície. As partes internas de um sistema podem, então, ser melhoradas ou modificadas, sem que isto afete seu programa. A Microsoft pode aparecer com o DOS 5, em outras palavras, e o seu programa, escrito para o DOS 2.x, ainda será executável. Isto é como se supõe que o 'ocultamento de informação' deveria funcionar. O problema é que o MS-DOS não oferece [e não apenas o MS-DOS, é claro] aos que desenvolvem programas tudo que eles necessitam, obrigando-os a se apoiarem em recursos dependentes de máquina ou não documentados ." [9] [Schulman: xv]
Isto é, neste caso, o "ocultamento de informação", ao invés de constituir uma garantia da "independência de implementação", força uma construção dependente de máquina ou fora de padrão. Porque "tudo que os programadores necessitam" é de informação. Não se pode dar "informação sobre protocolo" negando "informação sobre o dispositivo" a que aquele protocolo dá acesso, com a esperança de que todas as ferramentas possíveis e imagináveis necessárias ao programador estão contidas no protocolo dado e são acessíveis por ele. Ao contrário, é a documentação sobre o dispositivo que poderia, talvez, salvar o padrão. Ainda que se diga que "isto não era comercialmente aceitável", o abuso e a complexidade se tornaram tão grandes que uma reação generalizada, como de fato aconteceu, seria perfeitamente previsível já naquela época: uma vez que não posso compreender a ferramenta, é melhor construir outra; já que vou construí-la, devo fazer isto em outras bases. Ou mesmo reutilizar procedimentos menos "modernos", mas melhor documentados, mais flexíveis e mais inteligíveis. Não é possível predizer o comportamento e as necessidades de projeto e de utilização futuros de um dispositivo; nem suprir antecipada e satisfatoriamente tais necessidades com produtos "bem elaborados", i.e., que possam tomar o lugar dos procedimentos "inconsistentes" e "desordenados" dos usuários (isto é, "um bando de piratas" potenciais) "sem controle".
 

Homonímia e abstração de dados
Receita para transmutar homografia em "abstração"

1) Dois (ou mais) significados (e/ou representações) autônomos (isto é, irredutíveis entre si) coincidem em uma mesma seqüência de elementos gráficos:
 
N E P W N      B A C H      A B C D E F
50 5 100 800 50      SIb SI      10 11 12 13 14 15

Isto é, os valores numéricos das letras gregas com que se escreve o nome de Nero e o nome de Nero coincidem na seqüência 'NEPWN'; o nome de Bach e as notas musicais correspondentes às letras com que se escrevem no sistema alemão coincidem na seqüência 'BACH'; as primeiras seis letras do alfabeto coincidem com os algarismos hexadecimais de dez a quinze na seqüência 'ABCDEF'.

2) Pelo menos uma das "acepções" possíveis da seqüência pode ser associada a entidades manipuláveis em certo contexto [10]. Isto é, deve haver um conjunto "operacional", no sentido em que dizemos "operacionalizar um modelo". Nos interessam, particularmente, as seqüências binárias manipuláveis por algoritmos.

3) Como cada seqüência possui um correlato (considerado mais "concreto") funcionalmente invariável (cada elemento da seqüência referencia um bloco), é possível associarmos combinações de elementos de uma seqüência a outras seqüências, e assim por diante, em construções hierarquizadas ("aninhadas") perfeitamente decomponíveis até a camada elementar.

4) Graças à preservação de integridade (invariância) funcional dos componentes de "menor nível" nas transformações de "maior nível", podem ser combinados e manipulados rótulos de blocos inteiros sem a necessidade de que seus componentes estejam disponíveis no momento daquelas transformações. Somente ao se realizarem as correlações encadeadas, ao se substituirem os rótulos pelos blocos a que fazem referência, é que a presença dos componentes de níveis mais elementares torna-se indispensável.

5) As "abstrações" têm em comum com essas transformações a propriedade de poderem ser pensadas sem referência às suas origens. Mas combinar automaticamente elementos funcionalmente invariáveis não visa o entendimento. O agrupamento deve seguir as regras mecânicas da combinação: ainda que sejam usadas homografias na escolha dos símbolos-rótulos que referenciam cada grupo, facilitando assim a recordação da disposição dos encadeamentos e mesmo de suas finalidades; ainda assim, as homografias "sugestivas" não são mais que coincidências entre representações particulares dos símbolos e as representações das abstrações.

Então, assim como os rótulos de um programa representam homograficamente nomes e endereços numéricos, nas notações facilitadoras de contagem
(um, dois, três, quatro, cinco, etc.) do tipo: etc.,
coincidem homograficamente no mesmo símbolo a representação sintética do algarismo - sua forma caraterística  - e a representação analítica de seu valor (o número de traços corresponde ao número representado) - com base em uma regra de composição (os traços se acrescentam em uma certa ordem).

Esta convergência entre códigos diferentes (forma e valor) em um mesmo substrato (símbolo) é tomada como "abstração" nos textos correntes sobre linguagens de programação, mas é apenas homografia. A aplicação da relação "tradutora" símbolo-endereço, uma "chave" de portabilidade dos códigos entre máquinas diferentes, não corresponde a uma "aplicação concreta do código abstrato". O código é portátil, mas não é abstrato.

O título não é uma "abstração" da obra. Suponha-se que, ao invés de nomes sugestivos (e correlatos de "endereços" de máquina reais), tivéssemos conjuntos quaisquer de símbolos arbitrários. Também neste caso, que certamente não corresponde a abstração alguma, poderíamos "traduzir", através de uma "chave", os tais símbolos em "endereços" para cada máquina - como ocorre quando um código é compilado. O "código" de símbolos arbitrários também seria portátil. Assim, não se trata de "nível de abstração" do código, mas da existência de uma "chave tradutora" concreta [11].

Por que se substituem, através de um programa desmontador ("disassembler"), códigos numéricos "de máquina" por rótulos literais? A manipulação em linguagem de montagem vem da facilidade de reconhecimento pelo homem de semelhanças e diferenças entre símbolos e combinações usuais - palavras e acrônimos emprestados das línguas naturais, ao invés de padrões numéricos. É mais uma questão de comodidade de leitura do que de "abstração" , ainda que nomes sugestivos evocadores das finalidades do código também cumpram um papel mnemotécnico na manipulação humana do conjunto de instruções. O que desejo aqui é chamar a atenção para aquele aspecto de facilidade implicado no uso de habilidades por nós dominadas, ao invés de discutir sobre a "abstração" que os rótulos representariam. O reconhecimento está muito ligado à organização (no sentido que a Gestalt dá a este termo) do material - o que não implica, nem descarta, aprendizagem anterior - que se apresenta à percepção. Isto se pode verificar na leitura de diagramas que formam "figuras" reconhecíveis, nos dados agrupados que formam totalidades organizadas reconhecíveis como unitárias, enfim, em diversos fenômenos estudados por Köhler, Koffka e outros psicólogos da Gestalt.

Os nomes "sugestivos" dos comandos das linguagens ditas "de nível mais alto que o de máquina" são rótulos de múltipla função. Daí vem, talvez, a idéia de que aqueles nomes são "abstrações" dos procedimentos que realizam na máquina e que representam como algoritmos. Mas a máquina tradutora (no caso um computador alimentado com um programa montador) não converte abstrações em concreções, mas sim códigos concretos em outros códigos concretos. Concretos e "meramente coincidentes" [12], por assim dizer, já que é a liberdade (arbitrariedade) na escolha dos "endereços simbólicos" o que permite o uso de "nomes" correlatos "sugestivos" para o programador.

Recapitulando, um nome de subrotina (nome que é traduzido automaticamente como, por exemplo, endereço inicial do código correspondente à subrotina) não é uma "abstração" da função, nem muito menos do algoritmo que a implementa; é um rótulo "sugestivo" - isto é, que recorda ao leitor uma informação qualquer que o autor do programa julgou relevante associar ao código (poderia ser o sobrenome do autor da subrotina, por exemplo). O "nome" é escrito como uma seqüência concreta de símbolos (aos quais correspondem biunivocamente estados significativos a serem mapeados na máquina concreta) e foi escolhido por, no mínimo, sua dupla função, a saber: como indicador de um endereço de memória (ainda que arbitrário, qualquer um, desde que singular, diferente dos outros) e como homógrafo de uma expressão "sugestiva". A múltipla determinação de um signo não implica nenhuma relação de dependência entre cada uma dessas determinações. Nem muito menos uma suposta relação de abstração-para-concreção que os manuais de modelagem de sistemas informatizados postulam (do tipo "top-down", "abstrações sucessivas do alto-nível para o baixo-nível" [13], etc.).
 

Analogia e materialidade do código
As noções de "abstração", "instanciação" e "generalidade" não se referem somente a certa metodologia de programação, mas supõem-se aplicáveis a qualquer computador como máquina genérica. Diz-se, por exemplo, que "computadores são hierarquias de abstrações construídas sobre exemplos eletrônicos de máquinas de Turing." [Jean-Louis Gassée, in Laurel:226]

Há nessa idéia de "abstração" uma certa obsessão com a chamada dependência de implementação que os programas deveriam evitar: sendo o software um componente da máquina, a "abstração de dados" procura a portabilidade daquele software, sua facilidade de circulação entre diferentes tipos de hardware.

Analogias muito usadas nas explicações da "abstração de dados" são a da bicicleta e a do automóvel. Em um esboço de bicicleta, dependendo da "função" que deve ser evidenciada, podem faltar, por exemplo, os aros das rodas. Para outros objetivos, os detalhes do assento são irrelevantes e podem - ou devem! - ser omitidos. Cada tipo de esboço busca representar uma parte das funções da bicicleta; são - nos diz um texto sobre linguagens de programação [Ghezzi:31] - "abstrações" das implementações concretas daquelas funções na "bicicleta real": é por isso que tais representações são portáteis, isto é, universais, aplicam-se a quaisquer bicicletas. No exemplo do automóvel, a mesma coisa. O painel, controles e assento interessam ao usuário; detalhes do motor e da transmissão, ao engenheiro. A universalidade (portabilidade) das funções representadas dependeria de seu "grau de abstração" em relação ao que ocorre nas máquinas concretas.

Na bicicleta e no automóvel concretos são óbvios alguns recortes (articulações e desmontagens reais ou ideais) que podemos fazer corresponder aos limites de entidades funcionais abstratas. Esses aspectos funcionais, contudo, não são eles mesmos "recortes", rigorosamente falando, mas "extrações", abstrações de uma totalidade sintética ideal. Associando a cada função abstrata um objeto concreto que "a realize", uma composição apropriada dos módulos concretos deveria, em tese, "realizar" aquela totalidade sintética ideal. Para que a montagem "funcione" , existem as especificações de tolerância e os ajustes por tentativa e erro. Tolerância e ajustes também em relação àqueles aspectos, de que falamos anteriormente, escondidos pela "abstração" no modelo.

Existem, contudo, funções abstratas não tão facilmente associáveis a partes de um objeto real. A refrigeração de uma máquina, por exemplo, depende tanto dos materiais como dos volumes, das formas e do movimento global da circulação dos fluidos no sistema. A variação do estado térmico de cada parte influi, por sua vez, sobre o comportamento dos materiais, modifica as formas e os volumes, enfim, também retroage sobre o funcionamento do sistema naquele instante. Os pedais da bicicleta influenciam a forma de sentar, as formas do assento e do guidom alteram o rendimento do ciclista e estabelecem limites prováveis - inferior e superior - das faixas de velocidades e de acelerações, e assim por diante.

O que um objeto faz é necessariamente distinto do que um sistema (abstrato) modela [14]. Se associamos a um objeto uma idéia abstrata, nem por isso ele perde sua condição de objeto concreto e autônomo. Assim, "o que ele faz" como objeto concreto não é rigorosamente "o que ele faz" se estivermos falando abstratamente de sua função. Para funcionar, o segmento de um código deve ser concretamente executado em um processo real. As conseqüências daqueles aspectos que foram "escondidos" pela abstração do modelo vão aparecer necessariamente, sejam elas "boas" ou "más" conseqüências: e nem sempre a troca da peça (ou do módulo) é possível ou conveniente.
 

Correspondência e abstração
No software, cada função corresponde a partes implementadas discretas do código (por exemplo, endereços de entrada de subrotina distintos) [15].

É só devido a essa correspondência biunívoca estilística, por assim dizer, entre "efeito pretendido" e "segmento de código" que se pode tomar a função como abstração "de qualquer segmento que realize aquele efeito". Contudo, ao nos concentrarmos naquilo que o subprograma faz (e não em seu código, em como ele faz), o que é uma recomendação de projeto na construção de programas modulares e um princípio das linguagens orientadas para objeto, como vimos, estamos fazendo uso da abstração em relação a certa totalidade sintética ideal (isto é, em relação ao sistema ideal), mas não em relação ao sistema implementado. Considerar a abstração como relativa ao sistema implementado é um "modo de dizer", um abuso de linguagem possível apenas pela correspondência função-implementação constitutiva daquela forma "nominalista" de construção. Os "isomorfismos" afirmados pelas metodologias "top-down" não decorrem de uma análise do real, não são correspondências funcionais "abstraídas do mundo real", foram colocados lá pela teoria.

Em resumo, certos sistemas podem ser recortados de forma que suas partes (módulos) apareçam articuladas em um todo desmontável (com o funcionamento daquelas articulações regidas por normas e especificações de tolerância, que poderíamos chamar de protocolos de comunicação entre as partes). Além disso, cada módulo pode ser - e, em geral, é - implementado concretamente como um segmento de código independente, ativado ("chamado") exclusivamente mediante um protocolo (instruções de comunicação). Para se fazer funcionar concretamente cada parte - e o sistema todo - devem ser implementadas (escritas, compiladas) certas opções de métodos, algoritmos e outros detalhes. O que necessariamente tem de ser preservado em qualquer implementação particular, o que deve permanecer "independente de máquina" são as articulações entre as partes, articulações constitutivas do sistema, inalteráveis mesmo ao preço de ineficiência real em certo equipamento: no caso, sacrifica-se ao padrão a eficiência. Cada implementação particular ideal é uma instância daquele modelo geral abstrato [16]. Para ele, o programa concreto é apenas o instrumento, o medium ("ocasional") que representa (evidencia, manifesta) a idéia (propriedade). O programa, contudo, é também um instrumento produtivo real: transforma o mundo concretamente. Assim, não apresenta apenas o que representa, não é mero reverso da abstração analítica, como seria o caso de uma totalidade sintética ideal. É na correspondência um-a-um idéia-implementação concreta (em um encadeamento que vai do semicondutor ao sistema de menus na tela) que se deve buscar a razão pela qual a afirmação de que "um rótulo de subrotina é uma abstração do código que o implementa" não parece contraditória. O isomorfismo - e não a abstração - é o que nos permite passar de um âmbito a outro na comparação entre idéia e concreção. [Ver Köhler:147ss].

A abstração implica, sempre, certa finalidade; e o ato de implementação concreta não tem, em princípio, outra finalidade que não a mesma da abstração que lhe dá origem. Não é, contudo, irrelevante para o usuário o código interno de um programa e , por isso, não é algo que deva ser sistematicamente omitido. Entre outras coisas, os papéis e os efeitos de um código não se esgotam em sua finalidade.
Um programa é mais do que um modelo - ao contrário do que parecem pensar os entusiastas da "abstração de dados". Um programa é parte da máquina se estiver registrado em mídia conveniente. Então, programas não são meras "reproduções" abstratas - ou modelos - dos procedimentos concretos. Programas são produtos concretos, ainda que também simbólicos, integrados ao projeto e à realidade da máquina que irá implementar ou simular aqueles procedimentos. A utilidade e inteligibilidade de um programa depende justamente dessa ambigüidade.
 
 

Notas:

* Este artigo atualiza questões tratadas em Elementos para uma avaliação crítica das interfaces homem-computador, Diss. Mestr., Rio de Janeiro: ECO/UFRJ, 1993, em particular as do capítulo "Ocultamento de Informação e Abstração de Dados". Para os que ainda desconfiam de comparações entre áreas tão diversas como a Filosofia, a Política e a Computação, até que o artigo foi bem cauteloso. Basta dar uma olhada no verbete "computer theory", escrito por Arthur W. Burks da Universidade de Michigan para "The Cambridge Dictionary of Philosophy (2nd. Ed., 1999)", que ilustra, i.e., modela a "lei do eterno retorno" de Nietzsche como um autômato finito fechado.

** [Roland Barthes, O Rumor da Língua, São Paulo: Brasiliense, 1988, p. 162] e [Erich Auerbach, Mimesis, São Paulo: Perspectiva, 1976, p. 494], respectivamente.

[1] Por exemplo: "The user interface refers to what a person must know in order to invoke the operations of the data type." [Gary Simons, "Data Abstraction", in BYTE, Vol. 9, N. 11, October 1984, N. York: McGraw-Hill, p. 423]. O que a pessoa deve conhecer é o protocolo de comunicação com o tipo de dado de forma a poder invocá-lo. O protocolo é um conjunto padronizado de elementos e regras de manipulação considerados legítimos, necessários e suficientes para estabelecer a comunicação entre as partes.


[2] Em particular, Peter Wegner é bastante crítico quanto à pretendida suficiência das descrições protocolares:
'O Algol 60 é cuidadosamente projetado em torno de um modelo de implementação no qual a alocação de armazenamento para a avaliação de expressões, entrada e saída de bloco e entrada e entrada e saída de procedimento pode ser realizada em uma simples pilha em tempo de execução. E. W. Dijkstra desenvolveu uma implementação de Algol 60 logo no outono de 1960, baseado neste modelo simples de implementação.["Construindo um tradutor para ALGOL 60", APIC Bull., vol.7, 1961]. Contudo, este modelo semântico de implementação estava mais implícito do que explícito no relatório do Algol. A incompreensão quanto ao modelo conduziu a uma idéia generalizada de que o Algol 60 tinha um alto preço de sobrecarga em tempo de execução, e a um exagero das dificuldades de se implementar o Algol 60. Uma descrição explícita do modelo de implementação é dado em [Randell & Russell, Algol 60 Implementation. N.York:Academic, 1964]. Algol 60 é um bom exemplo de uma linguagem que se torna semanticamente muito simples se temos o modelo certo de implementação, mas que parece ser semanticamente complexa se temos o modelo errado.'
"Algol 60 is carefully designed around a model of implementation in which storage allocation for expression evaluation, block entry and exit and procedure entry and exit can be performed in a single run-time stack. [E.W.] Dijkstra developed an implementation of Algol 60 as early as the fall of 1960 based on this simple model of implementation ['Making a translator for ALGOL 60', APIC Bull., vol 7, 1961]. However, this semantic model of implementation was implicit rather than explicit in the Algol report. Failure to understand the model led to a widespread view that Algol 60 required a high price in run-time overhead, and to an exaggerated view of the difficulty of implementing Algol 60. An explicit account of the model of implementation is given in [Randell & Russell, Algol 60 Implementation. N.York: Academic,1964]. Algol 60 is a good example of a language which becomes semantically very simple if we have the right model of implementation but appears to be semantically complex if we have the wrong model of implementation." [Wegner(1976):1210].

Como se sabe, há muito material especializado sobre equivalência e mapeamento de sistemas ou modelos, que não é o nosso assunto. Aqui nos interessa destacar a afirmação de que a insuficiência dos protocolos é uma característica desejável para certo tipo de projeto. Ver também [Wegner(1972)].


[3] " 'Que dizer da Internet e, de fato, de toda a indústria de telecomunicações?'
- (...)Isto pode realmente ser controlado? Não é tão óbvio. Eles [indústria e governo] querem usar a Internet para ... - bom, eles têm um ideal de como deveria ser a sociedade, e os Estados Unidos como que estão chegando perto desse ideal. Do ponto de vista deles a sociedade ideal consiste de uma unidade social que é uma pessoa e um aparelho de televisão. Você e uma televisão. Esta é a unidade social. Não deveria haver outros laços sociais. Sabe como é: você não deveria se importar com falar com outras pessoas, associar-se a elas e, por certo, não fazer nada junto com elas. Bom, este ideal é difícil de realizar, mas os esforços de toda a indústria de relações públicas, incluindo a televisão, a indústria de entretenimento, as escolas, a mídia, tudo se dirige a este objetivo e, assim, também é este o seu objetivo para a Internet. Algo assim como o que eles gostariam que a Internet fosse, um grande serviço de compras a domicílio. Então, você pode sentar-se em frente da tela de televisão deles e tomar a única decisão que realmente importa na vida humana: eu deveria ter este par de sapatos ou aquele? Você nem deveria encontrar outras pessoas numa loja, digamos, porque isso é perigoso, não é? As pessoas lá, falando umas com as outras e coisa e tal. Então, este é mais ou menos o ideal. Por outro lado, a Internet tem todo tipo de possibilidades extremamente difíceis de controlar, podem ser impossíveis de controlar, por razões simplesmente técnicas. Ela tem oferecido meios de comunicação alternativos que têm sido liberadores. E não sabemos de que jeito esta luta vai acabar ficando." [Chomsky:122-125]


[4] Pelo menos parte da "racionalidade" do ocultamento de informação, preconizado pela teoria como norma do bom projeto, estaria no uso econômico dos recursos finitos simbólicos (é também em nome da economia que um nome de variável local - "oculta" para outros lugares - está vigente somente durante o tempo necessário de processamento); como o repertório de símbolos (alfabéticos, léxicos, numéricos, ideográficos) é finito, o uso de um símbolo diminui as possibilidades (a precisão) de escolha para um novo processo - ou do código subseqüente do mesmo processo: o uso reduz o repertório. Nesse sentido, o ocultamento de informação - ou melhor, o uso local da informação - quer, entre outras coisas, preservar o repertório simbólico disponível para cada processo. Uma expressão mais adequada para essa função do ocultamento de informação seria independência simbólica, ou mesmo polissemia. Resta saber se a informação sobre a implementação precisa ser omitida para que a polissemia possa ocorrer; ou se os acessos livres aos núcleos dos códigos (e não apenas aos protocolos de entrada e saída) assegurariam - ao invés de dificultar - a compatibilidade entre programas, desde que houvesse intenção sincera de desenvolvimento coletivo e público (como na oposição entre o modo "catedral" e o modo "bazar" de desenvolvimento de sistemas; ver [Raymond]), e não apenas uma preocupação monopolista com a propriedade e o controle intelectual e industrial dos padrões. De qualquer modo, o chamado "ocultamento de informação" não é um procedimento "neutro", nem "comprovadamente indispensável" para o desenvolvimento de padrões estáveis. O sistema métrico decimal é uma prova disso. Nele não se "oculta" nada. Não é impedindo ou dificultando a comunicação e o conhecimento dos assim considerados "detalhes" que se vai "garantir a boa e correta comunicação". O que se visa no ocultamento é, principalmente, o controle dos usos e dos usuários, mesmo às custas da funcionalidade das ferramentas. Na verdade, procura-se mesmo a colonização do usuário, através do ocultamento das funcionalidades dos bens já licenciados. A obsessão por nomes locais e outros preceitos da programação estruturada (e, mais tarde, da orientação a objetos), resultado da necessidade de controle centralizado das atividades de programação e da verificabilidade da correção dos programas conduziu ao princípio da "informação oculta" como necessidade de padronização. Mas as falhas sistemáticas de documentação desmentem sua "bondade incondicional".


[5] Especiosas sementes da servidão voluntária e da dominação consentida. Severo Gomes afirma que "(...)nunca houve, na história do desenvolvimento industrial, nenhum momento em que a tecnologia do uso e a do produto estivessem tão distanciadas. Quer dizer, por mais que se saiba usar o computador, jamais se chegará a compreender suas entranhas. E delas virão a linguagem e os conceitos para influenciar as atividades econômicas, sociais e culturais." [Benakouche: 31]


[6] Pelo menos como expectativa. Jean-Louis Gassée diz que "a interface é o lugar cognitivo da interação homem-computador" e que "a evolução da interface homem-computador começa a comandar a evolução da inteligência". [Laurel:226].


[7] Não é que em Parnas surja por primeira vez o procedimento de ocultar informação. Em particular, qualquer protocolo implica a existência de níveis autônomos que "omitem" seus "detalhes de implementação" uns para os outros, já que o objeto de um nível não tem qualquer significado necessário para o outro nível. O protocolo de comunicação de dados OSI - RS-232C, por exemplo, especifica sete camadas - layers - (de "abstração"), o que implica a autonomia ("ocultamento", "inconsciência", "indiferença") de cada nível em relação aos demais. No extremo "mais baixo", há o nível "físico", com normas relativas a limites de voltagem, pinagem de conectores, etc. Há o nível intermediário de empacotamento das unidades de informação. E no outro extremo, "mais alto", as regras relativas às sessões e aos formatos das mensagens, regras que devem ser obedecidas pelos usuários finais daquele protocolo. A compreensão do protocolo, contudo, implica ter acesso a todo o conjunto de especificações dos diversos níveis.


[8] Por exemplo: "De certo modo, o ocultamento de informação dita que os sistemas de programação devem possuir características não documentadas, ocultas, e que tais características não documentadas são algo bom, e não uma coisa má. Quando uma interface é projetada convenientemente, os programadores não deveriam ter qualquer necessidade de usar, ou mesmo conhecer estas características escondidas, tudo o que eles necessitam para fazer o seu trabalho é fornecido pela própria interface."
"In a way, 'information hiding' dictates that software systems must have undocumented, hidden features, and that such undocumented features are good thing, not a bad thing. When an interface is designed properly, programmers should have no need to use or even know about these hidden features: everything they need to do their job is supplied by the interface itself." [Schulman:xiv-xv]

Ou, reproduzindo o abstract do artigo de Parnas: "Este artigo apresenta uma abordagem para escrever especificações de partes de sistemas de software O objetivo principal é fornecer especificações suficientemente precisas e completas de modo que se possam escrever outras partes de software que interajam com a parte especificada sem qualquer informação adicional. O segundo objetivo é incluir na especificação apenas a informação estritamente necessária para atingir o primeiro objetivo. A técnica é ilustrada através de uma variedade de exemplos de um sistema tutorial."
"This paper presents an approach to writing specifications for parts of software systems. The main goal is to provide specifications sufficiently precise and complete that other pieces of software can be written to interact with the piece specified without additional information. The secondary goal is to include in the specification no more information than necessary to meet the first goal. The technique is illustrated by means of a variety of examples from a tutorial system." [Parnas(May72), Abstract]


[9] A imensa sobrecarga que o "ocultamento de informação" impõe não é nova, certamente. Por exemplo, por volta de 1989, a lista de "interrupções não-documentadas" do MS-DOS, que já era resultado da contribuição de mais de cem pessoas, tinha cerca de 380 páginas e crescia à razão de 8 páginas por mês. A lista seguiu engordando. Na época, existiam pessoas encarregadas de manter disponíveis as novas informações através de serviços on-line como os da CompuServe [ver Schulman:495].


[10] Até aqui, creio que ninguém diria que uma acepção não manipulável da seqüência é uma "abstração" da acepção manipulável; ou seja, é ainda impensável que o nome próprio BACH seja uma "abstração" da seqüência Si b - Lá - Dó - Si, manipulável em um contexto melódico, mesmo que alguém, intencionalmente, tenha escolhido aquela seqüência melódica pela homografia "sugestiva" com o nome do compositor.
Em um exemplo numérico, a seqüência binária 101 pode ser associada arbitrariamente ao número 101 (em decimal), sem que certamente se possa dizer que o número 101 (em decimal) é uma "abstração" da seqüência "mais concreta" 101 (binária) pela homografia na representação.
Claro que sempre poderemos definir "abstração" e "concreção" como nos aprouver. Podemos dizer: Seja, por exemplo, "BACH" uma "abstração" da seqüência Si b - Lá - Dó - Si. Valendo a definição, se associarmos arbitrariamente ao nome "BACH" as acepções "alemão", "músico", "Florais", "xyz", podemos considerá-las, neste caso, "abstrações" da seqüência musical Si b - Lá - Dó - Si. Mas, nesse caso, o conceito de "abstração" tem pouca utilidade "cognitiva" para nós: "abstrato" ou "concreto" deixariam de ser características verificáveis ou observáveis nas coisas (o que tem "alemão" a ver com Si b-Lá-Dó-Si?) e passariam a ser meras tautologias derivadas das definições formais. Tamanho deslocamento do significado usual dos conceitos nos jogaria para fora do âmbito da discussão original sobre a "abstração" e a "concreção", servindo esses termos, a partir daí, apenas como fatores de confusão do pensamento.


[11] No jargão de hipertexto, fala-se de "implementação de cada operação, idéia ou conceito "abstrato" através de um ícone, botão, janela, etc., isto é, através de uma representação "concreta". Por exemplo,: "(...)Um bom lema do hipertexto é: 'Um objeto de interface por objeto de banco de dados'. Isto é uma tentativa de tornar o abstrato concreto, fazendo corresponder idéias a objetos da percepção".
"(...)A nice hypertext slogan is: 'One interface object per database object'. This is an attempt to make the abstract concrete by having ideas correspond to perceptual objects(...)" [K.Gygi in Laurel:280].


[12] "Coincidentes", mas não "isomórficos". As acepções da palavra "Bach" coincidem em sua "chave externa", a própria palavra "Bach". Enquanto a "mera coincidência" faz convergir dessemelhanças através de uma chave externa, o "isomorfismo" provém de analogias que se desprendem de semelhanças entre os objetos. Assim, há isomorfismo entre a partitura e sua execução. O artifício "analítico" de se atribuir ao "isomorfismo" uma substância concreta - no caso, uma chave externa tradutora, conversora, autônoma em relação aos objetos - é produto de uma tradição filosófica muito antiga [cf., por exemplo, Dreyfus:17] e o cerne dos fundamentos dos trabalhos correntes nos campos da Ciência da Computação e da Inteligência Artificial. É interessante comparar, por exemplo, o que diz [Hofstadter] e o que diz [Köhler:147ss] sobre o "isomorfismo". Na confusão entre correlação e isomorfismo reside, talvez, um dos principais canais para certas previsões eufóricas sobre o sempre iminente aparecimento do "pensamento automático". A tradição das Ciências da Computação é principalmente nominalista. As discussões sobre a "abstração" são versões daquelas sobre os "universais". A Filosofia e a Lingüística, por exemplo, têm feito, há muito tempo, a crítica da linguagem como representação (entre outros, Wittgenstein; ver, por exemplo, [Zilhão]). Só vale a pena tratar do assunto aqui, ao invés de simplesmente remeter o leitor a trabalhos filosóficos especializados, muito mais completos e autorizados, devido ao "ocultamento de informação" que a área em geral gosta de praticar. Quando os fundamentos de um campo de conhecimento devem tanto a uma alternativa filosófica, de certa forma aquela alternativa passa a fazer parte do campo. Além disso, naqueles trabalhos filosóficos seria difícil encontrar uma referência direta ao problema específico que tratamos. É tarefa de cada área a análise crítica frutífera de seus fundamentos. A Gestalt, a Lingüística, a Física do Campo e a Fenomenologia são exemplos disso.


[13] Um lugar (assim como um rótulo, uma rubrica) difere de uma abstração pelo menos no sentido de que esta torna explícito certo aspecto considerado relevante do objeto que representa, enquanto que o mero rótulo pode, no máximo, localizar o objeto em relação a outros em um sistema de referências.


[14] Galileu não parece ter problema algum em "reconhecer"a independência entre modelo e experiência: "(...)em nada prejudica as conclusões demonstradas por Arquimedes a respeito da espiral o não se encontrar na natureza móvel que daquela maneira se mova espiralmente." Nem Torricelli: "Se (...) as bolas de chumbo, ferro, pedra não observam aquela suposta direção, pior para elas: diremos que não estamos falando delas." (Citado por [Rossi:99])


[15] Se a implementação é feita através de interrupções (mesmos endereços de entrada) com conteúdos de registradores (flags e parâmetros) diferentes, ainda assim, as ramificações de programa são multiplexadas segundo aqueles conteúdos de registradores (flags). Então, cada função particular corresponde a uma subrotina implementada diferente, para cada função "abstrata" há um objeto implementado "concreto" com um endereço de entrada. Isto é uma norma de construção.


[16] Reproduzir a essência significa transformar a aparência de forma a compensar-se as modificações da circunstância. Reproduções da aparência só correspondem a reproduções da essência pela assunção da equivalência dos contextos de cada exemplar. A semelhança essencial (profunda, efetiva) não corresponde, necessariamente, à semelhança aparente (superficial). Daí derivam as "explicações" ingênuas: dos abusos e da rigidez das metáforas concebidas para o usuário "médio" (leia-se, também, "ingênuo") das interfaces homem-máquina.
 
 

Referências Bibliográficas:

[Benakouche], Rabah (Org). A Questão da Informática no Brasil. São Paulo: Brasiliense; CNPq, 1985.

[Cardelli], Luca; Wegner, Peter. "On Understanding Types, Data Abstraction, and Polymorphism", in Computer Surveys, Vol. 17, No. 4, December 1985, pp 471-522.

[Chomsky], Noam. "Perguntas e respostas ao vivo (19/11/1996)", in Noam Chomsky na UFRJ, Rio de Janeiro: COPPE/UFRJ, 1997 (pp 122-125)

[Dahmke], Mark. Sistemas Operacionais para Microcomputadores. Rio de Janeiro: Campus, 1986. (Orig. 1982)

[Dreyfus], Hubert. O que os Computadores Não Podem Fazer. Rio de Janeiro: A Casa do Livro, 1975. (Há uma revisão de 1992, reimpressa em 1999, com o nome What Computers Still Can't Do, MIT, Cambridge, Massachusetts)

[Ghezzi], C & Jazayeri, M. Conceitos de Linguagens de Programação. Rio de Janeiro: Campus, 1985 (Orig.1982)

[Hofstadter], Douglas R. Gödel, Escher, Bach. UnB: Brasília, 2001 (Orig. 1979)

[Köhler], Wolfgang. The Place of Value in a World of Facts. N.York: Mentor Books, Liveright, 1966. (Orig. 1938)

[Laurel], Brenda.(Ed.). The Art of Human-Computer Interface Design. Reading (Mass): Addison-Wesley, 1990.

[Parnas(May72)] D.L. Parnas, "A technique for software module specification with examples", in Communications of the ACM, Vol. 15, No. 5, May 1972 pp. 330 - 336  [disponível em http://portal.acm.org/ para usuários cadastrados]

[Parnas(Dec72)] D.L. Parnas, "On the Criteria To Be Used in Decomposing Systems into Modules", in Communications of the ACM, Vol. 15, No. 12, December 1972 pp. 1053 - 1058 [disponível livremente em http://www.acm.org/classics/may96/ ]

[Raymond], Eric S. The Cathedral & the Bazaar. O'Reilly, Jan 2001. Ver http://www.oreilly.com/catalog/cathbaz/
Versões diversas mais ou menos resumidas disponíveis em várias URLs e idiomas. Por exemplo:
http://catb.org/~esr/writings/cathedral-bazaar/
http://www.catb.org/~esr/writings/cathedral-bazaar/cathedral-bazaar/
http://www.firstmonday.dk/issues/issue3_3/raymond/
http://www.openresources.com/documents/cathedral-bazaar/

[Rossi], Paolo. Os Filósofos e as Máquinas. São Paulo: Companhia das Letras, 1989. (Orig. 2ªed.1971)

[Schulman], Andrew et alii. Undocumented DOS. Reading (MA): Addison-Wesley, 1990.

[Sethi], Ravi. Programming Languages: concepts and constructs. Reading (Mass): Addison-Wesley, 1990.

[Stallman], Richard. The GNU Project. Em http://www.gnu.org/gnu/thegnuproject.html . Também disponível em português (O Projeto GNU) em http://www.dgz.org.br/fev00/Art_04.htm

[Wegner (1972)] Wegner, Peter. "Operational Semantics of Programming Languages", in Source Proceedings of ACM Conference on Proving Assertions about Programs - Las Cruces, New Mexico, USA: ACM, 1972, pp 128-141.

[Wegner(1976)], Peter. "Programming Languages - The First 25 Years", in IEEE Transactions on Computers, Vol c-25, N. 12, December 1976.

[Zilhão], António. Linguagem da Filosofia e Filosofia da Linguagem. Lisboa:Colibri,1993.
 
 

Sobre o autor / About the Author
    Luiz Carlos Brito Paternostro
    patern@alternex.com.br
    Dr. [Ciência da Informação], UFRJ/ECO, IBICT/CNPq, 1998
    Professor da Escola de Comunicação da Universidade Federal do Rio de Janeiro (UFRJ)
    Endereço residencial/ Personal address:
    Av. N. S. Copacabana, 1049/601 -  22060-000
    Rio de Janeiro, RJ, Brasil