わかりました。これをまっすぐにしてみましょう。私の最終的な目的は、次のようなマクロをAPIとしてユーザーに提供することです。
(defscript [a b]
(println a))
Script
結果は、次のようなプロトコルのインスタンスである必要があります。
(defprotocol Script
(run [this model]))
の最初の引数は、 :defscript
内の対応するキーにバインドする必要があるシンボルのリストであるという考えです。model
(.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
どうすればこのポイントを乗り越えて、ピースを接着できますか?