2017-11-02 2 views
0

Hier sind zwei Makros IWie evaluiert clojure den Code zum Zeitpunkt der Kompilierung?

(defmacro hello [x] '(+ 1 2))

&

(defmacro hello [x] (eval '(+ 1 2)))

Auf macroexpanding die erste geschrieben hatte, bekomme ich (+ 1 2), und während die zweite macroexpanding, erhalte ich den Wert 3. Bedeutet dies, dass der Zusatz zur Kompilierzeit passiert ist? Wie ist das überhaupt möglich? Was passiert, wenn ich anstelle von '(+ 1 2) eine Funktion geschrieben habe, die eine db abfragt. Würde es die Datenbank zur Kompilierungszeit abfragen?

Antwort

7

Ein Makro injiziert beliebigen Code in den Compiler. Normalerweise besteht der Zweck darin, benutzerdefinierten Code wie (1 + 2) in etwas vorzuverarbeiten, das Clojure als (+ 1 2) versteht. Sie könnten jedoch alles (einschließlich DB-Zugriff) in die Kompilierungsphase einschließen, wenn Sie wirklich wollen. Nach all dem Compiler ist nur ein Stück Software auf einem Allzweck-Computer ausgeführt. Da es Open-Source ist, können Sie den Compiler-Code direkt ändern, um etwas zu tun.

Die Verwendung eines Makros ist nur eine bequemere Möglichkeit zum Ändern/Erweitern des Basis-Compiler-Codes, der für die Erweiterung der Clojure-Kernsprache optimiert ist. Allerdings sind Makros nicht auf diesen Anwendungsfall beschränkt (wenn Sie wirklich verrückt werden wollen).


Es gibt eine ähnliche Fähigkeit, die Expression Template-Mechanismus C++ verwendet wird, die eine komplette Turing Compiler-Vorprozessor ist. Ein berühmtes Beispiel war die Verwendung des Compilers, um die ersten paar Primzahlen als "Fehler" -Meldungen zu berechnen. Siehe http://aszt.inf.elte.hu/~gsd/halado_cpp/ch06s04.html#Static-metaprogramming

2

Macro Körper wird während der Kompilierzeit ausgeführt und der Rückgabewert wird verwendet, um seine Verwendung im Code zu ersetzen, und dieser neue Code wird kompiliert.

So kann Ihr Makrocode:

(defmacro hello [x] (eval '(+ 1 2)))

tatsächlich eval mit dem Formular '(+ 1 2) während der Kompilierung und der Ergebniswert dieses Ausdrucks ausführen (3) wird als Ergebnis des Makros ersetzt seine Verwendung zurückgegeben werden (zB (hello 0)).

+0

jetzt sehe ich die Macht: D –

Verwandte Themen