Loop de leitura-avaliação-impressão - Read–eval–print loop

Um loop read-eval-print ( REPL ), também denominado de nível superior interativo ou shell de linguagem , é um ambiente de programação de computador interativo simples que recebe entradas de um único usuário, as executa e retorna o resultado ao usuário; um programa escrito em um ambiente REPL é executado por partes. O termo é geralmente usado para se referir a interfaces de programação semelhantes ao ambiente interativo de máquina Lisp clássico . Exemplos comuns incluem shells de linha de comando e ambientes semelhantes para linguagens de programação , e a técnica é muito característica das linguagens de script .

Visão geral

Em um REPL, o usuário insere uma ou mais expressões (em vez de uma unidade de compilação inteira ) e o REPL as avalia e exibe os resultados. O nome loop read – eval – print vem dos nomes das funções primitivas Lisp que implementam esta funcionalidade:

  • A função de leitura aceita uma expressão do usuário e a analisa em uma estrutura de dados na memória. Por exemplo, o usuário pode inserir a expressão s (+ 1 2 3) , que é analisada em uma lista vinculada contendo quatro elementos de dados.
  • A função eval pega essa estrutura de dados interna e a avalia. Em Lisp, avaliar uma expressão s começando com o nome de uma função significa chamar essa função nos argumentos que compõem o resto da expressão. Portanto, a função +é chamada nos argumentos 1 2 3, produzindo o resultado 6.
  • A função de impressão pega o resultado gerado por eval e o imprime para o usuário. Se for uma expressão complexa, pode ser bem impressa para ser mais fácil de entender.

O ambiente de desenvolvimento então retorna ao estado de leitura, criando um loop, que termina quando o programa é fechado.

REPLs facilitam a programação exploratória e a depuração porque o programador pode inspecionar o resultado impresso antes de decidir qual expressão fornecer para a próxima leitura. O loop de leitura-avaliação-impressão envolve o programador com mais freqüência do que o ciclo clássico de edição-compilação-execução-depuração.

Como a função de impressão sai no mesmo formato textual que a função de leitura usa para entrada, a maioria dos resultados é impressa em um formato que pode ser copiado e colado de volta no REPL. No entanto, às vezes é necessário imprimir representações de elementos que não podem ser lidos de volta de maneira sensata, como um identificador de soquete ou uma instância de classe complexa. Nesses casos, deve haver uma sintaxe para objetos ilegíveis. Em Python, é a <__module__.class instance>notação, e em Common Lisp, a #<whatever>forma. O REPL do CLIM , SLIME e a Symbolics Lisp Machine também podem ler objetos ilegíveis. Eles registram para cada saída qual objeto foi impresso. Posteriormente, quando o código for lido de volta, o objeto será recuperado da saída impressa.

REPLs podem ser criados para oferecer suporte a qualquer idioma baseado em texto. O suporte REPL para linguagens compiladas é geralmente obtido através da implementação de um interpretador no topo de uma máquina virtual que fornece uma interface para o compilador. Por exemplo, começando com JDK 9, Java incluiu JShell como uma interface de linha de comando para a linguagem. Vários outros idiomas têm ferramentas de terceiros disponíveis para download que fornecem interação de shell semelhante com o idioma.

Usos

Como um shell , um ambiente REPL permite que os usuários acessem recursos relevantes de um sistema operacional, além de fornecer acesso a recursos de programação. O uso mais comum para REPLs fora dos shells do sistema operacional é para prototipagem instantânea . Outros usos incluem cálculo matemático, criação de documentos que integram análise científica (por exemplo, IPython ), manutenção de software interativa, benchmarking e exploração de algoritmo.

Especificidades do Lisp

Implementação

Uma definição mínima é:

(define (REPL env)
  (print (eval env (read)))
  (REPL env) )

Onde envrepresenta o evalambiente de graduação inicial . Também se presume que envpode ser atualizado destrutivamente por eval.

Funcionalidade

A funcionalidade típica fornecida por um Lisp REPL inclui:

  • Histórico de entradas e saídas.
  • As variáveis ​​são definidas para as expressões de entrada e resultados. Essas variáveis ​​também estão disponíveis no REPL. Por exemplo, em Common Lisp *se refere ao último resultado **e ***aos resultados anteriores a ele.
  • Níveis de REPLs. Em muitos sistemas Lisp, se ocorrer um erro durante a leitura, avaliação ou impressão de uma expressão, o sistema não é jogado de volta ao nível superior com uma mensagem de erro. Em vez disso, um novo REPL, um nível mais profundo, é iniciado no contexto de erro. O usuário pode então inspecionar o problema, corrigi-lo e continuar - se possível. Se ocorrer um erro em tal REPL de depuração, outro REPL, novamente um nível mais profundo, é iniciado. Freqüentemente, o REPL oferece comandos especiais de depuração.
  • Tratamento de erros . O REPL fornece reinicializações. Essas reinicializações podem ser usadas, quando ocorre um erro, para voltar a um determinado nível REPL.
  • Entrada e saída de objetos de dados sensíveis ao mouse .
  • Edição de entrada e conclusão específica de contexto sobre símbolos, nomes de caminhos, nomes de classes e outros objetos.
  • Ajuda e documentação para comandos.
  • Variáveis para controlar o leitor. Por exemplo, a variável * base de leitura * controla em que os números de base são lidos por padrão.
  • Variáveis ​​para controlar a impressora. Exemplo: comprimento máximo ou profundidade máxima das expressões a serem impressas.
  • Sintaxe de comando adicional. Alguns REPLs têm comandos que não seguem a sintaxe da expressão s, mas geralmente funcionam com dados Lisp como argumentos.
  • REPLs gráficos. Alguns REPLs Lisp (o CLIM Listener é um exemplo) aceitam também entradas e saídas gráficas.

Veja também

Referências

links externos