Clojure compile time constants

This question is based solely on "mental skill" and probably has no practical value.

If I define a value in Clojure using def , can I get the compiler to evaluate it at compile time and not wait for runtime?

 (def the-answer 42) (+ the-answer 1) 

I suppose I can define a macro, but the call syntax is getting 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 I understand that Common Lisp supports custom reader macros, so you can define a reader macro (something like #$ ) that evaluates the following character at compile time:

 (+ #$the-answer 1) 

By the way, this syntax is not “prettier” than macros.

How to make Clojure evaluate constant var at compile time and replace the reference with the actual value? Is it already done?

Before anyone starts quoting Knuth Law (“premature optimization is the root of all evil”), I ask this question to better understand the internals of Clojure compilation.

+7
source share
3 answers

From Clojure 1.3 documents

== 2.14 ^: const defs ==

^: const allows you to specify primitive values ​​with a faster reference.

(def constants {: pi 3.14: e 2.71})

(def ^: const pi (: pi constants)) (def: const e (: const constants))

The overhead: e and: pi on the map occurs during compilation time, since the constants (: pi) and (: e constants) are evaluated when their parent def forms are evaluated.

+11
source

One of the main uses of macros is to move computations to compile, so it only runs once. With that in mind, my opinion is that macros are the right tool for this , and the extra set ( ) looks to me as if it really helps to highlight the special parts.

+5
source

`~foo literally identical to foo in all cases - everything you think about leaving the first is an illusion.

I think that :const is probably the correct answer, but you can also use macro symbols from clojure.tools.macro - there is symbol-macrolet and defsymbolmacro / with-symbol-macros (as well as other uses).

+2
source

All Articles