clojure 有标识符宏吗?

Does clojure have identifier macros?

换句话说,有什么方法可以在看起来不像 (MACRO arg* ...).

的表单上触发宏扩展

举个假设的例子:

(defmacro my-var
  (do (printf "Using my-var!\n") 42))
(+ my-var 1) ;; Should print & return 43

我真正想做的是用自由变量调用 macroexpand。我想这些自由变量在宏展开时应该有特殊的意义,但之后应该回到"normal"。

抱歉,不,Clojure 没有这个功能。

除了 reader 宏,例如 quote '、syntax-quote `、dispatch # 等,它们会扩展到函数参数位置之外,您不能添加在此位置展开的宏。

Reader 文字略有相关,因为您可以定义将在读取时转换为数据结构的文字语法,尽管这些不能像您描述的那样用作变量。

syntax-quote reader 宏的 auto-gensym 特性有一点这种味道,尽管方式更加有限。

此功能目前作为 Clojure Contrib 库的功能之一存在于 Clojure 中 tools.macro。相关的 tools.macro 宏是 defsymbolmacrowith-symbol-macrossymbol-macrolet – 这是自述文件中的 symbol-macrolet 示例(现在可以在 master 分支的顶端找到):

(symbol-macrolet [def foo]
  (def def def))

expands to (def def foo)

symbol-macrolet 用于引入词法范围的符号宏,而 defsymbolmacro 引入应用于任何 with-symbol-macros 块内的符号宏(取消 with-symbol-macros 只会在 Clojure 编译器本身的支持下成为可能。

AFAIK,symbol-macrolet 的某个版本已经计划包含在 Clojure 的编译器中很长一段时间了;预计何时以及如果它着陆,它可能会被称为 letmacro。不过,没有具体的 public 时间表,当然也不能保证它会落地。

tools.macro 使用的名称受到 Common Lisp 的启发,其中相关的宏被称为 define-symbol-macro and symbol-macrolet。由于这是 CL 中的标准编译器功能,因此 define-symbol-macro 引入的符号宏实际上是全局应用的,无需任何辅助宏的帮助。