我正在尝试定义一个宏来定义在Clojure 1.3中添加的编译时常量语法:
== 2.14 ^:const defs ==
^:const允许您使用更快的参考命名原始值。
(def constants {:pi 3.14:e 2.71})
(def ^:const pi(:pi constants))(def ^:const e(:e constants))
查找的开销:e和:地图中的pi发生在编译时 时间,因为(:pi常数)和(:e常数)在它们的时候进行评估 父母def表格被评估。
基本上我想要(def ^:const ... ...)
左右的语法糖,所以我试着这样做:
(defmacro defconst [const-name const-val]
`(def ^:const ~const-name ~const-val))
但这不起作用:
user=> (macroexpand '(defconst pi 3.14))
(def pi 3.14)
从我收集的内容来看,#^<...>
元快捷方式是一个读取器宏,并且要定义一个向某些内容添加元数据的宏,应该使用(with-meta ...)
。
我没有找到关于^:const
的任何文件。这个语法结构是否甚至可以创建某种元数据?以下示例未显示任何内容:
user=> (def ^:const pi 3.14)
#'user/pi
user=> (meta pi)
nil
答案 0 :(得分:10)
第一个问题是您正在检查3.14
的元数据。使用(meta (var pi))
查看pi
的元数据。如果您这样做,您会看到它包含:const true
。
(defmacro defconst [const-name const-val]
`(def
~(with-meta const-name
(assoc (meta const-name) :const true))
~const-val))
准确地再现了^:const
的元数据和性能(代码是根据defn-
的来源改编的。)