Clojure:拯救一个函数

时间:2018-03-21 16:22:14

标签: clojure

我正在为Clojure编写一个简单的测试数据生成系统,它为给定的函数生成控制流图并对输入数据执行进化搜索。驱动该进化搜索的适应度函数是目标函数的一种形式,在每个条件形式的每个分支处具有标签(例如(if TEST (do (branch-label ...) THEN) (do (branch-label ...) ELSE)。使用控制流图中节点的索引调用branch-label函数,该索引对应于函数执行中的当前点和另一个分支的分支距离。然后,该函数基于进场水平和分支距离计算适合度值并将其存储在原子中。为了加快这个过程,我希望健身功能立即终止,如果执行遵循一条路径,这条路径将无法达到目标,或者达到了目标。

我最初的方法是让branch-label函数抛出一个特定类型的异常然后被我的搜索函数捕获,但后来我发现健身函数本身可能会捕获例如,如果在try-catch块内满足终止条件,则过早地例外。

e.g。假设我们在一个函数中有这个:

(try (if TEST THEN ELSE) (catch Exception _))

健身功能类似于:

(try 
    (if TEST 
      (do (branch-label ...) THEN)
      (do (branch-label ...) ELSE))
    (catch Exception _))

因此,如果branch-label在哪里抛出任何类型的异常,它将被吞并到这里并且该函数可能会继续运行。

我的另一个想法是在一个单独的线程上运行fitness函数并从分支标签函数内部调用(.stop (Thread/currentThread)),但似乎所有消息来源都说永远不应该使用Thread.stop。

总而言之,我的问题是试图找到一种(相对)干净的方式,在Clojure的常用控制流机制之外立即逃避正在运行的函数。

1 个答案:

答案 0 :(得分:0)

好的,所以我已经达到了我认为是令人满意的解决方案。我没有使用Thread.stop,而是将健身函数作为未来运行,并将其传递给一个承诺(后者又传递给branch-label)。主线程然后解除这个承诺(并因此被阻止)。在达到停止条件时,最终适应性将被传递到承诺并且主线程被解锁,并继续取消未来。