Por que estudar um intérprete lisp em lisp é tão importante?

30

Eu já vi muitos currículos de CS e sugestões de aprendizado para novos programadores que pedem que o aspirante a programador estude um intérprete de cisco escrito especificamente em cisco. Todos esses sites dizem coisas semelhantes a "é uma revelação intelectual", "é uma experiência de iluminação que todo programador sério deveria ter" ou "mostra as relações de hardware / software" e outras declarações vagas, principalmente de deste artigo, retirado de este respeitável como fazer .

O sentimento geral da minha pergunta é: como o lisp alcança os objetivos acima e por que o lisp? Por que não outra língua?

Estou perguntando isso porque acabei de escrever um interpretador de esquema em esquema (retirado do SICP http://mitpress.mit.edu/sicp/ ) e agora estou escrevendo um interpretador de python em esquema e estou lutando para ter essa epifania lendária isso deveria vir especificamente do primeiro. Estou procurando detalhes técnicos específicos entre os dois idiomas que posso explorar em seus intérpretes de esquema para entender melhor como os programas funcionam.

Mais especificamente:

Por que o estudo de um intérprete escrito na linguagem que ele interpreta é tão enfatizado - é apenas um ótimo exercício mental manter a linguagem original e a linguagem construída corretas ou existem problemas específicos cujas soluções só podem ser encontradas na natureza da linguagem? linguagem original?

Como os intérpretes lisp demonstram bons conceitos de arquitetura para o futuro design de software?

O que eu sentiria falta se fizesse esse exercício em uma linguagem diferente como C ++ ou Java?

Qual é a explicação mais usada ou "ferramenta mental" deste exercício? **

** Eu selecionei a resposta que eu fiz porque eu tenho notado que eu ganhei com este exercício mais habilidade em projetar ferramentas parsing na minha cabeça do que qualquer outra ferramenta única e eu gostaria de encontrar diferentes métodos de análise que pode funcionar melhor para o esquema intérprete que o intérprete python.

Ma-at
fonte
4
@gnat Não é exatamente um conselho de carreira, mas uma pergunta "o que há de tão bom no Lisp".
Robert Harvey
11
@RobertHarvey esse link não é apenas para carreira, mas também para aconselhamento educacional , eu quis dizer isso. Mas, bem, Lisp-é tão grande é provavelmente uma boa opção também
mosquito
11
Parece que você está perguntando o que aprenderá com um exercício específico. Sua reticência é um sinal de preguiça, essencial para qualquer bom programador, mas, independentemente da única maneira de descobrir o que você aprenderá com um exercício, é fazê-lo e ver. Ninguém pode lhe dizer o que você aprenderá com isso, apenas precisará fazê-lo.
Jimmy Hoffa
2
Embora essa questão esteja relacionada à educação como um todo, eu não a classificaria como "aconselhamento educacional" da maneira "que idioma devo aprender?" é. Ou seja, não é específico para um determinado tipo de curso ou trabalho. De fato, se você cortar algumas das palavras-chave da educação, essa é uma pergunta sobre linguagens de programação como um todo, cujas respostas discutem os recursos da linguagem. Também não é realmente específico para o Lisp, mas pode ser aplicado a outras linguagens homoicônicas como o xslt. Portanto, não direi que essa é uma pergunta perfeita, apenas que não é simplesmente "conselho de carreira".
TheRubberDuck

Respostas:

17

Correndo o risco de dar uma resposta "eu também", se você tentar, verá ...

Se você estuda linguagens de computador, é provável que tenha a impressão de que é pelo menos metade da análise. Se você aprender Lisp, perceberá que analisar a sintaxe da superfície nada mais é do que uma conveniência para pessoas (como a maioria de nós) que não gostam de muitos parênteses irritantes.

Então você poderia perceber que um grande preço foi pago por essa conveniência. No Lisp, é trivial para um programa criar outro programa e executá-lo. Em outras línguas, é uma técnica avançada, como multiplicar números romanos.

Claro, quase todo mundo perguntaria "quem precisa fazer isso?" Bem, você pode muito bem ver que ele abre uma visão inteira de coisas que você nem percebeu que não podia fazer antes. Você pode fazer isso em outros idiomas, mas não tão facilmente.

INSERIDO para responder ao comentário de Izkata:

  • O programa SHRDLU de entendimento do idioma natural funcionou ao traduzir uma declaração ou pergunta em inglês em um programa em um dialeto Lisp chamado MICRO-PLANNER e executá-lo.
  • Programas que manipulam programas, por exemplo, para simplificá-los ou prová-los corretos, são naturalmente escritos em Lisp.
  • Usei a geração de programas em um programa para compreender cenas visuais, onde ele tinha que lidar com todas as simetrias capazes de objetos tridimensionais, sem multiplicar o código.
  • Qualquer coisa relacionada à lógica e à prova de teoremas trata da manipulação de expressões lógicas, que são uma forma de programa.
  • A matemática simbólica, como cálculo integral ou diferencial simbólico, envolve a manipulação de expressões matemáticas, que são como programas em miniatura.
  • Qualquer problema envolvendo geração de código, ou o termo mais sofisticado "avaliação parcial", é natural no Lisp. Eu fiz isso para um programa de ponte de banco de dados há muito tempo. Fiz isso em C, o que não foi tão fácil quanto o Lisp, mas recebi a ideia do Lisp. Isso foi considerado uma técnica que quase ninguém poderia fazer naquele momento (especialmente os chefes de COBOL). Talvez mais agora, espero.

... isso são apenas alguns ...

Então você percebe que algumas coisas consideradas "modernas" hoje são obsoletas em Lisp há 40 anos. Como programação funcional. Como coleta de lixo. Como fechamentos.

Isso não quer dizer que as línguas modernas não tenham novas boas idéias, como OOP, etc. Mas se você aprender o Lisp, isso ampliará sua perspectiva.

Mike Dunlavey
fonte
You can do it in other languages, but not nearly so easily.- Gostar? (A pergunta me parece ser, pois declarações como estas são muitas vezes feitas, mas quase nunca ser mais específico)
Izkata
Pensei pela primeira vez que o mundo foi revolucionado quando percebi que o javascript poderia imprimir seu próprio código-fonte e os objetos poderiam ser percorridos para obter uma string literal que pode ser alterada para o literal do objeto. Então percebi que o Perl tinha isso tudo junto com $ Data :: Dumper :: Deparse, e então percebi que o lisp tinha isso para sempre. A compreensão de interpretadores libera esse poder que sempre existe para criar módulos vivos, e no Lisp isso é mais acessível do que qualquer outra linguagem.
Dmitry
O engraçado é que um programador Lisp ciente dos internos do Lisps sempre pode criar seu próprio front-end do Lisp para qualquer linguagem dinâmica, de javascript a bash ou perl ou python; lisp muito bem a partir do ambiente disponível.
Dmitry
19

A resposta simples para sua pergunta é experimentar o Lisp, de preferência em conjunto com o SICP . Então você será iluminado.

Dito isto...

Código é dados
A maioria dos idiomas faz uma distinção nítida entre código e dados; Lisp não. Isso possibilita, por exemplo, escrever trivialmente um analisador Lisp no Lisp e manipular o código Lisp no Lisp. A melhor descrição desse esclarecimento que encontrei é A natureza do Lisp .

Isso é verdade em parte porque a sintaxe do idioma é muito simples. Possibilita coisas no Lisp (como metaprogramação) que são impraticáveis ​​em outros idiomas porque a sintaxe atrapalha.

Leitura adicional
superando as médias

Robert Harvey
fonte
3
O segundo parágrafo não faz sentido: homoiconicidade! = Sintaxe simples; A sintaxe simples facilita a gravação de um analisador Lisp em qualquer idioma (veja isso ). O terceiro parágrafo é vago, precisa de exemplos.
@MattFenwick é verdade que a homoiconicidade pode ser feita com sintaxe complexa, mas isso seria extremamente difícil. É justo supor que, se você estiver lidando com uma sintaxe homoicônica, será simples, se por outro motivo não for a consistência exigida, que tornará inefavelmente mais fácil de seguir do que uma sintaxe não homoicônica. Embora seu segundo ponto é uma boa, LISP é fácil de analisar porque é sintaxe simples, não por causa de homoiconicity (mesmo se o homoiconicity é a causa para que a simplicidade)
Jimmy Hoffa
11
De qualquer forma, há pouca sobrecarga em pegar um valor de dados e interpretá-lo como um programa. Isso é uma coisa legal. A programação por configuração é simples quando tudo o que você precisa fazer é escrever um intérprete para os dados de configuração. Transformações matemáticas avançadas (que são difíceis de implementar em linguagens com estado) são frequentemente "reduzidas" a meras transformações sintáticas do puro fragmento de Lisp.
nomen
11
@ MattFenwick: removi a palavra "Homoiconicidade" da minha resposta.
Robert Harvey
11
Eu gostaria de poder dar mais de um +1 para The Nature of Lisp; Eu nunca vi uma explicação tão boa.
Doval 30/04
9

Por que o estudo de um intérprete escrito no idioma que ele interpreta é tão enfatizado?

Em geral, o estudo de um intérprete fornece informações sobre o idioma e os recursos. Em geral, estudar código em uma linguagem de programação é como praticar uma linguagem falada ouvindo e lendo: familiariza-o com o que essa linguagem pode fazer, como é usada e com "expressões idiomáticas" comuns. Mais especificamente, Lisp é uma linguagem homoicônica, o que significa que sua sintaxe para expressões é a mesma que para dados. Escrever código no Lisp parece terrivelmente com você escrevendo uma lista e vice-versa. Assim, interpretar o código Lisp com o código Lisp é tão simples quanto percorrer listas com care cdr.

Como devo aproveitar esse exercício para tirar o máximo proveito dele conceitualmente?

Pense em como o intérprete se interpretaria - em muitas implementações meta-circulares (onde uma linguagem homoicônica se interpreta) pode simplesmente "passar" pela função. Por exemplo, para implementar car, basta usar caro argumento. Isso tira a ênfase dos mecanismos de armazenamento de dados e foca na funcionalidade.

Como os intérpretes lisp demonstram bons conceitos de arquitetura para o futuro design de software?

Os intérpretes podem ser muito complicados, o que incentiva uma boa arquitetura ao projetá-los. Com isso em mente, este é mais dependente do intérprete individual.

O que eu sentiria falta se fizesse esse exercício em uma linguagem diferente como C ++ ou Java?

Essas linguagens não são homoicônicas, portanto não se beneficiam da graça e simplicidade de um intérprete meta-circular de Lisp. Isso torna o exercício mais difícil e talvez menos comum, mas eu não diria que é realmente menos benéfico.

Qual é a explicação mais usada ou "ferramenta mental" deste exercício?

Não sei se tenho uma boa resposta para essa; simplesmente que ajuda a ver como o intérprete funciona e, talvez mais importante, mexer com ele para ver como pequenas alterações no idioma podem ser facilmente implementadas.

TheRubberDuck
fonte
5

O próprio LISP está estruturado de uma maneira que facilita a análise. Se você tentar escrever um compilador, perceberá que é muito mais fácil se tudo no seu idioma for uma expressão e tiver um baixo nível de ambiguidade. O LISP força parênteses em todos os lugares para eliminar a ambiguidade e não possui declarações, apenas expressões.

O fato de o LISP ser muito fácil de analisar incentiva os usuários a analisar seu próprio código-fonte e fazer truques de mágica com ele. A linha entre dados e código fica embaçada e você pode facilmente fazer coisas que normalmente exigem bastante esforço, como reflexão, reescrita dinâmica de código, plugins e serialização.

Essa é a essência disso. Provavelmente, o exercício pretende fornecer algumas dicas sobre o que é possível quando o código é facilmente analisável por si mesmo.

Alexander Torstling
fonte
Não é fácil analisar o Lisp. Expressões S são fáceis de analisar. Além disso, você precisa analisar o Lisp.
Rainer Joswig
@Rainer: Isso não é apenas uma brincadeira? No meu mundo, analisar significa ir do texto para um AST, que não diz nada sobre a interpretação dos comandos.
Alexander Torstling
No C ++, o analisador detectará uma declaração de função sintaticamente incorreta. Lisp não. O leitor não sabe nada sobre a linguagem de programação Lisp. O analisador C ++ conhece a sintaxe completa do C ++. O leitor Lisp conhece apenas expressões s.
Rainer Joswig
Ah, então eu entendo o que você quer dizer. É verdade, embora eu ainda ache que um avaliador simples do cisco seria mais fácil de construir do que um simples c ++. É isso que eles fazem no SICP, não é (já faz um tempo desde que eu o li)?
Alexander Torstling
a linguagem usada no SICP é muito simples, nem mesmo o esquema completo. Um intérprete para uma pequena linguagem C também deve ser simples. C ++ é grande. Algumas de suas dificuldades vêm de um número relativamente alto de sintaxe interna. Em um sistema Lisp típico, grande parte da sintaxe é criada com macros - fora do intérprete. Macros implementam sintaxe e um mecanismo de extensão para transformações de origem. Isso mantém o núcleo menor. Mas as macros podem ser enormes. Por exemplo, a implementação da construção LOOP possui mais de 2000 linhas de código macro complexo.
Rainer Joswig
4

Não tenho certeza se é realmente importante para todos. Você pode ser um desenvolvedor de sucesso sem saber como um intérprete Lisp funciona. Ao estudar Ciência da Computação, as idéias básicas do Lisp devem ser aprendidas.

Os intérpretes do Lisp são importantes para os programadores do Lisp. Eles precisam entender como um intérprete ([e compilador] 1 ) funciona, para entender completamente como usar a linguagem.

Um intérprete Lisp é frequentemente usado como uma ferramenta em ciência da computação para ensinar aos alunos algumas coisas:

Como um dispositivo de ensino, um intérprete Lisp é útil, porque pode ser aprendido e entendido em pouco tempo. Como poucos estudantes já conhecem o Lisp, eles estão em um campo nivelado quando se trata de aprender os conceitos acima.

Rainer Joswig
fonte