Clojure编译时​​常量

Ral*_*lph 7 clojure compile-time-constant

这个问题纯粹来自"心理大师",可能没有实际价值.

如果我在Clojure中定义一个值def,是否可以诱导编译器在编译时对其进行评估,而不是等到运行时?

(def the-answer 42)

(+ the-answer 1)
Run Code Online (Sandbox Code Playgroud)

我想我可以定义一个宏,但调用语法变得有点尴尬:

(defmacro the-answer [] 42)

(+ (the-answer) 1)
Run Code Online (Sandbox Code Playgroud)

这也有效,但仍然很难看:

(+ `~the-answer 1)
Run Code Online (Sandbox Code Playgroud)

我也理解(或相信)Clojure在编译时评估常量表达式:

(def milliseconds-per-day (* 24 60 60 1000))
Run Code Online (Sandbox Code Playgroud)

我只是在学习Common Lisp,但我的理解是Common Lisp支持用户定义的阅读器宏,所以你可以定义一个阅读器宏(类似的东西#$),它在编译时评估下面的符号:

(+ #$the-answer 1)
Run Code Online (Sandbox Code Playgroud)

顺便说一句,该语法并不比宏调用"更漂亮".

如何让Clojure在编译时评估常量变量并用实际值替换引用?它已经这样做了吗?

在任何人开始引用Knuth定律之前("过早优化是所有邪恶的根源"),我要求这个问题更好地理解Clojure编译的内部.

Jul*_*ang 11

来自Clojure 1.3文档

== 2.14 ^:const defs ==

^:const允许您使用更快的引用命名原始值.

(def常数{:pi 3.14:e 2.71})

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

查找的开销:e和:地图中的pi发生在编译时,因为(:pi常量)和(:e常量)在评估其父def形式时进行评估.


Art*_*ldt 5

宏的一个主要用途是将计算转移到编译时间,因此它只执行一次.考虑到这一点,我认为宏是正确的工具,( )对我来说额外的外观就像它实际上有助于使特殊部件看起来特别.