0

私は、作業中にさまざまな機能やステップを使用するアルゴリズムを持っています。これらのステップにバインドされたさまざまな可能な関数を使用してアルゴリズムを実行したいと思います。本質的に、いくつかの値のセット (特定の関数をこの特定のステップにバインドする必要があります) を準備し、それらのセットのすべてでアルゴリズムを実行したいと考えています。そして、入力セットと一緒にすべての実行の結果をキャプチャします。

そんな感じ:

(binding [step1 f1
          step2 f2]
(do-my-job))

(binding [step1 f11
          step2 f22]
(do-my-job))

ただし、動的バインディング式を使用します。

私のオプションは何ですか?

4

4 に答える 4

2

では、パラメータ スイープのようなことをしようとしているのですか?

動的バインディングを行う必要がある理由がわかりません。あなたのアルゴリズムは、ファーストクラスの関数呼び出しに関して定義されています。関数をパラメーターとしてアルゴリズムに渡すだけです。

すべての値を試すには、値の順列を生成し、このリストに対して map を実行します。これからすべての結果が得られます。

于 2012-12-01T19:59:45.977 に答える
1

バインディングはマクロであるため、動的バインディングフォームを生成するマクロを作成する必要があります。

于 2012-12-01T18:20:42.653 に答える
0

さて、私はそれが次のように機能しているようです:

(def conditions [[`step1 f1 `step2 f2] [`step1 f11 `step2 f22]])

(map #(eval `(binding ~% body)) conditions)
于 2012-12-01T21:09:08.517 に答える
0

それで、私はこれをテストしましたが、私が見る限り、すべてうまくいきます。

以下の例では、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 つの関数が実行されます。明らかに、リストのリストを渡す必要があります。必要に応じて、すべてを並列化できるはずです。

これは、ベクトル全体をスプライスしようとするよりもはるかに簡単です。バインディング フォームの値は評価されるため、好きな値にできます。

于 2012-12-04T23:29:45.500 に答える