Pourquoi est-il si important d'étudier un interprète lisp dans lisp?

30

J'ai vu de nombreux curriculums CS et des suggestions d'apprentissage pour de nouveaux programmeurs qui appellent le programmeur en herbe à étudier un interprète lisp spécifiquement écrit en lisp. Tous ces sites disent des choses similaires à «c'est une révélation intellectuelle», «c'est une expérience d'illumination que tout programmeur sérieux devrait avoir» ou «il vous montre des relations matériel / logiciel» et d'autres déclarations vagues, en particulier de cet article tiré de ce mode d'emploi réputé .

Le sentiment général de ma question est, comment le lisp atteint-il les objectifs ci-dessus et pourquoi le lisp? Pourquoi pas une autre langue?

Je pose cette question parce que je viens de terminer l'écriture d'un interpréteur de schéma dans le schéma (tiré du SICP http://mitpress.mit.edu/sicp/ ) et maintenant j'écris un interprète python dans le schéma et j'ai du mal à avoir cette épiphanie légendaire qui est censé provenir spécifiquement de l'ancien. Je suis à la recherche de détails techniques spécifiques entre les deux langues que je peux exploiter dans leurs interprètes de schéma pour comprendre le fonctionnement des programmes.

Plus précisement:

Pourquoi l'étude d'un interprète écrit dans la langue qu'il interprète est-elle si soulignée - est-ce simplement un excellent exercice mental pour garder la langue originale et la langue construite droite ou y a-t-il des problèmes spécifiques dont les solutions ne peuvent être trouvées que dans la nature de la langue originale?

Comment les interprètes lisp démontrent-ils de bons concepts d'architecture pour la future conception de logiciels?

Que manquerais-je si je faisais cet exercice dans un langage différent comme C ++ ou Java?

Quel est le plat à emporter ou "outil mental" le plus utilisé dans cet exercice? **

** J'ai choisi la réponse que je l'ai fait parce que je l' ai remarqué que je l' ai acquise lors de cet exercice plus de compétences dans la conception d' outils d' analyse syntaxique dans ma tête que tout autre outil et je voudrais trouver différentes méthodes d'analyse qui peuvent mieux travailler pour le régime interprète que l'interpréteur python.

Ma-at
la source
4
@gnat Pas exactement des conseils de carrière, plutôt une question "ce qui est si bien avec Lisp".
Robert Harvey
1
@RobertHarvey ce lien n'est pas seulement pour la carrière mais aussi pour des conseils en éducation , je voulais dire cela. Mais bon, Lisp-is-so-great est probablement aussi un bon ajustement
moucher
1
Vous semblez demander ce que vous apprendrez d'un exercice particulier. Votre réticence est un signe de paresse, clé de tout bon programmeur, mais quelle que soit la seule façon de découvrir ce que vous apprendrez d'un exercice, c'est de le faire et de voir. Personne ne peut vous dire ce que vous apprendrez en faisant cela, il vous suffira de le faire.
Jimmy Hoffa
2
Bien que cette question se rapporte à l'éducation dans son ensemble, je ne la classerais pas comme un "conseil pédagogique" dans le sens "Quelle langue dois-je apprendre?" est. Autrement dit, ce n'est pas spécifique à un certain type de cours ou d'emploi. En fait, si vous supprimez certains des mots à la mode de l'éducation, il s'agit d'une question sur les langages de programmation dans leur ensemble, dont les réponses traitent des fonctionnalités du langage. Ce n'est vraiment pas spécifique à Lisp non plus, mais peut être appliqué à d'autres langages homoiconiques comme xslt. Je ne dirai donc pas que c'est une question parfaite, juste que ce n'est pas simplement des "conseils de carrière".
TheRubberDuck

Réponses:

17

Au risque de donner une réponse "moi aussi", si vous l'essayez, vous verrez ...

Si vous étudiez les langages informatiques, vous aurez probablement l'impression qu'il s'agit au moins de la moitié de l'analyse. Si vous apprenez le Lisp, vous vous rendrez compte que l'analyse de la syntaxe de surface n'est rien de plus qu'une commodité pour les personnes (comme la plupart d'entre nous) qui n'aiment pas beaucoup de parenthèses simples irritantes.

Vous pourriez alors réaliser qu'un gros prix a été payé pour cette commodité. En Lisp, il est trivial pour un programme de construire un autre programme et de l'exécuter. Dans d'autres langues, c'est une technique avancée, comme la multiplication en chiffres romains.

Bien sûr, presque tout le monde demanderait "qui doit faire ça?" Eh bien, vous pouvez très bien voir que cela ouvre toute une perspective de choses que vous n'aviez même jamais réalisé que vous ne pouviez pas faire auparavant. Vous pouvez le faire dans d'autres langues, mais pas si facilement.

INSÉRÉ pour répondre au commentaire d'Izkata:

  • Le programme de compréhension du langage naturel SHRDLU a fonctionné en traduisant une déclaration ou une question en anglais dans un programme dans un dialecte Lisp appelé MICRO-PLANNER et en l'exécutant.
  • Les programmes qui manipulent des programmes, par exemple pour les simplifier ou les prouver, sont naturellement écrits en Lisp.
  • J'ai utilisé la génération de programme dans un programme pour comprendre des scènes visuelles, où il devait gérer toutes les symétries capables dans les objets tridimensionnels, sans multiplier le code.
  • Tout ce qui a à voir avec la logique et la démonstration des théorèmes concerne la manipulation des expressions logiques, qui sont une forme de programme.
  • Les mathématiques symboliques, telles que le calcul symbolique intégral ou différentiel, impliquent la manipulation d'expressions mathématiques, qui sont comme des programmes miniatures.
  • Tout problème impliquant la génération de code, ou le terme plus élevé "évaluation partielle", est naturel en Lisp. J'ai fait cela pour un programme de pont de base de données il y a longtemps. Je l'ai fait en C, ce qui n'était pas aussi facile que Lisp, mais j'ai eu l'idée de Lisp. Cela a été considéré comme une technique que presque personne ne pouvait faire à l'époque (en particulier les têtes COBOL). Peut-être plus maintenant, j'espère.

... c'est juste quelques-uns ...

Ensuite, vous vous rendez compte que certaines choses qui sont considérées comme «modernes» aujourd'hui sont à l'ancienne à Lisp depuis 40 ans. Comme la programmation fonctionnelle. Comme la collecte des ordures. Comme des fermetures.

Cela ne veut pas dire que les langues modernes n'ont pas de nouvelles bonnes idées, comme la POO, etc. Mais si vous apprenez le lisp, cela élargira votre perspective.

Mike Dunlavey
la source
You can do it in other languages, but not nearly so easily.- Comme? (La question me semble être parce que de telles déclarations sont souvent faites, mais ne sont presque jamais plus précises)
Izkata
J'ai d'abord pensé que le monde était révolutionné lorsque j'ai réalisé que javascript pouvait imprimer son propre code source et que les objets pouvaient être parcourus pour obtenir un littéral de chaîne pouvant être évalué dans le littéral d'objet. Ensuite, j'ai réalisé que Perl avait tout cela avec $ Data :: Dumper :: Deparse, puis j'ai réalisé que lisp avait cela pour toujours. Comprendre les interprètes déverrouille ce pouvoir qui a toujours été là pour construire des modules vivants, et en Lisp, c'est plus accessible que n'importe quel autre langage.
Dmitry
ce qui est drôle, c'est qu'un programmeur Lisp conscient des internes Lisps peut toujours créer son propre frontend Lisp dans n'importe quel langage dynamique, de javascript à bash ou perl ou python; lisp bien amorcé à partir de l'environnement disponible.
Dmitry
19

La réponse simple à votre question est d'essayer Lisp, de préférence en conjonction avec SICP . Ensuite, vous serez éclairé.

Cela dit...

Le code est des données
La plupart des langues font une distinction nette entre le code et les données; Lisp non. Cela permet, par exemple, d'écrire trivialement un analyseur Lisp en Lisp, et de manipuler du code Lisp dans Lisp. La meilleure description de cette illumination que j'ai trouvée est La nature de Lisp .

Cela est vrai en partie parce que la syntaxe de la langue est si simple. Cela rend possible des choses en Lisp (comme la métaprogrammation) qui ne sont pas pratiques dans d'autres langues parce que la syntaxe fait obstacle.

Lectures supplémentaires
Battre les moyennes

Robert Harvey
la source
3
Le deuxième paragraphe n'a pas de sens: homoiconicité! = Syntaxe simple; une syntaxe simple facilite l'écriture d'un analyseur Lisp dans n'importe quelle langue (voir ceci ). Le 3ème paragraphe est vague, nécessite des exemples.
@MattFenwick c'est vrai que l'homoiconicité peut se faire avec une syntaxe complexe, mais ce serait extrêmement difficile. Il est juste de supposer que si vous avez affaire à une syntaxe homoiconique, elle sera simple, si ce n'est pour une autre raison que la cohérence exigée qui la rendra ineffablement plus facile à suivre qu'une syntaxe non homoiconique. Bien que votre deuxième point soit bon, LISP est facile à analyser car c'est une syntaxe simple, pas à cause de l'homoiconicité (même si l'homoiconicité est la cause de cette simplicité)
Jimmy Hoffa
1
Dans tous les cas, il y a peu de frais généraux pour prendre une valeur de données et l'interpréter comme un programme. C’est une bonne chose. La programmation par configuration est simple lorsque tout ce que vous avez à faire est d'écrire un interpréteur pour les données de configuration. Les transformations mathématiques avancées (qui sont difficiles à implémenter dans les langages avec état) sont souvent "réduites" à de simples transformations syntaxiques du pur fragment de Lisp.
nomen
1
@MattFenwick: J'ai supprimé le mot "homoiconicité" de ma réponse.
Robert Harvey
1
J'aimerais pouvoir donner plus d'un +1 pour The Nature of Lisp; Je n'ai jamais vu une si grande explication.
Doval
9

Pourquoi l'étude d'un interprète écrit dans la langue qu'il interprète est-elle si importante?

En général, étudier un interprète vous donne un aperçu de sa langue et de ses fonctionnalités. En général, étudier le code dans un langage de programmation, c'est comme pratiquer un langage parlé en écoutant et en lisant: il vous familiarise avec ce que ce langage peut faire, comment il est utilisé et les "idiomes" courants. Plus précisément, Lisp est un langage homoiconique, ce qui signifie que sa syntaxe pour les expressions est la même que sa syntaxe pour les données. L'écriture de code en Lisp ressemble terriblement à l'écriture d'une liste, et vice-versa. Ainsi, interpréter du code Lisp avec du code Lisp est aussi simple que de parcourir des listes avec caret cdr.

Comment dois-je capitaliser sur cet exercice pour en tirer le meilleur parti conceptuellement?

Réfléchissez à la façon dont l'interprète s'interpréterait - dans de nombreuses implémentations d' interprètes méta-circulaires (où un langage homoiconique s'interprète lui-même) peuvent simplement "passer" par la fonction. Par exemple, pour implémenter car, prenez simplement carl'argument. Cela met l'accent sur les mécanismes de stockage de données et se concentre sur la fonctionnalité.

Comment les interprètes lisp démontrent-ils de bons concepts d'architecture pour la future conception de logiciels?

Les interprètes peuvent être très compliqués, ce qui encourage une bonne architecture dans leur conception. Dans cet esprit, celui-ci dépend davantage de l'interprète individuel.

Que manquerais-je si je faisais cet exercice dans un langage différent comme C ++ ou Java?

Ces langages ne sont pas homoiconiques, ils ne bénéficient donc pas de la grâce et de la simplicité d'un interprète méta-circulaire Lisp. Cela rend l'exercice plus difficile et peut-être moins courant, mais je ne dirais pas que c'est vraiment moins bénéfique.

Quel est le plat à emporter ou "outil mental" le plus utilisé dans cet exercice?

Je ne suis pas sûr d'avoir une bonne réponse pour celui-ci; simplement qu'il aide à voir comment fonctionne l'interprète et, peut-être plus important encore, à le bricoler pour voir comment des modifications mineures de la langue peuvent être facilement mises en œuvre.

TheRubberDuck
la source
5

LISP est lui-même structuré d'une manière qui le rend extrêmement facile à analyser. Si vous essayez d'écrire un compilateur, vous remarquerez que c'est beaucoup plus facile si tout dans votre langue est une expression et a un faible niveau d'ambiguïté. LISP force les parenthèses partout pour éliminer l'ambiguïté et n'a pas de déclarations, seulement des expressions.

Le fait même que LISP soit très facile à analyser encourage les utilisateurs à analyser leur propre code source et à faire des tours de magie avec. La ligne entre les données et le code devient floue et vous pouvez facilement faire des choses qui nécessitent normalement un certain effort, comme la réflexion, la réécriture de code dynamique, les plugins et la sérialisation.

Voilà l'essentiel. L'exercice est probablement destiné à vous donner un aperçu de ce qui est possible lorsque le code est facilement analysable par lui-même.

Alexander Torstling
la source
Ce n'est pas Lisp qui est facile à analyser. Les expressions S sont faciles à analyser. En plus de cela, vous devez alors analyser Lisp.
Rainer Joswig
@Rainer: N'est-ce pas juste une piqûre? Dans mon monde, l'analyse signifie passer du texte à un AST, qui ne dit rien sur l'interprétation des commandes.
Alexander Torstling
En C ++, l'analyseur détectera une déclaration de fonction syntaxiquement incorrecte. En Lisp non. Le lecteur ne sait rien du langage de programmation Lisp. L'analyseur C ++ connaît la syntaxe C ++ complète. Le lecteur Lisp ne connaît que les expressions s.
Rainer Joswig
Ah, alors je comprends ce que tu veux dire. Certes, bien que je pense toujours qu'un simple évaluateur lisp serait plus simple à construire qu'un simple c ++. C'est ce qu'ils font dans le SICP, n'est-ce pas (ça fait longtemps que je ne l'ai pas lu)?
Alexander Torstling
le langage utilisé dans SICP est très simple, même pas complet. Un interprète pour un petit langage de type C devrait également être simple. C ++ est volumineux. Une partie de sa difficulté vient d'un nombre relativement élevé de syntaxe intégrée. Dans un système Lisp typique, une grande partie de la syntaxe est construite avec des macros - en dehors de l'interpréteur. Les macros implémentent la syntaxe et un mécanisme d'extension pour les transformations de source. Cela maintient le noyau plus petit. Mais les macros peuvent être massives. Par exemple, l'implémentation de la construction LOOP a plus de 2000 lignes de code macro complexe.
Rainer Joswig
4

Je ne suis pas sûr que ce soit vraiment important pour tout le monde. Vous pouvez être un développeur performant sans savoir comment fonctionne un interpréteur Lisp. Lorsque vous étudiez l'informatique, les idées de base de Lisp doivent cependant être apprises.

Les interprètes Lisp sont importants pour les programmeurs Lisp. Ils doivent comprendre comment fonctionne un interprète ([et un compilateur] 1 ), pour bien comprendre comment utiliser le langage.

Un interprète Lisp est souvent utilisé comme un outil en informatique pour enseigner aux étudiants quelques choses:

En tant que dispositif d'enseignement, un interprète Lisp est utile, car il peut être appris et compris en peu de temps. Étant donné que peu d'étudiants connaissent déjà Lisp, les étudiants sont sur un terrain de niveau lorsqu'il s'agit d'apprendre les concepts ci-dessus.

Rainer Joswig
la source