2014-06-18 13 views
12

Jeder Common Lisp-Programmierer weiß, dass Makros ein mächtiges Werkzeug sind. Gemeinsame Lisp-Makros wurden unter anderem verwendet, um Objektorientierung oberhalb von Lisp ohne hinzuzufügen, um die Sprachspezifikation zu ändern. Read-Macros sind ein weiteres Konstrukt mit Mind-Bending-Fähigkeiten.Vergleich von Common-Lisp-Makros und Forth-Metaprogrammierungsfunktionen

Ein weiteres Programm, das Meta-Programmierung ermöglicht, ist Forth. Forth macht es auf eine etwas andere Art und Weise, indem er Wörter verwendet und Wörter generiert.

Ich würde gerne wissen, von jemandem, der in beiden Sprachen versuchte, wenn gemeinsame Lisp Makros und vierte Konstrukte in Breite/Macht vergleichbar sind: Gibt es etwas, was Sie tun können mit dem ersten, die Sie nicht mit letzterem tun können ? Oder umgekehrt?

Natürlich spreche ich nicht über Turing-Vollständigkeit der beiden Sprachen: Ich spreche über metaprogramming Fähigkeiten. C ist Turing-vollständig, aber nur ein Idiot würde behaupten, dass C-Makros vergleichbar mit Common-Lisp-Makros sind.

+2

Dies ist viel spezifischer als die vorherige Version, [Lisp und Forth Makros \ [in der Warteschleife]] (http://stackoverflow.com/q/24272856/1281433), was gut ist.Natürlich, jetzt hat diese Frage erneut Stimmen, und das hat eine enge Abstimmung, also gibt es einige Verwirrung darüber, welche davon eigentlich offen bleiben sollte. Es ist viel klarer, was Sie in dieser Frage suchen, aber es ist immer noch off-Thema, weil ["Vergleichs-Frage sind eine schlechte Passform für \ [Stack Overflow \], da es keine Grenzen zu den Antworten gibt, die gebucht werden können sie. "] (http://meta.stackoverflow.com/q/251328/1281433). –

+3

Der enge Grund ** zu breit ** gilt hier: "Es gibt entweder * zu viele mögliche Antworten * oder gute Antworten wären für dieses Format zu lang." Das ist überhaupt keine schlechte Frage. es ist einfach nicht besonders gut für Stack Overflow geeignet. Diese Frage könnte zum Beispiel in comp.lang.lisp groß sein. –

+1

Die besondere Teilfrage, "gibt es etwas, was man mit dem ersteren machen kann, was man mit letzterem nicht machen kann? Oder umgekehrt?" ist wahrscheinlich das spezifischste hier. Es könnte immer noch zu viele Antworten geben, aber wenn es etwas gibt, was man tun kann, was das andere nicht kann, ist es wahrscheinlich möglich, eine relativ kanonische Antwort zu geben. –

Antwort

7

Meiner Ansicht nach ähneln Common Lisp Makros Forth unmittelbare Wörter. (Eigentlich sind sie am ähnlichsten Lisp Leser Makros.)

  • Sie sind beide Verfahrens Makros, das heißt volle Leistung der Sprache nutzen können.

  • Beide haben Zugriff auf den Quellcode-Eingang.

  • Sie beide können alles ausdrücken, das in der Sprache ausdrückbar ist. (ZB eine objektorientierte Erweiterung in Lisp, oder basische Steuerfluß Konstrukten in Forth.)

Der Hauptunterschied vielleicht wäre, dass Forth „Makro“ eingegeben werden Zeichenkette, während Lisp von Makros auf einem betreiben Baum analysieren.

+3

Lisp-Makros funktionieren auf S-Ausdrücke, von denen ich anschaue, dass sie wie Nicht-Lisper-Strukturen, aber trotzdem aussehen könnten. Ich erwähne diesen Unterschied, weil in fast jedem Lisp-Dialekt die Lesephase vor der Kompilierungsphase steht und Lispers daher beim Schreiben von Makros Code _als_ Daten sieht. Yay Homoiconicity! (Du weißt das alles ganz genau, denn [common-lisp] ist ein Top-Tag für dich, aber ich glaube, dass andere Leser hier auch den Unterschied verstehen sollten.) –

2

Es tut uns leid, wenn die Diskussion unten etwas vage erscheint, aber es gibt zu viel zu sagen.

Ich habe nur theoretische Kenntnisse von Lisp, nicht Hands on.

Auf der anderen Seite könnte Forth eine vollständige Metaprogrammierung innerhalb der Sprache haben (aber normale Forth hat nicht). Metaprogrammierung ist jedoch möglich und möglich, aber ohne kohärente Syntax. Ich denke, das gleiche passiert in Lisp.

Ich habe eine sehr saubere Lösung mit dieser Möglichkeit in einem kleinen Paradigma von Forth wie Sprache implementiert. Um Metaprogrammierung zu haben, sollten wir in der Lage sein, auf das zu verweisen, was wir schreiben. Also, wenn wir ein Programm schreiben, ausgeführt werden immediatelly wie:

bread eat 

wir sollten mit der Absicht, auf den gleichen Satz zu der Lage sein, zu beziehen, anstatt sie auszuführen, es zu halten für den späteren Gebrauch auf. Das könnte getan werden, indem z.B.

{ bread eat } 

oben Die Phrase als Folge haben könnte, das erstellte Objekt auf dem Stapel zu lassen. Aber da wir ein neues Wort als { und } erstellt haben, haben wir auch das Recht darauf zu verweisen.

So konnten wir verweisen mögen:

{ bread 

Wie könnten wir auf das verweisen? Eine vorläufige Syntax lautet: {{ { bread }}.

Wenn wir den Namen XXX zum vorherigen Ausdruck geben könnten wir den anfänglichen Satz als schreiben:

XXX eat } 

und die Phrase oben sollte korrekt auf dem Stapel zu verlassen arbeitet die

{ bread eat } 

Wie Ich weiß nicht, ob das, was ich sage, genau das ist, wonach du suchst, es genügt zu sagen, dass durch die obige Argumentation und ihre Implementierung in Forth jedes Wort eine Ausführungsebene erhält und definiert, welches Niveau die Metaprogrammierung des Wortes ist.

Offensichtlich haben wir die erste Unendlichkeitsstufe und jede nachfolgende Ebene. Daher basieren die Ausführungsebenen auf der mathematischen Unendlichkeit.

Ich habe das oben in einer Art von Forth implementiert und auf der ersten Ebene (unter unendlich) funktioniert alles reibungslos.

{ bread eat } { tomatos eat } x 3 = if 

in: So zum Beispiel in der Lage eine Uhr die Syntax ändern

{ bread eat | tomatos eat } x 3 = if 

Das wird durch die Definition | als } { als Gebrüll getan:

{{ } { }} "|" define 

oder wenn Sie mögen es besser als:

2{ } { 2} "|" define 

Die obige Methode nimmt innerhalb der Sprache mit einer korrekten Syntax die Metasprache und macht sie zur Sprache.

So haben meiner Meinung nach beide Lisp und Forth die Möglichkeit der Metaprogrammierung, aber beide fehlt diese Möglichkeit als integrierender Teil der Sprache.

Ich habe mehr Details dazu auf napl.wikispaces.com.

+1

Ich habe nur theoretisches Wissen über Lisp, nicht hands on. ... Ich denke, das gleiche passiert in Lisp. –

5

Ich bin ein Forth-Implementor und habe breite Erfahrung in Forth, ein halbes Dutzend Implementierungen, ein paar hundert projecteuler Probleme. Ich machte auch eine kleine objektorientierte Erweiterung (klein, d. H. Etwa ein Dutzend Zeilen). Meine Erfahrung in LISP ist viel mehr auf der Kurs-Ebene, aber ich denke, es ist fair zu sagen, dass die Meta-Programmierung Einrichtungen von LISP systematischer und in der Praxis leistungsfähiger sind.

Es ist relativ einfach, Abstraktionen über Abstraktionen in LISP zu erstellen. Wenn ich in Forth eine Matrix auf einem linearen Raum definiere, der durch Objekte mit nicht-trivialen Definitionen definiert ist, wechsle ich zu Python.

Der Grund ist auch offensichtlich, zumindest für mich. Die Schöpfer von LISP sind Mathematiker, während Chuck Moore das ultimative Beispiel eines praktischen Programmierers ist, der seine Zeit niemals mit einem theoretischen Problem verschwendet.