それで、私はこれをテストしましたが、私が見る限り、すべてうまくいきます。
以下の例では、var を作成してから、この var を関数に再バインドします。ご覧のとおり、関数の呼び出しはバインディング フォームのレキシカル スコープの外で行われるため、ここでは動的バインディングを行います。
(def
^{:dynamic true}
*bnd-fn*
nil
)
(defn fn1 []
(println "fn1"))
(defn fn2 []
(println "fn2"))
(defn callfn []
(*bnd-fn*))
;; crash with NPE
(callfn)
;; prints fn1
(binding [*bnd-fn* fn1]
(callfn))
;; prints fn2
(binding [*bnd-fn* fn2]
(callfn))
私自身のライブラリにも同様のアプローチを使用してきました (興味がある場合は Clojure-owl を使用してください!) が、私の場合、動的に再バインドする必要があるのは Java オブジェクトです。
その場合、動的な再バインドを許可しましたが、ほとんどの場合は許可しません。名前空間ごとに異なる Java オブジェクトを使用するだけです。これは私にとってうまく機能します。
あなたのコメントへの返信として、単一のバインディング フォームが必要な場合、これは簡単に実現できます。次のコードを追加します。
(defn dobinding [fn]
(binding [*bnd-fn* fn]
(callfn)))
(dorun
(map dobinding
[fn1 fn2]))
関数 dobinding は、他のすべてを実行します。次に、これを単一のマップで評価します (そして dorun または遅延シーケンスを取得します)。これにより、各ステップで 2 つの関数が実行されます。明らかに、リストのリストを渡す必要があります。必要に応じて、すべてを並列化できるはずです。
これは、ベクトル全体をスプライスしようとするよりもはるかに簡単です。バインディング フォームの値は評価されるため、好きな値にできます。