简体   繁体   中英

How does clojure evaluate code at compile time?

Here are two macros I had written

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

&

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

On macroexpanding the first one, I get (+ 1 2) , and while macroexpanding the second, I get the value 3. Does this mean the addition happened at compile time? How is that even possible? What if instead of '(+ 1 2) I had written a function that queries a db. Would it query the db at compile time?

A macro injects arbitrary code into the compiler. Usually, the purpose is to "pre-process" custom code like (1 + 2) into something Clojure understands like (+ 1 2) . However, you could include anything (including DB access) into the compilation phase if you really want to. After all the compiler is just a piece of software running on a general-purpose computer. Since it is open-source, you could modify the compiler code directly to do anything.

Using a macro is just a more convenient way of modifying/extending the base compiler code, that is optimized for extending the core Clojure language. However, macros are not limited to that use-case (if you really want to get crazy).


There is a similar ability using the C++ expression template mechanism, which is a Turing Complete compiler pre-processor. A famous example was to use the compiler to compute the first several prime numbers as "error" messages. See http://aszt.inf.elte.hu/~gsd/halado_cpp/ch06s04.html#Static-metaprogramming

Macro body is executed during compile time and its return value is used to replace its usage in the code and this new code will be compiled.

Thus your macro code:

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

will actually execute eval with the form '(+ 1 2) during compilation and the result value of that expression ( 3 ) will be returned as the result of the macro replacing its usage (eg (hello 0) ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM