LINGUAGENS DE PRIMEIRA GERAÇÃO A primeira geração de linguagens remonta aos dias da codificação em nível de máquina. Contudo, algum trabalho com as linguagens de primeira geração continua até hoje. O código de máquina e seu equivalente mais legível por seres humanos - a linguagem assembler - representam a primeira geração de linguagens de programação. Essas linguagens dependentes da máquina exibem o mais baixo nível de abstração com o qual um programa pode ser representado. Há tanto linguagens assembler como arquiteturas de processadores com conjuntos de instruções customizadas. Do ponto de vista da engenharia de software, tais linguagens devem ser usadas somente quando uma linguagem de alto nível não puder cumprir os requisitos ou não for suportada. LINGUAGENS DE SEGUNDA GERAÇÃO As linguagens de segunda geração foram desenvolvidas no final da década de 1950 e no começo da década de 1960 e servem de base para todas as linguagens de programação modernas (terceira geração). As linguagens de segunda geração são caracterizadas pelo amplo uso, enormes bibliotecas de software e a mais ampla familiaridade e aceitação. Não há muito o que discutir em relação ao fato de que o FORTRAN, o COBOL, o ALGOL e (em certa medida) o BASIC são linguagens fundamentais em virtude de sua maturidade e aceitação. O FORTRAN tem resistido a 30 anos de críticas, permanecendo como a primeira linguagem de programação em trabalhos de engenharia/científicos. A versão padronizada original do FORTRAN (denominada "FORTRAN-66") proporcionou uma poderosa ferramenta para a solução de problemas computacionais, mas lhe faltava suporte direto para as construções estruturadas, tinha uma tipologia de dados fraca, não podia suportar facilmente a manipulação de strings e apresentava muitas outras deficiências. O mais novo padrão ANSI (denominado "FORTRAN-77") e o próximo padrão corrigem algumas das deficiências encontradas em versões anteriores da linguagem. Em muitos casos, o FORTRAN tem sido encaixado à força em áreas de aplicação para as quais ele nunca foi projetado, e grande parte da crítica à linguagem tem sido bastante injusta. Para aplicações que lidam com números, o FORTRAN continua sendo a linguagem preferida, mas para aplicações em software básico, de tempo real ou de produtos embutidos, outras linguagens oferecem vantagens irresistíveis. O COBOL, como o FORTRAN, atingiu a maturidade e é uma linguagem "padrão" para aplicações de processamento de dados comerciais. Ainda que às vezes seja criticada pela falta de concisão, essa linguagem tem excelentes capacidades de definição de dados, possui uma ampla autodocumentação e oferece suporte a uma grande variedade de técnicas procedimentais pertinentes ao processamento de dados comerciais. O ALGOL é a precursora de muitas linguagens de terceira geração e oferece um repertório extremamente rico de construções procedimentais e de tipologia de dados. O ALGOL tem sido extensivamente usado na Europa, mas tem encontrado pouco apoio nos Estados Unidos (com exceção dos ambientes acadêmicos). A versão mais comumente D:\841073491.doc 1-7 usada da linguagem, corretamente denominada "ALGOL-60", foi ampliada para uma implementação mais poderosa, o ALGOL-68. Ambas as versões da linguagem sustentam a noção de estruturação e bloco, alocação dinâmica de memória, recursão e outras características que tiveram uma forte influência sobre as linguagens modernas que se seguiram. O BASIC é uma linguagem que foi originalmente projetada para se ensinar programação num modo de tempo compartilhado. A linguagem caminhava para a obsolescência no início da década de 1970, mas experimentou um renascimento com o advento dos sistemas de computadores pessoais. Existem centenas de versões do BASIC, dificultando a discussão dos benefícios e das deficiências da linguagem. LINGUAGENS DE TERCEIRA GERAÇÃO As linguagens de terceira geração (também chamadas linguagens de programação estruturadas ou modernas) são caracterizadas por fortes capacidades de estruturação procedimental e de dados. As linguagens dessa classe podem ser divididas em três amplas categorias: linguagens de alto nível de uso geral, linguagens de alto nível orientadas a objeto e linguagens especializadas. Todas as linguagens de alto nível de uso geral e orientadas a objeto exibem as características técnicas discutidas na Seção 16.3. As linguagens especializadas, por outro lado, foram projetadas para atender a requisitos especiais e têm uma sintaxe e forma que freqüentemente são únicas. Linguagens de Alto Nível de Uso Geral: A mais antiga linguagem de alto nível de uso geral (também uma linguagem básica), o ALGOL, serviu como modelo para outras linguagens desta categoria. Suas descendentes, PL/l, PASCAL, Modula-2, C e Ada, estão sendo adotadas como linguagens, tendo um potencial para aplicações de amplo espectro (isto é, para uso em áreas de aplicação de engenharia/científicas, produtos embutidos, comerciais e/ou básicas). A PL/1 poderia ser mais adequadamente classificada como linguagem de geração 2,5. Ela foi a primeira linguagem de amplo espectro verdadeira, desenvolvida com uma ampla variedade de características que possibilitam que ela seja usada em muitas áreas de aplicação diferentes. A PL/1 oferece suporte para aplicações comerciais e de engenharia/científicas, possibilitando, ao mesmo tempo, a especificação de estruturas de dados sofisticadas, multitarefas, E/S complexas, processamento de listas e muitas outras características. Subconjuntos da linguagem têm sido desenvolvidos para ensinar programação (PL/C), para uso em microprocessadores (PL/M) e para programação de software básico (PL/S). A PASCAL é uma linguagem de programação moderna que foi desenvolvida na década de 1970 como uma linguagem para ensinar técnicas modernas (por exemplo, programação estruturada) no desenvolvimento de software. Desde a sua introdução, a PASCAL encontrou crescente apoio de um amplo público de desenvolve dores de software é amplamente usada em aplicações de engenharia/científicas e em programação de software básico (a linguagem tem sido chamada "FORTRAN" desde a década de 1980). A PASCAL é uma descendente direta do ALGOL e contêm muitas das mesmas características: D:\841073491.doc 2-7 estruturação em bloco, tipologia de dados forte, suporte direto à recursão e outras características complementares. Ela tem sido implementada em computadores de todos os tamanhos. A Modula-2 é um desenvolvimento evolucionário da PASCAL e (diriam alguns) uma possível alternativa à linguagem de programação Ada. A Modula-2 combina a implementação direta de características de projeto tais como a ocultação de informações, abstração e tipologia de dados, com estruturas de controle para suportar a recursão e a concorrência. Atualmente, o uso da linguagem Modula-2 para aplicações industriais tem sido limitado. A linguagem de programação C foi originalmente projetada como uma linguagem para implementadores de sistemas operacionais. O sistema operacional UNIX é implementado em C. Hoje, porém, um amplo conjunto de softwares comerciais, aplicações embutidas e software básico tem sido construído usando a linguagem C. A linguagem C foi desenvolvida para o engenheiro de software sofisticado e contém poderosas características que dão a ela considerável flexibilidade. Essas mesmas características também podem criar problemas. Cox [COX85] apresenta uma descrição poética da linguagem: Um dos meus hobbies favoritos é o trabalho com madeira verde. Um projeto inicia-se não no depósito de madeira, com madeira secada no forno, mas na floresta. Um carvalho ereto é derrubado e transformado numa mobília rústica com um assombroso equipamento de ferramentas antigas... As ferramentas desse hobby têm um bocado em comum com as ferramentas que uso como programador. Por exemplo, o enxó é uma pesada lâmina sobre um cabo de 1,20 m (como uma enxada). Ele é uma ferramenta especializada, cuja função primária é alisar as superfícies ásperas de um tronco fendido. Ele é usado com as duas mãos, mantendo-se as pernas abertas sobre o trabalho. A aguçada lâmina remove lascas de seis polegadas de carvalho sólido num único golpe, a uma pequena distância de pernas e pés desprotegidos! Adoro esse enxó, da mesma forma que adoro a linguagem C. Ela não é uma ferramenta para tolos e para crianças. Mas, nas mãos de um artesão habilidoso, ela é capaz de realizar trabalhos poderosos, ainda que delicados. Seu potencial para sérios danos é tão óbvio que o perigo proporciona o único mecanismo de segurança; um salutar respeito por aquilo que um uso descuidado pode fazer! Como outras linguagens dessa categoria, a linguagem C suporta estruturas de dados sofisticadas e tem razoáveis características de tipologia de dados, faz uso extensivo de ponteiros e tem um rico conjunto de operadores para computação e manipulação de dados. Além disso, ela possibilita que o programador "fique perto da máquina", ao apresentar características semelhantes à linguagem assembly. A linguagem Ada foi originalmente desenvolvida como uma nova linguagem padrão para sistemas computadorizados de tempo real embutidos a serem desenvolvidos pelo Departamento de Defesa Americano. Atualmente, essa linguagem é amplamente usada tanto em aplicações de defesa como de não-defesa. Semelhante ao Pascal em sua estrutura e notação (mas bem mais poderoso e complexo), o Ada sustenta um rico conjunto de características que inclui multitarefas, manejo de interrupções, sincronização intertarefa e comunicação, bem como um conjunto de características únicas, tais como o package Ada. A linguagem Ada criou e continua a gerar muita controvérsia. Os adeptos louvam sua rica estrutura de linguagem e concentram-se no ambiente Ada para engenharia de software, e D:\841073491.doc 3-7 não nos aspectos esotéricos relacionados à linguagem. Os oponentes preocupam-se com a complexidade da linguagem, com a atual ineficiência dos compiladores operacionais e com a longa curva de aprendizagem. Parece, entretanto, que os benefícios da linguagem predominarão e a linguagem Ada dominará bem certas esferas de aplicação durante a década de 1990. Linguagens Orientadas a Objeto: As linguagens de programação orientadas a objeto possibilitam que o engenheiro de software implemente modelos de análise e projeto criados usando-se a OOA e o OOD (Capítulos 8 e 12). Essas linguagens têm características que foram descritas na Seção 16.4.3. Não obstante dezenas de linguagens orientadas a objeto tenham sido introduzi das no decorrer da última década, somente algumas conquistaram um lugar significativo no mercado: dialetos de C (por exemplo, C++, Objective-C), Smalltalk e Eiffel. O Smalltalk, uma linguagem precursora orientada a objeto, foi originalmente desenvolvido no começo da década de 1970 para explorar conceitos orientados a objeto. Hoje, versões do Smalltalk encontram-se disponíveis em computadores de todos os tipos, ainda que o uso da linguagem para o desenvolvimento de produtos e sistemas de qualidade industriais seja limitado. Os dialetos orientados a objeto de C ganharam generalizado uso em toda a comunidade UNIX e junto a muitos desenvolvedores iniciantes de sistemas orientados a objeto. Tendo como base as potencialidades da linguagem C, os dialetos orientados a objeto possibilitam uma transição uniforme a partir dessa linguagem de alto nível, amplamente aproveitada e de uso geral. O Eiffel [MEY88] é uma dentre uma série de "novas" linguagens orientadas a objeto que são robustas o bastante para aplicações industriais. Como os dialetos C e Smalltalk, o Eiffel proporciona suporte direto a definições de classes, herança, encapsulação e envio de mensagens. Linguagens Especializadas: As linguagens especializadas são caracterizadas por formas sintáticas incomuns que foram especialmente projetadas para uma aplicação distinta. Centenas de linguagens especializadas estão em uso atualmente. Em geral, tais linguagens têm uma base de usuários muito menor do que as linguagens de uso geral. Entre as linguagens que encontraram aplicação dentro da comunidade de engenharia de software estão LISP, PROLOG, APL e FORTH. O LISP é uma linguagem especialmente adequada à manipulação de símbolos e ao processamento em lista encontrado em problemas combinatórios. Usada quase que exclusivamente pela comunidade de inteligência artificial, essa linguagem é particularmente apropriada à prova de teoremas, pesquisas sobre estruturas em árvore e outras atividades relacionadas à solução de problemas. Os subprogramas são implementados como funções que fazem intenso uso da recursão. Uma vez que cada função LISP é uma entidade única, a reusabilidade pode ser conseguida criando-se bibliotecas de funções primitivas. Nos últimos anos, o LISP tem sido usado para desenvolver uma ampla variedade de sistemas especialistas e "compiladores" de sistema especialistas. O LISP facilita a especificação de fatos, regras e das correspondentes inferências (implementadas como funções LISP) que são exigidas em sistemas baseados em conhecimento. O PROLOG é outra linguagem de programação que encontrou generalizado uso na construção de sistemas especialistas. Como o LISP, o PROLOG apresenta características que suportam a representação de conhecimento. Dentro da linguagem, uma estrutura de dados uniforme, denominada termo, é usada para construir todos os dados e todos os D:\841073491.doc 4-7 programas. Cada programa consiste em um conjunto de cláusulas que representam fatos, regras e inferências. Tanto o LISP quanto o PROLOG são especialmente receptivos a problemas que tratem de objetos e suas relações. Por essa razão, algumas pessoas referemse ao LISP e ao PROLOG como linguagens orientadas a objeto. Além disso, a natureza orientada a objeto do LISP e do PROLOG possibilita que cada um seja aplicado dentro do contexto do paradigma de prototipação da engenharia de software. A APL é uma linguagem extremamente concisa e poderosa para a manipulação de arrays e vetores. A linguagem contém pouco suporte a construções estruturadas ou à tipologia de dados. A APL oferece um rico conjunto de operadores computacionais e tem conquistado um pequeno, mas ávido conjunto de seguidores para a resolução de problemas matemáticos. A FORTH é uma linguagem projetada para o desenvolvimento de software de microprocessadores. Essa linguagem suporta a definição de funções definidas pelo usuário [implementadas com notação pós-fixada (forma polonesa revertida)] que são executadas de uma forma baseada em pilhas para obter eficiência em velocidade e memória. Do ponto de vista da engenharia de software, as linguagens especializadas apresentam tanto vantagens como desvantagens. Desde que uma linguagem especializada tenha sido projetada para tratar de uma aplicação específica, a conversão dos requisitos em projeto para a implementação do código pode ser facilitada. Por outro lado, a maioria das linguagens especializadas é bem menos portátil e freqüentemente menos capaz de obter manutenção do que as linguagens de uso geral. LINGUAGENS DE QUARTA GERAÇÃO Ao longo de toda a história do desenvolvimento de software, tentamos gerar programas de computador em níveis de abstração cada vez mais elevados. As linguagens de programação de primeira geração trabalharam no nível de fixação de instruções de máquina, o mais baixo nível de abstração possível. As linguagens de programação de segunda e terceira gerações elevaram o nível em que representamos os programas de computador, mas procedimentos algorítmicos distintos e completamente detalhados ainda têm de ser especificados. No decorrer da década passada, as linguagens de quarta geração (4GLs) elevaram o nível de abstração a um ponto ainda mais alto. As linguagens de quarta geração, como todas as linguagens artificiais, contêm uma sintaxe distinta para a representação da estrutura de dados e de controle. Uma 4GL, entretanto, representa essas estruturas em um nível de abstração mais elevado, ao eliminar a necessidade de especificar detalhes algorítmicos. Por exemplo, a instrução COMPUTAR VALOR-LÍQUIDO-ATUAL E RETORNO-SOBRE-O-INVESTIMENTO PARA DISPÊNDIOS #5 E #9. é uma instrução de 4GL típica. O sistema 4GL "sabe" como computar os dados financeiros desejados e o faz sem exigir que o desenvolvedor do software especifique os algoritmos apropriados. Deve ficar claro que o "conhecimento" acima descrito é específico quanto ao domínio. Ou seja, a mesma 4GL indubitavelmente se chocaria com D:\841073491.doc 5-7 COMPUTAR AS RAÍZES DA EQUAÇÃO TRANSCENDENTAL #3 E APLICÁ-LAS AO MODELO FÍSICO. não obstante outra 4GL, projetada especificamente para o domínio de aplicação implícito acima, pudesse fazer o trabalho esplendidamente. As linguagens de quarta geração combinam características procedimentais e nãoprocedimentais. Ou seja, a linguagem possibilita que o usuário especifique condições e as correspondentes ações (o componente procedimental), encorajando, ao mesmo tempo, o usuário a indicar o resultado desejado (o componente não-procedimental) e então aplicar seu conhecimento específico do domínio para preencher os detalhes procedimentais. Martin ([MAR85], [MAR86]) apresenta uma discussão abrangente das linguagens de quarta geração e desenvolve as seguintes categorias gerais: Linguagens de Consulta Até hoje, a grande maioria das 4GLs foi desenvolvida para ser usada em conjunto com aplicações de bancos de dados. Tais linguagens de consulta possibilitam que o usuário manipule informações contidas num banco de dados preexistente de uma forma sofisticada. Algumas linguagens de consulta exigem uma sintaxe complexa que não é mais simples (e, em certos casos, pior) do que uma linguagem de terceira geração. Por exemplo [MAR85]: list by região (87.vendas.real.set) sum (87.vendas.set.est) , (sum (sum (87.vendas.real.set))) Entretanto, outras linguagens de consulta disponíveis atualmente oferecem uma interface de linguagem natural que permite que o usuário declare [INT86]: Para as regiões leste e oeste, como se comportaram as vendas reais do último mês em comparação com as previsões? É desnecessário dizer que a segunda abordagem seria preferida pelos usuários. Geradores de Programas Os geradores de programas representam outra classe, bem mais sofisticada, de linguagens de quarta geração. Em vez de confiar num banco de dados previamente definido como seu ponto focal, um gerador de programas possibilita que o usuário crie programas completos em linguagem de terceira geração, usando (muitos afirmam) declarações com uma ordem de magnitude a menos. Essas linguagens de programação de nível muito elevado fazem intenso uso de abstrações procedimentais e de dados (Capítulo 10). Infelizmente, para os que trabalham na área de produtos e sistemas de engenharia, a maioria dos geradores de programas disponíveis atualmente concentra-se exclusivamente em aplicações de sistemas de informação e gera programas em COBOL. Porém, uma nova geração de ferramentas CASE possibilita que o engenheiro de software modele graficamente uma aplicação de engenharia e depois gere um código-fonte C ou Ada a partir do modelo gráfico. Outras 4GLs Não obstante as linguagens de consulta e os geradores de programas sejam as D:\841073491.doc 6-7 linguagens de quarta geração mais comuns, existem outras categorias. As linguagens de apoio a decisões possibilitam que "não-programadores" realizem uma variedade de análise do tipo "e se?" que variam de simples modelos de planilhas bidimensionais a sofisticados sistemas de modelagem estatística ou de pesquisa operacional. As linguagens de prototipação foram desenvolvidas para auxiliar na criação de protótipos, facilitando a criação de interfaces com o usuário e diálogo e proporcionando um meio para a modelagem de dados. As linguagens formais de especificação (discutidas no Capítulo 9) podem ser consideradas linguagens de quarta geração quando produzem software executável em máquina. Finalmente, as ferramentas usadas num ambiente de computador pessoal (por exemplo, planilhas, sistemas de bancos de dados, Macintosh Hypercard) possibilitam que o usuário "programe" em um nível de abstração mais elevado do que aquele que estava anteriormente disponível. D:\841073491.doc 7-7