Warum ist es so wichtig, einen Lisp-Dolmetscher in Lisp zu lernen?

30

Ich habe viele CS-Lehrpläne und Lernvorschläge für neue Programmierer gesehen, die den angehenden Programmierer auffordern, einen Lisp-Interpreter zu studieren, der speziell in Lisp geschrieben ist. Alle diese Seiten sagen Dinge ähnlich wie „seine intellektuelle Offenbarung“, „es ist eine Erleuchtungserfahrung jeder ernsthafte Programmierer haben sollte“ oder „es zeigt Ihnen , Hardware / Software - Beziehungen“ und andere vage Aussagen, vor allem aus diesem Artikel entnommen aus dieses seriöse How-to .

Das allgemeine Gefühl meiner Frage ist, wie erreicht Lispel die oben genannten Ziele und warum Lispel? Warum nicht eine andere Sprache?

Ich frage dies, weil ich gerade mit dem Schreiben eines Schema-Interpreters im Schema fertig bin (entnommen aus SICP http://mitpress.mit.edu/sicp/ ) und jetzt schreibe ich einen Python-Interpreter im Schema und ich habe Mühe, diese legendäre Offenbarung zu haben das soll speziell von ersteren kommen. Ich suche nach bestimmten technischen Details zwischen den beiden Sprachen, die ich in ihren Schema-Interpreten verwenden kann, um zu verstehen, wie Programme funktionieren.

Genauer:

Warum wird das Studium eines Dolmetschers, der in der Sprache geschrieben ist, die er interpretiert, so betont? Ist es nur eine große mentale Übung, die Originalsprache und die gebaute Sprache gerade zu halten, oder gibt es spezifische Probleme, deren Lösungen nur in der Natur der Sprache zu finden sind? Ursprache?

Wie demonstrieren Lisp-Interpreten gute Architekturkonzepte für das zukünftige Softwaredesign?

Was würde ich vermissen, wenn ich diese Übung in einer anderen Sprache wie C ++ oder Java machen würde?

Was ist das am häufigsten verwendete Mitnehmer- oder "mentale Werkzeug" aus dieser Übung? **

** Wie wähle ich die Antwort , die ich tat , weil ich habe bemerkt , dass ich von dieser Übung mehr Geschick bei der Gestaltung Parsen Werkzeugen in meinem Kopf als jedes andere Werkzeug gewonnen haben , und ich möchte verschiedene Methoden finden , dass der Parsen besser für die Regelung kann arbeiten Interpreter als der Python-Interpreter.

Ma-at
quelle
4
@gnat Nicht gerade ein Karrieretipp, eher eine "Was ist so toll an Lisp" -Frage.
Robert Harvey
1
@RobertHarvey Dieser Link ist nicht nur für die Karriere, sondern auch für die Bildungsberatung gedacht, das meine ich. Aber gut, Lisp-is-so-great ist wahrscheinlich auch eine gute Passform
Mücke
1
Sie scheinen zu fragen, was Sie aus einer bestimmten Übung lernen werden. Ihre Zurückhaltung ist ein Zeichen der Faulheit, der Schlüssel zu jedem guten Programmierer. Um jedoch herauszufinden, was Sie aus einer Übung lernen, müssen Sie sie tun und sehen. Niemand kann Ihnen sagen, was Sie daraus lernen, Sie müssen es nur tun.
Jimmy Hoffa
2
Obwohl sich diese Frage auf die gesamte Bildung bezieht, würde ich sie nicht als "Bildungsberatung" in der Art "Welche Sprache soll ich lernen?" Einstufen. ist. Das heißt, es ist nicht spezifisch für eine bestimmte Art von Kurs oder Job. Wenn Sie einige der Modewörter aus dem Bildungsbereich weglassen, handelt es sich um eine Frage zu den Programmiersprachen insgesamt, in deren Antworten die Sprachfunktionen erörtert werden. Es ist auch nicht spezifisch für Lisp, kann aber auf andere homoikonische Sprachen wie xslt angewendet werden. Ich werde also nicht sagen, dass dies eine perfekte Frage ist, nur dass es nicht einfach "Karriereberatung" ist.
TheRubberDuck

Antworten:

17

Auf die Gefahr einer "Ich auch" Antwort, wenn Sie es versuchen, werden Sie sehen ...

Wenn Sie Computersprachen lernen, haben Sie wahrscheinlich den Eindruck, dass es mindestens zur Hälfte um das Parsen geht. Wenn Sie Lisp lernen, werden Sie feststellen, dass das Parsen der Oberflächensyntax nichts anderes ist als eine Annehmlichkeit für Leute (wie die meisten von uns), die viele irritierende einzelne Klammern nicht mögen.

Dann konnte man feststellen, dass für diese Bequemlichkeit ein hoher Preis gezahlt wurde. In Lisp ist es für ein Programm trivial, ein anderes Programm zu erstellen und auszuführen. In anderen Sprachen ist es eine fortgeschrittene Technik, wie die Multiplikation mit römischen Ziffern.

Natürlich würde fast jeder fragen: "Wer muss das tun?" Nun, Sie konnten sehr gut sehen, dass es eine ganze Reihe von Dingen eröffnet, von denen Sie noch nie bemerkt haben, dass Sie es vorher nicht konnten. Sie können es in anderen Sprachen tun, aber bei weitem nicht so einfach.

EINGEFÜGT, um Izkata Kommentar zu beantworten:

  • Das SHRDLU-Programm zum Verstehen der natürlichen Sprache übersetzte eine englische Aussage oder Frage in ein Programm in einem Lisp-Dialekt namens MICRO-PLANNER und führte es aus.
  • Programme, die Programme manipulieren, um sie beispielsweise zu vereinfachen oder als richtig zu erweisen, sind natürlich in Lisp geschrieben.
  • Ich habe die Programmerstellung in einem Programm verwendet, um visuelle Szenen zu erfassen, in denen es um alle Symmetrien ging, die in dreidimensionalen Objekten möglich sind, ohne den Code zu multiplizieren.
  • Alles, was mit Logik und Theorem zu tun hat, befasst sich mit der Manipulation logischer Ausdrücke, die eine Form von Programm sind.
  • Symbolische Mathematik wie die symbolische Integral- oder Differentialrechnung umfasst die Bearbeitung mathematischer Ausdrücke, die wie Miniaturprogramme aussehen.
  • Jedes Problem, das mit der Codegenerierung oder dem höherwertigen Begriff "partielle Evaluierung" zusammenhängt, ist in Lisp selbstverständlich. Ich habe dies vor langer Zeit für ein Datenbank-Bridge-Programm getan. Ich habe es in C gemacht, was nicht so einfach war wie Lisp, aber ich habe die Idee von Lisp bekommen. Dies wurde als eine Technik angesehen, die zu dieser Zeit fast niemand ausführen konnte (insbesondere die COBOL-Köpfe). Vielleicht jetzt mehr, hoffe ich.

... das sind nur ein paar ...

Dann merkt man, dass einige Dinge, die heute als "modern" gelten, in Lisp seit 40 Jahren ein alter Hingucker sind. Wie funktionale Programmierung. Wie Müllabfuhr. Wie Verschlüsse.

Das heißt nicht, dass moderne Sprachen keine neuen guten Ideen wie OOP usw. haben. Wenn Sie jedoch Lisp lernen, wird dies Ihre Perspektive erweitern.

Mike Dunlavey
quelle
You can do it in other languages, but not nearly so easily.- Mögen? (Die Frage für mich scheint zu sein, weil Aussagen wie diese oft gemacht werden, aber fast nie spezifischer werden)
Izkata
Ich dachte zuerst, die Welt sei revolutioniert, als mir klar wurde, dass Javascript seinen eigenen Quellcode drucken und Objekte durchlaufen werden können, um ein String-Literal zu erhalten, das sich in das Objekt-Literal verwandeln lässt. Dann wurde mir klar, dass Perl dies alles zusammen mit $ Data :: Dumper :: Deparse hatte, und dann wurde mir klar, dass Lisp dies für immer hatte. Durch das Verstehen von Interpreten wird diese Kraft freigesetzt, die es immer gibt, lebende Module zu bauen, und in Lisp ist dies zugänglicher als jede andere Sprache.
Dmitry
lustig ist, dass ein Lisp-Programmierer weiß, dass Lisps-Interna immer ein eigenes Lisp-Frontend für jede dynamische Sprache erstellen können, von Javascript über Bash oder Perl bis hin zu Python. lispel schön Bootstraps aus der verfügbaren Umgebung.
Dmitry
19

Die einfache Antwort auf Ihre Frage ist, Lisp zu probieren, vorzugsweise in Verbindung mit SICP . Dann wirst du erleuchtet.

Das gesagt...

Code ist Daten
Die meisten Sprachen unterscheiden zwischen Code und Daten. Lisp tut es nicht. Dies ermöglicht es beispielsweise, einen Lisp-Parser trivial in Lisp zu schreiben und den Lisp-Code innerhalb von Lisp zu manipulieren. Die beste Beschreibung dieser Erleuchtung, die ich gefunden habe, ist Die Natur von Lisp .

Dies gilt zum Teil, weil die Syntax für die Sprache so einfach ist. Es ermöglicht Dinge in Lisp (wie Metaprogrammierung), die in anderen Sprachen unpraktisch sind, weil die Syntax im Weg steht.

Lesen Sie weiter und
übertreffen Sie die Durchschnittswerte

Robert Harvey
quelle
3
2. Absatz macht keinen Sinn: Homoikonizität! = Einfache Syntax; Eine einfache Syntax macht es einfach, einen Lisp-Parser in einer beliebigen Sprache zu schreiben (siehe dies ). 3. Absatz ist vage, braucht Beispiel (e).
@MattFenwick Es ist wahr, dass Homoikonizität mit komplexer Syntax durchgeführt werden kann, aber das wäre außerordentlich schwierig. Es ist fair anzunehmen, dass es einfach sein wird, wenn Sie es mit einer homoikonischen Syntax zu tun haben, und dies aus keinem anderen Grund als der von ihr verlangten Konsistenz, die es ineffektiv einfacher macht, als einer nicht homoikonischen Syntax zu folgen. Obwohl Ihr zweiter Punkt gut ist, lässt sich LISP leicht analysieren, da es sich um eine einfache Syntax handelt, nicht um Homoikonizität (auch wenn die Homoikonizität die Ursache für diese Einfachheit ist)
Jimmy Hoffa
1
In jedem Fall ist der Aufwand gering, einen Datenwert als Programm zu interpretieren. Das ist eine schöne Sache. Die Programmierung per Konfiguration ist unkompliziert, wenn Sie lediglich einen Interpreter für die Konfigurationsdaten schreiben müssen. Fortgeschrittene mathematische Transformationen (die schwierig in zustandsbehafteten Sprachen zu implementieren sind) werden häufig auf bloße syntaktische Transformationen des reinen Fragmentes von Lisp "reduziert".
Nomen
1
@MattFenwick: Ich habe das Wort "Homoiconicity" aus meiner Antwort entfernt.
Robert Harvey
1
Ich wünschte, ich könnte mehr als +1 für The Nature of Lisp geben. Ich habe noch nie eine so gute Erklärung gesehen.
Doval
9

Warum wird das Studium eines Dolmetschers, der in der von ihm gedolmetschten Sprache geschrieben ist, so betont?

Wenn Sie einen Dolmetscher studieren, erhalten Sie im Allgemeinen einen Einblick in dessen Sprache und Funktionen. Im Allgemeinen ist das Lernen von Code in einer Programmiersprache wie das Üben einer gesprochenen Sprache durch Zuhören und Lesen: Es macht Sie mit der Funktionsweise dieser Sprache, ihrer Verwendung und den gebräuchlichen "Redewendungen" vertraut. Insbesondere ist Lisp eine homoikonische Sprache, was bedeutet, dass die Syntax für Ausdrücke mit der Syntax für Daten identisch ist. Das Schreiben von Code in Lisp sieht furchtbar aus, als würden Sie eine Liste schreiben und umgekehrt. Das Interpretieren von Lisp-Code mit Lisp-Code ist daher so einfach wie das Durchlaufen von Listen mit carund cdr.

Wie kann ich diese Übung nutzen, um sie konzeptionell optimal zu nutzen?

Überlegen Sie, wie der Interpreter sich selbst interpretieren würde - in vielen Implementierungen von Meta-Circular-Interpretern (bei denen sich eine homoikonische Sprache selbst interpretiert) kann er die Funktion nur "durchlaufen". carNehmen Sie zum Implementieren beispielsweise einfach cardas Argument of. Dies nimmt den Schwerpunkt von Datenspeichermechanismen und konzentriert sich auf Funktionalität.

Wie demonstrieren Lisp-Interpreten gute Architekturkonzepte für das zukünftige Softwaredesign?

Dolmetscher können sehr kompliziert sein, was eine gute Architektur bei ihrer Gestaltung fördert. In diesem Sinne ist dieser stärker vom jeweiligen Dolmetscher abhängig.

Was würde ich vermissen, wenn ich diese Übung in einer anderen Sprache wie C ++ oder Java machen würde?

Diese Sprachen sind nicht homoikonisch, daher profitieren sie nicht von der Anmut und Einfachheit eines Meta-Circular-Lisp-Interpreters. Das macht die Übung schwieriger und vielleicht auch seltener, aber ich würde nicht sagen, dass es weniger nützlich ist.

Was ist das am häufigsten verwendete Mitnehmer- oder "mentale Werkzeug" aus dieser Übung?

Ich bin mir nicht sicher, ob ich eine gute Antwort auf diese Frage habe. einfach, dass es hilft zu sehen, wie der Dolmetscher funktioniert und, was vielleicht noch wichtiger ist, daran herumzubasteln, um zu sehen, wie geringfügige Änderungen an der Sprache einfach implementiert werden können.

TheRubberDuck
quelle
5

LISP selbst ist so strukturiert, dass das Parsen extrem einfach ist. Wenn Sie versuchen, einen Compiler zu schreiben, werden Sie feststellen, dass es viel einfacher ist, wenn alles in Ihrer Sprache ein Ausdruck ist und eine geringe Mehrdeutigkeit aufweist. LISP zwingt Klammern überall, um Mehrdeutigkeiten zu beseitigen, und enthält keine Aussagen, nur Ausdrücke.

Die Tatsache, dass LISP sehr einfach zu analysieren ist, ermutigt Benutzer, ihren eigenen Quellcode zu analysieren und Zaubertricks damit zu machen. Die Grenze zwischen Daten und Code verwischt sich und Sie können auf einfache Weise Dinge tun, die normalerweise viel Aufwand erfordern, z. B. Reflektion, dynamisches Umschreiben von Code, Plugins und Serialisierung.

Das ist der Kern davon. Die Übung soll Ihnen wahrscheinlich einen Einblick geben, was möglich ist, wenn der Code leicht von sich aus analysiert werden kann.

Alexander Torstling
quelle
Es ist nicht Lisp, der leicht zu analysieren ist. S-Ausdrücke sind einfach zu analysieren. Darüber hinaus müssen Sie dann Lisp analysieren.
Rainer Joswig
@Rainer: Ist das nicht nur ein Trottel? In meiner Welt bedeutet Parsen, von einem Text zu einem AST zu wechseln, der nichts über die Interpretation der Befehle aussagt.
Alexander Torstling
In C ++ erkennt der Parser eine syntaktisch falsche Funktionsdeklaration. In Lisp nicht. Der Leser weiß nichts über die Programmiersprache Lisp. Der C ++ - Parser kennt die vollständige C ++ - Syntax. Der Lisp-Leser kennt nur s-Ausdrücke.
Rainer Joswig
Ah, dann verstehe ich was du meinst. Stimmt, obwohl ich immer noch denke, dass ein einfacher Lisp-Evaluator einfacher zu konstruieren wäre als ein einfacher C ++ - Evaluator. Das ist es, was sie in SICP machen, nicht wahr?
Alexander Torstling
Die in SICP verwendete Sprache ist sehr einfach, nicht einmal das vollständige Schema. Ein Dolmetscher für eine winzige C-ähnliche Sprache sollte ebenfalls einfach sein. C ++ ist groß. Einige seiner Schwierigkeiten rühren von einer relativ hohen Anzahl eingebauter Syntax her. In einem typischen Lisp-System wird ein Großteil der Syntax mit Makros erstellt - außerhalb des Interpreters. Makros implementieren Syntax und einen Erweiterungsmechanismus für Quelltransformationen. Dies hält den Kern kleiner. Aber die Makros können sehr umfangreich sein. Die Implementierung für das LOOP-Konstrukt enthält beispielsweise mehr als 2000 Zeilen komplexen Makrocodes.
Rainer Joswig
4

Ich bin mir nicht sicher, ob es wirklich wichtig für alle ist. Sie können ein erfolgreicher Entwickler sein, ohne zu wissen, wie ein Lisp-Interpreter funktioniert. Während des Studiums der Informatik sollten jedoch die Grundgedanken von Lisp erlernt werden.

Lisp-Interpreten sind für Lisp-Programmierer wichtig. Sie müssen verstehen, wie ein Interpreter ([und Compiler] 1 ) funktioniert, um vollständig zu verstehen, wie die Sprache verwendet wird.

Ein Lisp-Interpreter wird in der Informatik häufig als Werkzeug verwendet, um den Schülern einige Dinge beizubringen:

Als Lehrmittel ist ein Lisp-Dolmetscher hilfreich, weil er in kurzer Zeit erlernt und verstanden werden kann. Da nur wenige Schüler Lisp bereits kennen, sind die Schüler auf einem Niveau, wenn es darum geht, über Konzepte zu lernen.

Rainer Joswig
quelle