Was sind die typischen Anwendungen von Lisp-Makros?

19

Ich versuche, etwas über LISP zu lernen, und ich habe viel über die Bedeutung von LISP-Makros gelesen, daher möchte ich gerne Erfahrungen mit ihnen sammeln.

Können Sie einen praktischen Anwendungsbereich vorschlagen, in dem ich mithilfe von Makros ein reales Problem lösen und die Nützlichkeit dieses Programmierkonstrukts verstehen kann?

HINWEIS

Dies ist kein generisches Projekt, das ich als nächstes beantworten soll. Ich bin daran interessiert zu verstehen, welche Arten von Problemen typischerweise mit Hilfe von LISP-Makros gelöst werden. Sind sie beispielsweise für die Implementierung abstrakter Datentypen geeignet? Warum wurde dieses Konstrukt der Sprache hinzugefügt? Welche Probleme löst es, die mit einfachen Funktionen nicht gelöst werden können?

Giorgio
quelle

Antworten:

9

Lisp-Makros kombinieren einige unterschiedliche Eigenschaften:

  1. Makros definieren neue Syntax ↔ sie verwenden Quellcode als Eingabe
  2. Makros werden normalerweise zur Kompilierungszeit ausgeführt
  3. Makros erzeugen Quellcode

Die besten Anwendungen machen sich all diese Aspekte zunutze. Das wohl bekannteste Beispiel ist die (loop…) in Common Lisp. Ohne eine dieser Funktionen wäre sie nicht annähernd brauchbar. Ohne die Quelle als Eingabe wäre es umständlich, die Aktionen innerhalb der Schleife zu definieren. Ohne die Erweiterung zur Kompilierungszeit wäre es viel zu langsam. und ohne Code-Generierung wäre es nicht ausführbar.

Ein weiteres gutes Beispiel ist das Kapitel zur binären Serialisierung in Practical Common Lisp , Practical: Parsing Binary Files .

Ein Abfrage-Makro, das etwas Ähnliches wie LINQ implementiert, ist möglicherweise eine weitere gute Anwendung. Es würde jedoch die automatische Vervollständigung fehlen, die LINQ so schön macht, wie es ist. Fast alles, was heutzutage von speziellen Codegeneratoren mit XML-Eingaben (z. B. XAML) gelöst wird, könnte auch mit Lisp-Makros implementiert werden.

Patrick
quelle
Ich habe gerade das Buch "Practical Common Lisp" gekauft und werde mir das von Ihnen vorgeschlagene Beispiel ansehen.
Giorgio
2

Die Art und Weise, wie ich Makros in Common Lisp betrachte, ist, dass sie Funktionen sind, die zu bewertenden Code zurückgeben, aber ihre Argumente nicht 'auswerten', bevor sie diesen Code zurückgeben. Auch Funktionen geben etwas zurück, aber sie werten jedes Argument aus, bevor ihr Körper ausgewertet wird. Makros nicht.

Paul Graham in "On Lisp" liefert (IMHO) eine der besten Beschreibungen der Unterschiede zwischen Makros und Funktionen und erörtert deren Überlappung und Einzigartigkeit. Viele Codebits können entweder als Funktion oder als Makro geschrieben werden, aber es gibt Fälle, in denen nur ein Makro funktioniert. Sobald Sie Ihren Kopf darum gewickelt haben, haben Sie das Wesentliche an Makros in Lisp.

Ein Beispiel für ein Makro, bei dem eine Funktion nicht funktioniert, ist 'aif' (anaphorisches If). Es sind nur ein paar Zeilen Code und meine Empfehlung, wo ich anfangen soll.

Und verweisen Sie auf Common Lisps Version von anaphoric if, die sich die absichtliche Erfassung von Variablen zunutze macht. Die automatisch-hygienische Version von Scheme ist IMO nicht das "echte Geschäft". Die variable Erfassung ist ein wichtiger Bestandteil der Lisp-Makrologie, und einige der leistungsstärkeren und nützlicheren Makros machen sich dies zweifellos zunutze.

Clayton Stanley
quelle