2

わかりました。これをまっすぐにしてみましょう。私の最終的な目的は、次のようなマクロを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

どうすればこのポイントを乗り越えて、ピースを接着できますか?

4

1 に答える 1

4

基本的に、引数ベクトルはバインディングを破壊するためのショートカットのようです。

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

そうすることで、モデルは実行時に分解されます。

于 2011-10-28T06:53:05.740 に答える