Macros 作为宏中具体化的一部分的动态let表单

Macros 作为宏中具体化的一部分的动态let表单,macros,clojure,reify,Macros,Clojure,Reify,好的,让我们试着澄清一下:我的最终目的是向用户提供一个宏作为API,它看起来像: (defscript [a b] (println a)) 结果必须是脚本协议的一个实例,如下所示: (defprotocol Script (run [this model])) 其思想是defscript的第一个参数是需要绑定到模型中相应键的符号列表: (.run (defscript [a b] (println a)) {:a 1}) ;; yields 1 我想不出任何代码可以有效地产生这样

好的,让我们试着澄清一下:我的最终目的是向用户提供一个宏作为API,它看起来像:

(defscript [a b]
  (println a))
结果必须是
脚本
协议的一个实例,如下所示:

(defprotocol Script
  (run [this model]))
其思想是
defscript
的第一个参数是需要绑定到
模型中相应键的符号列表:

(.run (defscript [a b] (println a)) {:a 1}) ;; yields 1
我想不出任何代码可以有效地产生这样的效果,因为我在尝试使用
model
参数时总是碰壁,因为在宏扩展时它只是一个符号:

(defmacro invoke-
  [params model body]
  (let [p (flatten (map (fn [x] [x (model (keyword x))]) params))]
    `(let [~@p]
       ~body)))

(defmacro defscript
  [params & body]
  `(reify Script
    (run [~'this ~'model]
      (invoke- ~params ~'model ~@body))))
invoke-
如果直接调用,效果很好:

(invoke- [a] {:a 1} (println a)) ;; prints 1
但当在
defscript
中使用时,它不起作用,因为
model
无法正确展开:

(.run (defscript [a] (println a)) {:a 1}) ;; prints nil

我如何才能越过这一点,将各个部分粘在一起?

基本上,您的参数向量是解构绑定的快捷方式:

(defscript [a b] body)  -> (reify Script (run [this {:keys [a b]}] body))

这样,模型在运行时就应该被分解。

您描述的内容听起来与
clojure.template
中提供的功能有些模糊。