This question comes purely from "mental masterbation" and probably has no practical value.
If I define a value in Clojure using def
, can the compiler be induced to evaluate it at compile time, and not wait until run-time?
(def the-answer 42)
(+ the-answer 1)
I guess I could define a macro, but the calling syntax becomes sort of awkward:
(defmacro the-answer [] 42)
(+ (the-answer) 1)
This also works, but is still ugly:
(+ `~the-answer 1)
I also understand (or believe) that Clojure evaluates constant expressions at compile time:
(def milliseconds-per-day (* 24 60 60 1000))
I am just learning Common Lisp, but my understanding is that Common Lisp supports user-defined reader macros, so you could define a reader macro (something like #$
) that evaluates the following symbol at compile-time:
(+ #$the-answer 1)
By the way, that syntax is no "prettier" than the macro call.
How do I make Clojure evaluate the constant vars at compile time and replace the reference with the actual value? Does it already do so?
Before anyone starts quoting Knuth's Law ("premature optimization is the root of all evil"), I ask this question to better understand the internals of Clojure compilation.
From the Clojure 1.3 docs
== 2.14 ^:const defs ==
^:const lets you name primitive values with speedier reference.
(def constants {:pi 3.14 :e 2.71})
(def ^:const pi (:pi constants)) (def ^:const e (:e constants))
The overhead of looking up :e and :pi in the map happens at compile time, as (:pi constants) and (:e constants) are evaluated when their parent def forms are evaluated.
One of the main uses of macroes is moving computation to compile time so it is only done once. With this in mind, my opinion is that macros are the correct tool for this and the extra set of ( )
looks to me like it actually helps make the special parts look special.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With