Emacs Lisp-Definitionssyntax
Frage
Gibt es Analogien zu Scheme? define-syntax
in ELisp?In define-syntax
Ich kann einige Schlüsselwörter angeben und in elisp defmacro
Scheint, ich kann es nicht.BEARBEITEN:Offenbar verstehe ich Sie entweder nicht gut oder meine Frage ist nicht klar.Im Schema ist es möglich, Makros mit reservierten Wörtern wie zu definieren
(Schleife
for
Ain
einige-Liste(Schleife
while
…
In Emacs Lisp habe ich keine Möglichkeit gefunden, solchen Zucker einzuführen.Ich kann höchstens ein Makro erstellen, das so heißen muss
(Schleife für eine Liste (do-viel…)
Lesbarkeit ist wichtig
Lösung
Sowohl Scheme als auch Elisp verfügen über Makrosysteme.Die „Schlüsselwörter“ define-syntax
Und defmacro
beide führen einen Namen für ein benutzerdefiniertes Makro ein.
Zu diesem Zeitpunkt wird beispielsweise ein Makro, foo, im tatsächlichen Code verwendet (foo 1 bar)
Der Makro-Expander muss bestimmen, wie das gegebene Formular umgeschrieben werden soll. (foo 1 bar)
, in eine einfachere Form, die keine Benutzermakros enthält.Der Makro-Expander ruft die Funktion auf, die zum Zeitpunkt des Makros definiert war foo
wurde definiert.D.h.Es ruft die von Ihnen angegebene Funktion auf define-syntax
oder defmacro
mit einer Darstellung der Form, (foo 1 bar)
.Die Darstellung kann als „Syntaxobjekte“ oder als einfache Liste erfolgen (dies ist je nach Makrosystem unterschiedlich).
Dies ist meine Sicht auf die Ähnlichkeiten zwischen define-syntax
Und defmacro
.
Die Makrosysteme von R5RS Scheme und Elisp sind jedoch unterschiedlich.
Der mit verknüpfte Makro-Expander foo
kann im R5RS-Schema mit Hilfe von spezifiziert werden syntax-rules
.Dadurch können Sie den Mustervergleich verwenden, um die Umschreiberegeln festzulegen (intern wird das Formular „Syntaxregeln“ als Funktion ausgewertet).Weitere Unterschiede:Der Makroerweiterungsalgorithmus hilft Ihnen im R5RS-Schema dabei, versehentlich Namen einzuführen, die mit Namen aus anderen Teilen Ihres Programms kollidieren (z. B. aus einer Bibliothek, die Sie nicht selbst geschrieben haben).In der Vergangenheit ist dieses Problem aufgrund der Art und Weise, wie Namespaces in Lisps funktioniert, kein großer Deal in Lisp, aber es ist möglich, Fehler zu machen.
In der Vergangenheit verwendeten Scheme und Elisp beide denselben Makroerweiterungsalgorithmus, doch dann begann Schemers, mit anderen Algorithmen zu experimentieren.Das „Syntax-Regel“-System wurde in R5RS eingeführt, aber die Entwicklung hörte hier nicht auf.Heutzutage verfügen alle modernen Scheme-Implementierungen über (Varianten) des „Syntax-Case“-Systems.
Einige Implementierungen haben daran gearbeitet, dass dieser Erweiterungsalgorithmus mit Modulen funktioniert (Racket, R6RS-Implementierungen und andere).
Kurz gesagt, wenn Sie über Scheme-Makrosysteme lesen, achten Sie darauf, genau zu prüfen, um welche Variante es sich handelt.Wenn Sie über Einschränkungen lesen, haben Sie höchstwahrscheinlich einen Text zum (inzwischen ziemlich alten) syntax-rules
System.