Clojure编译时常量

Clojure编译时常量,clojure,compile-time-constant,Clojure,Compile Time Constant,这个问题纯粹来自“心理控制”,可能没有实际价值 如果我在Clojure中使用def定义一个值,编译器是否可以在编译时对其求值,而不是等到运行时 (def the-answer 42) (+ the-answer 1) 我想我可以定义一个宏,但是调用语法有点笨拙: (defmacro the-answer [] 42) (+ (the-answer) 1) 这也行得通,但仍然很难看: (+ `~the-answer 1) 我还了解(或相信)Clojure在编译时计算常量表达式: (def

这个问题纯粹来自“心理控制”,可能没有实际价值

如果我在Clojure中使用
def
定义一个值,编译器是否可以在编译时对其求值,而不是等到运行时

(def the-answer 42)

(+ the-answer 1)
我想我可以定义一个宏,但是调用语法有点笨拙:

(defmacro the-answer [] 42)

(+ (the-answer) 1)
这也行得通,但仍然很难看:

(+ `~the-answer 1)
我还了解(或相信)Clojure在编译时计算常量表达式:

(def milliseconds-per-day (* 24 60 60 1000))
我只是在学习Common Lisp,但我的理解是Common Lisp支持用户定义的读卡器宏,因此您可以定义一个读卡器宏(类似于
#$
),在编译时计算以下符号:

(+ #$the-answer 1)
顺便说一句,这种语法并不比宏调用更“漂亮”

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


在任何人引用Knuth定律(“过早优化是万恶之源”)之前,我问这个问题是为了更好地理解Clojure编译的内部结构。

宏的主要用途之一是将计算移到编译时,因此只需执行一次。考虑到这一点,我的观点是宏是实现这一点的正确工具,在我看来,额外的
()
集实际上有助于使特殊部件看起来特别。

来自

==2.14^:常数定义==

^:const允许您使用更快的引用命名基元值

(def常数{:pi3.14:e2.71})

(定义:常数pi(:pi常量))(定义:常数e(:e常量))

在映射中查找:e和:pi的开销发生在编译时 时间,作为(:pi常数)和(:e常数)在其 对父def表单进行评估


`~foo
在任何情况下都与
foo
完全相同——你认为从前者中得到的任何东西都是幻觉


我认为
:const
可能是正确的答案,但您也可以使用clojure.tools.macro中的符号宏-它有
符号宏let
defsymbolmacro
/
以及符号宏
用于此目的(以及其他用途)。

这不是pontification。“浮夸”是指夸夸其谈或武断。这是一个合理的答案,我也有同样的想法。语法比`~theanswer选项更好。我没有意识到关于
~foo。谢谢当我进一步思考这个问题时,
^:const`看起来确实是正确的选择,但只适用于原语(不包括
String
实例)。字符串的问题是,使用宏或常量可能会导致运行时比较
字符串
内容,而不是地址。如果这样做的原因是为了性能,那就是损失。