Programação extensível - Extensible programming

Programação extensível é um termo usado em ciência da computação para descrever um estilo de programação de computador que se concentra em mecanismos para estender a linguagem de programação , o compilador e o ambiente de execução . Linguagens de programação extensíveis, que suportam esse estilo de programação, foram uma área ativa de trabalho na década de 1960, mas o movimento foi marginalizado na década de 1970. A programação extensível tornou-se um tópico de interesse renovado no século XXI.

Movimento histórico

O primeiro artigo geralmente associado ao movimento da linguagem de programação extensível é o artigo de M. Douglas McIlroy de 1960 sobre macros para linguagens de programação de nível superior. Outra descrição inicial do princípio da extensibilidade ocorre no artigo de 1960 de Brooker e Morris sobre o Compilador-Compilador . O pico do movimento foi marcado por dois simpósios acadêmicos, em 1969 e 1971. Em 1975, um artigo de pesquisa sobre o movimento por Thomas A. Standish foi essencialmente um post mortem. A linguagem de programação Forth foi uma exceção, mas passou essencialmente despercebida.

Caráter do movimento histórico

Como normalmente imaginado, uma linguagem de programação extensível consistia em uma linguagem base fornecendo recursos de computação elementares e uma meta-linguagem capaz de modificar a linguagem base. Um programa então consistia em modificações de meta-linguagem e código na linguagem base modificada.

A técnica de extensão de linguagem mais proeminente usada no movimento foi a macro definição. A modificação gramatical também estava intimamente associada ao movimento, resultando no eventual desenvolvimento de formalismos gramaticais adaptativos . A comunidade da língua Lisp permaneceu separada da comunidade da língua extensível, aparentemente porque, como um pesquisador observou,

qualquer linguagem de programação na qual programas e dados são essencialmente intercambiáveis ​​pode ser considerada uma linguagem extensível [sic]. ... isso pode ser visto facilmente pelo fato de que Lisp tem sido usado como uma linguagem extensível por anos.

Na conferência de 1969, Simula foi apresentado como uma linguagem de programação extensível.

Standish descreveu três classes de extensão de linguagem, que ele chamou de paráfrase , ortofrase e metáfrase (caso contrário, paráfrase e metáfrase são termos de tradução ).

  • A paráfrase define uma facilidade mostrando como trocá-la por algo previamente definido (ou a ser definido). Como exemplos, ele menciona definições de macro, definições de procedimento ordinário, extensões gramaticais, definições de dados, definições de operador e extensões de estrutura de controle.
  • Orthophrase adiciona recursos a uma linguagem que não poderiam ser alcançados usando a linguagem base, como adicionar um sistema i / o a uma linguagem base que anteriormente não tinha primitivos i / o. As extensões devem ser entendidas como ortófrases relativas a algum idioma de base dado, uma vez que um recurso não definido em termos do idioma de base deve ser definido em termos de algum outro idioma. Orthophrase corresponde à noção moderna de plug-ins .
  • A metafrase modifica as regras de interpretação usadas para expressões pré-existentes. Corresponde à noção moderna de reflexão .

Morte do movimento histórico

Standish atribuiu a falha do movimento de extensibilidade à dificuldade de programar extensões sucessivas. Um programador comum poderia construir um único shell de macros em torno de uma linguagem base, mas se um segundo shell de macros fosse construído em torno disso, o programador teria que estar intimamente familiarizado com a linguagem base e o primeiro shell; um terceiro invólucro exigiria familiaridade com a base e com o primeiro e o segundo invólucros; e assim por diante. (Observe que proteger o programador de detalhes de nível inferior é a intenção do movimento de abstração que suplantou o movimento de extensibilidade.)

Apesar da apresentação anterior de Simula como extensível, em 1975, a pesquisa de Standish não parece ter incluído na prática as tecnologias baseadas em abstração mais recentes (embora ele tenha usado uma definição muito geral de extensibilidade que tecnicamente poderia tê-las incluído). Uma história de abstração de programação de 1978, desde a invenção do computador até os dias (então) atuais, não fazia menção a macros e não dava nenhuma pista de que o movimento das linguagens extensíveis já tivesse ocorrido. As macros foram provisoriamente admitidas no movimento de abstração no final da década de 1980 (talvez devido ao advento das macros higiênicas ), ao receber o pseudônimo de abstrações sintáticas .

Movimento moderno

No sentido moderno, um sistema que oferece suporte à programação extensível fornecerá todos os recursos descritos a seguir.

Sintaxe extensível

Isso significa simplesmente que os idiomas de origem a serem compilados não devem ser fechados, fixos ou estáticos. Deve ser possível adicionar novas palavras-chave, conceitos e estruturas ao (s) idioma (s) de origem. As linguagens que permitem a adição de construções com sintaxe definida pelo usuário incluem Camlp4 , OpenC ++ , Seed7 , Red , Rebol e Felix . Embora seja aceitável que alguns recursos fundamentais e intrínsecos da linguagem sejam imutáveis, o sistema não deve depender exclusivamente desses recursos de linguagem. Deve ser possível adicionar novos.

Compilador extensível

Na programação extensível, um compilador não é um programa monolítico que converte a entrada do código-fonte em uma saída executável binária. O próprio compilador deve ser extensível ao ponto de ser realmente uma coleção de plug-ins que auxiliam na tradução da entrada do idioma de origem em qualquer coisa . Por exemplo, um compilador extensível oferecerá suporte à geração de código-objeto, documentação de código, código-fonte reformatado ou qualquer outra saída desejada. A arquitetura do compilador deve permitir que seus usuários "entrem" no processo de compilação e forneçam tarefas de processamento alternativas em cada etapa razoável do processo de compilação.

Apenas para a tarefa de traduzir o código-fonte em algo que pode ser executado em um computador, um compilador extensível deve:

  • usar um plug-in ou arquitetura de componente para quase todos os aspectos de sua função
  • determine qual idioma ou variante de idioma está sendo compilado e localize o plug-in apropriado para reconhecer e validar esse idioma
  • usar especificações formais de linguagem para validar sintaticamente e estruturalmente as linguagens de origem arbitrárias
  • auxiliar na validação semântica de idiomas de origem arbitrários invocando um plug-in de validação apropriado
  • permitem que os usuários selecionem diferentes tipos de geradores de código para que o executável resultante possa ser direcionado para diferentes processadores, sistemas operacionais, máquinas virtuais ou outro ambiente de execução.
  • fornecer recursos para geração de erros e extensões para ele
  • permitir novos tipos de nós na árvore de sintaxe abstrata (AST),
  • permitir novos valores nos nós da AST,
  • permitem novos tipos de arestas entre nós,
  • apoiar a transformação da entrada AST, ou partes dela, por algum "passe" externo
  • apoiar a tradução do AST de entrada, ou partes dele, em outra forma por algum "passe" externo
  • auxiliar no fluxo de informações entre passes internos e externos, pois ambos transformam e traduzem o AST em novos ASTs ou outras representações

Tempo de execução extensível

Em tempo de execução, os sistemas de programação extensível devem permitir que as linguagens estendam o conjunto de operações que ele permite. Por exemplo, se o sistema usa um intérprete de código de byte , ele deve permitir que novos valores de código de byte sejam definidos. Tal como acontece com a sintaxe extensível, é aceitável que haja algum conjunto (pequeno) de operações fundamentais ou intrínsecas que são imutáveis. No entanto, deve ser possível sobrecarregar ou aumentar essas operações intrínsecas para que um comportamento novo ou adicional possa ser suportado.

Conteúdo separado do formulário

Os sistemas de programação extensível devem considerar os programas como dados a serem processados. Esses programas devem ser completamente desprovidos de qualquer tipo de informação de formatação. A exibição visual e edição de programas para os usuários deve ser uma função de tradução, suportada pelo compilador extensível, que traduz os dados do programa em formas mais adequadas para visualização ou edição. Naturalmente, esta deve ser uma tradução bidirecional. Isso é importante porque deve ser possível processar facilmente programas extensíveis de várias maneiras. É inaceitável que os únicos usos da entrada do idioma de origem sejam a edição, visualização e tradução para código de máquina. O processamento arbitrário de programas é facilitado pelo desacoplamento da entrada de origem das especificações de como ela deve ser processada (formatada, armazenada, exibida, editada etc.).

Suporte à depuração do idioma de origem

Os sistemas de programação extensível devem suportar a depuração de programas usando as construções da linguagem de origem original, independentemente das extensões ou transformação que o programa sofreu para torná-lo executável. Mais notavelmente, não se pode presumir que a única maneira de exibir dados de tempo de execução seja em estruturas ou matrizes . O depurador, ou mais corretamente 'inspetor de programa', deve permitir a exibição de dados de tempo de execução em formas adequadas ao idioma de origem. Por exemplo, se a linguagem oferece suporte a uma estrutura de dados para um processo de negócios ou fluxo de trabalho , deve ser possível para o depurador exibir essa estrutura de dados como um gráfico de espinha de peixe ou outro formulário fornecido por um plug-in.

Exemplos

Veja também

Referências

links externos

Em geral

  1. Artigo de Greg Wilson na fila ACM
  2. Discussão Slashdot
  3. Modern Extensible Languages - Um artigo de Daniel Zingaro

Ferramentas

  1. MetaL - uma implementação de mecanismo de compilador de programação extensível
  2. XPS - eXtensible Programming System (em desenvolvimento)
  3. MPS - sistema de metaprogramação JetBrains

Linguagens de programação com sintaxe extensível

  1. OpenZz
  2. xtc - eXTensible C
  3. Escrita em inglês
  4. Nemerle Macros
  5. Boo Syntactic Macros
  6. Compilador de formato intermediário da Stanford University
  7. Seed7 - A linguagem de programação extensível
  8. Katahdin - uma linguagem de programação com sintaxe e semântica que são mutáveis ​​em tempo de execução
  9. π - outra linguagem de programação com sintaxe extensível, implementada usando um analisador Earley