Programação literária - Literate programming

Literate Programming de Donald Knuth é o livro seminal sobre programação literária

A programação literária é um paradigma de programação introduzido por Donald Knuth no qual um programa de computador recebe uma explicação de sua lógica em uma linguagem natural , como o inglês, intercalada com fragmentos de macros e código-fonte tradicional , a partir do qual o código-fonte compilável pode ser gerado. A abordagem é usada em computação científica e em ciência de dados rotineiramente para pesquisas reproduzíveis e propósitos de acesso aberto . Ferramentas de programação letradas são usadas por milhões de programadores hoje.

O paradigma de programação letrado, conforme concebido por Knuth, representa um afastamento da escrita de programas de computador na forma e ordem impostas pelo computador e, em vez disso, permite que os programadores desenvolvam programas na ordem exigida pela lógica e pelo fluxo de seus pensamentos. Os programas letrados são escritos como uma exposição ininterrupta da lógica em uma linguagem humana comum , bem como o texto de um ensaio , no qual macros são incluídas para ocultar abstrações e o código-fonte tradicional .

Ferramentas de programação literária (LP) são usadas para obter duas representações de um arquivo de origem literário: uma adequada para posterior compilação ou execução por um computador, o código "entrelaçado", e outra para visualização como documentação formatada , que é chamada de "tecido "da fonte letrada. Enquanto a primeira geração de ferramentas de programação letradas eram específicas à linguagem de computador , as últimas são agnósticas em relação às linguagens e existem acima das linguagens de programação.

História e filosofia

A programação literária foi introduzida pela primeira vez por Knuth em 1984. A principal intenção por trás dessa abordagem era tratar um programa como literatura compreensível para os seres humanos. Essa abordagem foi implementada na Universidade de Stanford como parte da pesquisa sobre algoritmos e tipografia digital . Essa implementação foi chamada de " WEB " por Knuth, pois ele acreditava que era uma das poucas palavras de três letras em inglês que ainda não tinha sido aplicada à computação. No entanto, ele se assemelha corretamente à natureza complicada do software delicadamente montado a partir de materiais simples. A prática da programação letrada teve um ressurgimento importante na década de 2010 com o uso de notebooks, especialmente em data science .

Conceito

Programação letrada é escrever a lógica do programa em uma linguagem humana com fragmentos de código e macros incluídos (separados por uma marcação primitiva). As macros em um arquivo de origem letrado são simplesmente frases explicativas ou semelhantes a títulos em uma linguagem humana que descrevem abstrações humanas criadas durante a solução do problema de programação e ocultam fragmentos de código ou macros de nível inferior. Essas macros são semelhantes aos algoritmos em pseudocódigo normalmente usados ​​no ensino de ciência da computação . Essas frases explicativas arbitrárias tornam-se novos operadores precisos, criados instantaneamente pelo programador, formando uma meta-linguagem sobre a linguagem de programação subjacente.

Um pré - processador é usado para substituir hierarquias arbitrárias, ou melhor, "redes 'interconectadas de macros", para produzir o código-fonte compilável com um comando ("entrelaçar") e a documentação com outro ("tecer"). O pré-processador também fornece a capacidade de escrever o conteúdo das macros e adicionar macros já criadas em qualquer lugar no texto do arquivo de origem do programa literário, eliminando assim a necessidade de manter em mente as restrições impostas pelas linguagens de programação tradicionais ou para interromper o fluxo do pensamento.

Vantagens

De acordo com Knuth, a programação letrada fornece programas de alta qualidade, uma vez que força os programadores a declarar explicitamente o que está por trás do programa, tornando mais óbvias as decisões de design mal pensadas. Knuth também afirma que a programação letrada fornece um sistema de documentação de primeira linha, que não é um complemento, mas é desenvolvido naturalmente no processo de exposição dos pensamentos de alguém durante a criação de um programa. A documentação resultante permite ao autor reiniciar seus próprios processos de pensamento em qualquer momento posterior e permite que outros programadores entendam a construção do programa mais facilmente. Isso difere da documentação tradicional, na qual um programador é apresentado com o código-fonte que segue uma ordem imposta pelo compilador e deve decifrar o processo de pensamento por trás do programa a partir do código e seus comentários associados. As capacidades da meta-linguagem da programação letrada também são alegadas para facilitar o pensamento, dando uma "visão panorâmica" do código e aumentando o número de conceitos que a mente pode reter e processar com sucesso. A aplicabilidade do conceito à programação em grande escala, a de programas de nível comercial, é comprovada por uma edição do código TeX como um programa letrado.

Knuth também afirma que a programação letrada pode levar a uma fácil portabilidade de software para vários ambientes e até cita a implementação do TeX como exemplo.

Contraste com a geração de documentação

A programação letrada é muitas vezes mal interpretada como se referindo apenas à documentação formatada produzida a partir de um arquivo comum com código-fonte e comentários - o que é apropriadamente chamado de geração de documentação - ou a comentários volumosos incluídos com o código. Este é o oposto da programação letrada: código bem documentado ou documentação extraída do código segue a estrutura do código, com documentação embutida no código; enquanto na programação letrada, o código está embutido na documentação, com o código seguindo a estrutura da documentação.

Esse equívoco levou a alegações de que as ferramentas de extração de comentários, como os sistemas Perl Plain Old Documentation ou Java Javadoc , são "ferramentas de programação letradas". No entanto, porque essas ferramentas não implementam a "teia de conceitos abstratos" escondida atrás do sistema de macros de linguagem natural, ou fornecem a capacidade de alterar a ordem do código-fonte de uma sequência imposta por máquina para uma conveniente para a mente humana , eles não podem ser chamados de ferramentas de programação letradas no sentido pretendido por Knuth.

Crítica

Em 1986, Jon Bentley pediu a Knuth para demonstrar o conceito de programação letrada para sua coluna Pérolas de Programação nas Comunicações do ACM , escrevendo um programa na WEB. Knuth enviou-lhe um programa para um problema discutido anteriormente na coluna (o da amostragem de M números aleatórios no intervalo 1 .. N ), e também pediu uma "atribuição". Bentley deu-lhe o problema de encontrar as palavras K mais comuns em um arquivo de texto, para o qual Knuth escreveu um programa WEB que foi publicado junto com uma revisão de Douglas McIlroy, da Bell Labs. McIlroy elogiou a complexidade da solução de Knuth, sua escolha de uma estrutura de dados (uma variante do hash trie de Frank M. Liang ) e a apresentação. Ele criticou algumas questões de estilo, como o fato de que a ideia central foi descrita no final do artigo, o uso de constantes mágicas e a ausência de um diagrama para acompanhar a explicação da estrutura de dados. McIlroy, conhecido por pipelines Unix , também usou a revisão para criticar a própria tarefa de programação, apontando que no Unix (desenvolvido no Bell Labs), utilitários para processamento de texto ( tr , sort , uniq e sed ) foram escritos anteriormente e que foram " staples ", e uma solução fácil de implementar, depurar e reutilizar poderia ser obtida combinando esses utilitários em um script de shell de seis linhas . Em resposta, Bentley escreveu que:

[McIlroy] admira a execução da solução, mas falha o problema por motivos de engenharia. (Essa é, obviamente, minha responsabilidade como responsável pela atribuição de problemas; Knuth resolveu o problema que lhe foi dado por motivos que são importantes para a maioria dos engenheiros - os contracheques fornecidos por seus responsáveis ​​pela atribuição de problemas).

McIlroy mais tarde admitiu que sua crítica foi injusta, já que ele criticou o programa de Knuth por motivos de engenharia, enquanto o propósito de Knuth era apenas demonstrar a técnica de programação letrada. Em 1987, Communications of the ACM publicou um artigo subsequente que ilustrou a programação letrada com um programa C que combinava a abordagem artística de Knuth com a abordagem de engenharia de McIlroy, com uma crítica de John Gilbert.

Fluxo de Trabalho

A implementação da programação alfabetizada consiste em duas etapas:

  1. Tecelagem: Gerando um documento abrangente sobre o programa e sua manutenção.
  2. Emaranhado: Gerando código executável de máquina

A tecelagem e o emaranhamento são feitos na mesma fonte para que sejam consistentes um com o outro.

Exemplo

Um exemplo clássico de programação letrada é a implementação letrada do programa padrão de contagem de palavras do Unix wc . Knuth apresentou uma versão CWEB desse exemplo no Capítulo 12 de seu livro Literate Programming . O mesmo exemplo foi reescrito posteriormente para a ferramenta de programação noweb literate. Este exemplo fornece uma boa ilustração dos elementos básicos da programação letrada.

Criação de macros

O seguinte fragmento do wcprograma literato mostra como frases descritivas arbitrárias em uma linguagem natural são usadas em um programa literário para criar macros, que agem como novos "operadores" na linguagem de programação literária e escondem pedaços de código ou outras macros. A notação de marcação consiste em colchetes angulares duplos (" <<...>>") que indicam macros, o @símbolo " " que indica o final da seção de código em um arquivo noweb. O <<*>>símbolo " " representa a "raiz", o nó superior a partir do qual a ferramenta de programação letrada começará a expandir a teia de macros. Na verdade, escrever o código-fonte expandido pode ser feito a partir de qualquer seção ou subseção (ou seja, um trecho de código designado como " <<name of the chunk>>=", com o sinal de igual), de modo que um arquivo de programa letrado pode conter vários arquivos com código-fonte de máquina.

The purpose of wc is to count lines, words, and/or characters in a list of files. The
number of lines in a file is ......../more explanations/

Here, then, is an overview of the file wc.c that is defined by the noweb program wc.nw:
    <<*>>=
    <<Header files to include>>
    <<Definitions>>
    <<Global variables>>
    <<Functions>>
    <<The main program>>
    @

We must include the standard I/O definitions, since we want to send formatted output
to stdout and stderr.
    <<Header files to include>>=
    #include <stdio.h>
    @

O desdobramento dos pedaços pode ser feito em qualquer lugar do arquivo de texto do programa letrado, não necessariamente na ordem em que são sequenciados no pedaço envolvente, mas como é exigido pela lógica refletida no texto explicativo que envolve todo o programa.

Programe como uma web - macros não são apenas nomes de seção

Macros não são iguais a "nomes de seção" na documentação padrão. Macros de programação letrados podem ocultar qualquer pedaço de código por trás deles e ser usados ​​dentro de qualquer operador de linguagem de máquina de baixo nível, geralmente dentro de operadores lógicos como " if", " while" ou " case". Isso é ilustrado pelo seguinte fragmento do wcprograma de alfabetização.

The present chunk, which does the counting, was actually one of
the simplest to write. We look at each character and change state if it begins or ends
a word.

    <<Scan file>>=
    while (1) {
      <<Fill buffer if it is empty; break at end of file>>
      c = *ptr++;
      if (c > ' ' && c < 0177) {
        /* visible ASCII codes */
        if (!in_word) {
          word_count++;
          in_word = 1;
        }
        continue;
      }
      if (c == '\n') line_count++;
      else if (c != ' ' && c != '\t') continue;
      in_word = 0;
        /* c is newline, space, or tab */
    }
    @

Na verdade, as macros podem representar qualquer pedaço arbitrário de código ou outras macros e, portanto, são mais gerais do que "fragmentação" de cima para baixo ou de baixo para cima, ou do que subseção. Knuth diz que, quando percebeu isso, começou a pensar em um programa como uma teia de várias partes.

Ordem da lógica humana, não do compilador

Em um programa alfabetizado agora, além da ordem livre de sua exposição, os pedaços por trás das macros, uma vez introduzidos com " <<...>>=", podem ser aumentados posteriormente em qualquer lugar no arquivo simplesmente escrevendo " <<name of the chunk>>=" e adicionando mais conteúdo a ele, como o trecho a seguir ilustra ("mais" é adicionado pelo formatador do documento para facilitar a leitura e não está no código).

 The grand totals must be initialized to zero at the beginning of the program.
If we made these variables local to main, we would have to do this  initialization
explicitly; however, C globals are automatically zeroed. (Or rather,``statically
zeroed.'' (Get it?)

    <<Global variables>>+=
    long tot_word_count, tot_line_count,
         tot_char_count;
      /* total number of words, lines, chars */
    @

Registro da linha de pensamento

A documentação para um programa de alfabetização é produzida como parte da elaboração do programa. Em vez de comentários fornecidos como notas laterais para o código-fonte, um programa letrado contém a explicação dos conceitos em cada nível, com os conceitos de nível inferior adiados para seu lugar apropriado, o que permite uma melhor comunicação do pensamento. Os fragmentos do letrado wcacima mostram como uma explicação do programa e seu código-fonte estão entrelaçados. Essa exposição de idéias cria o fluxo de pensamento que é como uma obra literária. Knuth escreveu um "romance" que explica o código do jogo de ficção interativo Colossal Cave Adventure .

Exemplos notáveis

  • Axiom , que é uma evolução do scratchpad, um sistema de álgebra computacional desenvolvido pela IBM. Agora está sendo desenvolvido por Tim Daly, um dos desenvolvedores do scratchpad, Axiom é totalmente escrito como um programa letrado.

Práticas de programação letradas

O primeiro ambiente de programação literário publicado foi WEB , introduzido por Knuth em 1981 para seu sistema de composição TeX ; ele usa Pascal como sua linguagem de programação subjacente e TeX para a composição da documentação. O código-fonte completo do TeX comentado foi publicado em Knuth's TeX: The program , volume B de seus 5 volumes de Computers and Typesetting . Knuth tinha usado em particular um sistema de programação letrado chamado DOC já em 1979. Ele foi inspirado pelas ideias de Pierre-Arnoul de Marneffe . O CWEB gratuito , escrito por Knuth e Silvio Levy, é adaptado para WEB para C e C ++ , roda na maioria dos sistemas operacionais e pode produzir documentação TeX e PDF .

Existem várias outras implementações do conceito de programação letrado (alguns deles não têm macros e, portanto, violam a ordem do princípio da lógica humana ):

Nome Idiomas Suportados Escrito em Linguagem de marcação Comentários
Observável JavaScript JavaScript , TypeScript TeX ( KaTeX ), HTML Armazenado na nuvem com interface da web. Os conteúdos podem ser publicados como websites. Versão controlada; a plataforma define suas próprias operações de controle de versão. As células de código podem ser organizadas fora de ordem ; notebooks observáveis ​​construirão o gráfico de execução (um DAG ) automaticamente. Uma rica biblioteca padrão implementada com recursos modernos de JavaScript . As células de diferentes blocos de anotações observáveis ​​podem fazer referência umas às outras. Bibliotecas Npm podem ser importadas em tempo real.
REDE Pascal Pascal TeX O primeiro ambiente de programação alfabetizado publicado.
CWEB C ++ e C C TeX A WEB é adaptada para C e C ++ .
NoWEB Algum C , AWK e ícone LaTeX , TeX , HTML e troff É bem conhecido por sua simplicidade e permite a formatação de texto em HTML em vez de passar pelo sistema TeX.
Alfabetizado Algum D Markdown Suporta equações TeX. Compatível com Vim ( literate.vim )
FunnelWeb Algum C HTML e TeX Tem uma marcação mais complicada, mas tem muitas opções mais flexíveis
NuWEB Algum C ++ Látex Ele pode traduzir uma única fonte LP em qualquer número de arquivos de código. Ele faz isso em uma única invocação; ele não possui comandos de entrelaçamento e entrelaçamento separados. Não tem a extensibilidade de noweb
pyWeb Algum Pitão ReStructuredText Respeita o recuo que o torna utilizável para linguagens como Python , embora você possa usá-lo para qualquer linguagem de programação.
Molly Algum Perl HTML Tem como objetivo modernizá-lo e escalá-lo com "HTML dobrável" e "visualizações virtuais" no código. Ele usa a marcação "noweb" para os arquivos de origem alfabetizados.
Codnar Rubi É uma ferramenta de programação de letramento inverso disponível como Ruby Gem. Em vez de o código-fonte legível por máquina ser extraído das fontes de documentação letradas, a documentação letrada é extraída dos arquivos normais de código-fonte legíveis por máquina.
Emacs org-mode Algum Emacs Lisp Texto simples Requer o Babel, que permite a incorporação de blocos de código-fonte de várias linguagens de programação em um único documento de texto. Os blocos de código podem compartilhar dados entre si, exibir imagens embutidas ou ser analisados ​​em código-fonte puro usando a sintaxe de referência do noweb .
CoffeeScript CoffeeScript CoffeeScript , JavaScript Markdown CoffeeScript oferece suporte a um modo "alfabetizado", que permite que os programas sejam compilados a partir de um documento-fonte escrito em Markdown com blocos de código recuados.
Planilhas Maple Maple (software) XML As planilhas do Maple são um ambiente de programação independente de plataforma que combina texto e gráficos com código ao vivo para computação simbólica. "Folhas de trabalho do Maple" . www.maplesoft.com . Página visitada em 2020-05-30 .
Cadernos Wolfram Wolfram Language Wolfram Language Os notebooks Wolfram são um método de programação versado em plataforma independente que combina texto e gráficos com código ativo.
Playgrounds Swift (linguagem de programação) Fornece um ambiente de programação interativo que avalia cada instrução e exibe resultados ao vivo conforme o código é editado. Playgrounds também permitem que o usuário adicione linguagem de marcação junto com o código que fornece cabeçalhos, formatação embutida e imagens.
Jupyter Notebook , anteriormente IPython Notebook Python e qualquer um com um kernel Jupyter HTML Funciona no formato de cadernos, que combinam cabeçalhos, texto (incluindo LaTeX), plotagens, etc. com o código escrito.
nbdev Notebook Python e Jupyter nbdev é uma biblioteca que permite desenvolver uma biblioteca python em Notebooks Jupyter, colocando todo o seu código, testes e documentação em um só lugar.
Julia (linguagem de programação) Suporta o modo de desenvolvimento iJulia que foi inspirado no iPython.
Agda (linguagem de programação) Oferece suporte a uma forma limitada de programação alfabetizada pronta para uso.
Linguagem de programação Eve Os programas são principalmente em prosa. Eve combina variantes de Datalog e Markdown com um ambiente de desenvolvimento gráfico ao vivo.
Notebooks R Markdown (ou Notebooks R) R , Python , Julia e SQL PDF , Microsoft Word , LibreOffice e formatos de apresentação ou apresentação de slides , além de formatos interativos como widgets HTML
Sweave R PDF
Knitr R LaTeX , PDF , LyX , HTML , Markdown , AsciiDoc e reStructuredText
Codebraid Pandoc , Rust , Julia , Python , R , Bash
Pweave Pitão PDF

Outras ferramentas úteis incluem

  • O editor de texto Leo é um editor de esboço que suporta marcação opcional noweb e CWEB. O autor de Leo combina duas abordagens diferentes: primeiro, Leo é um editor de esboços, o que ajuda no gerenciamento de grandes textos; segundo, Leo incorpora algumas das ideias de programação letrada, que em sua forma pura (ou seja, a maneira como é usada pela ferramenta Knuth Web ou ferramentas como "noweb") só é possível com algum grau de inventividade e o uso do editor de uma forma não exatamente imaginada por seu autor (em nós @root modificados). No entanto, esta e outras extensões (nós @file) tornam a programação de esboço e o gerenciamento de texto bem-sucedidos e fáceis e, em alguns aspectos, semelhantes à programação literária.
  • A linguagem de programação Haskell tem suporte nativo para programação semi-alfabetizada. O compilador / interpretador oferece suporte a duas extensões de nome de arquivo: .hse .lhs; o último representa o letrado Haskell.
Os scripts letrados podem ser textos fonte completos em LaTeX, ao mesmo tempo em que podem ser compilados, sem alterações, pois o interpretador apenas compila o texto em um ambiente de código, por exemplo
% here text describing the function:
\begin{code}
fact 0 = 1
fact (n+1) = (n+1) * fact n
\end{code}
here more text
O código também pode ser marcado no estilo Richard Bird, começando cada linha com um símbolo de maior que e um espaço, precedendo e terminando o trecho de código com linhas em branco.
O listingspacote LaTeX fornece um lstlistingambiente que pode ser usado para embelezar o código-fonte. Ele pode ser usado para definir um codeambiente a ser usado em Haskell para imprimir os símbolos como:
\newenvironment{code}{\lstlistings[language=Haskell]}{\endlstlistings}

\begin{code}
comp :: (beta -> gamma) -> (alpha -> beta) -> (alpha -> gamma)
(g `comp` f) x = g(f x)
\end{code}
pode ser configurado para produzir algo assim:
Embora o pacote não forneça meios para organizar pedaços de código, pode-se dividir o código-fonte do LaTeX em arquivos diferentes. Consulte o manual de listas para uma visão geral.
  • O sistema Web 68 Literate Programming usava Algol 68 como a linguagem de programação subjacente, embora não houvesse nada no 'tangente' do pré-processador para forçar o uso dessa linguagem.
  • O mecanismo de personalização da Iniciativa de Codificação de Texto, que permite a restrição, modificação ou extensão do esquema TEI , permite que os usuários misturem documentação em prosa com fragmentos de especificação de esquema em seu formato One Document Does-it-all . A partir dessa documentação, esquemas e pipelines de modelo de processamento podem ser gerados e o paradigma de programação literária de Knuth é citado como a inspiração para essa forma de trabalhar.

Veja também

  • Gerador de documentação - o inverso da programação letrada, onde a documentação é incorporada e gerada a partir do código-fonte
  • Interface de notebook - ambiente de notebook virtual usado para programação literária
  • Sweave e Knitr - exemplos de uso da ferramenta Literate Programming "noweb" dentro da linguagem R para a criação de relatórios estatísticos dinâmicos
  • Código autodocumentado - código -fonte que pode ser facilmente compreendido sem documentação

Referências

Leitura adicional

links externos