如何为宏生成表达式?

How to generate expressions for a macro?

因为不能将宏应用于列表,例如

;; does not work
(apply -> [expr1 expr2 expr3])

如何生成这样的表达式:

(-> expr1
    expr2
    expr3)

在哪里


上下文

我正在尝试设计嵌入式 DSL,例如

["increment" "increment" "increment"]

然后将其转换为代码,例如

(fn [n] (-> n inc inc inc))

您可以使用宏生成它,例如

(defmacro opfun [op-names]
  (let [m {"increment" 'inc}
        ops (map m op-names)]
    `(fn [n#] (-> n# ~@ops))))

然后

(opfun ["increment" "increment" "increment"])

如果您需要在运行时提供参数列表,您可以直接解释您的结构,例如

(defn build-eval [op-names]
  (let [m {"increment" inc}
        ops (map m op-names)]
    (fn [n] (reduce (fn [acc f] (f acc)) n ops))))