我有一个算法,它在工作期间使用了许多不同的功能或步骤。我想运行具有绑定到这些步骤的不同可能功能的算法。本质上,我想准备一些值集(特定的函数应该绑定到这个特定的步骤)并运行我的算法与每个集合。并且用输入集捕获每次运行的结果。
类似的东西:
(binding [step1 f1
step2 f2]
(do-my-job))
(binding [step1 f11
step2 f22]
(do-my-job))
但使用动态绑定表达式。
我有什么选择?
答案 0 :(得分:2)
所以你试图做一些像参数扫描的事情?
我看不出你为什么需要动态绑定。您的算法是根据第一类函数调用定义的。只需将函数作为参数传递给算法。
要尝试所有值,只需生成值的排列,然后在此列表上运行map。您将从中获得所有结果。
答案 1 :(得分:1)
因为绑定是一个宏,你需要编写一个生成动态绑定表单的宏。
答案 2 :(得分:0)
好吧,看来我的工作方式如下:
(def conditions [[`step1 f1 `step2 f2] [`step1 f11 `step2 f22]])
(map #(eval `(binding ~% body)) conditions)
答案 3 :(得分: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或你得到一个懒的序列)。这为每个步骤运行两个函数。显然,您需要传递一个列表列表。如果您愿意,您应该可以并行化整个列表。
这比尝试拼接整个矢量要容易得多。评估绑定表单中的值,以便它可以是您喜欢的任何内容。