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 或者你得到一个惰性序列)。这为每个步骤运行两个函数。显然,您需要传入一个列表列表。如果您愿意,您应该能够并行化整个批次。

这比尝试拼接整个向量要容易得多。绑定表单中的值被评估,因此它可以是您喜欢的任何值。

于 2012-12-04T23:29:45.500 回答