如何追踪功能会影响它的作用?

时间:2014-11-30 03:04:20

标签: clojure

我定义了一个函数play,如下所示:

(let [play-switch (fn [c]
                (condp = c
                    :scales (play-scale)
                    :intervals (play-interval)
                    :chords (play-chord)
                    :inversions (play-inversion)
                    (print "play error, invalid :practice_mode state")))]
(def ^:dynamic play 
  "if no argument, evaluates the appropriate play-<mode> function, based on the current state of @opts.
   if one argument, does the corresponding play-<mode> function."
  (fn 
    ([] (play-switch (get @opts :practice_mode)))
    ([method] (play-switch method)))))

当我在我的应用程序play中调用(play)时,其预期的副作用不会发生。但是,当我在我的应用程序中play时,(clojure.tools.trace/dotrace [play] (play))。跟踪函数如何影响它的作用?

1 个答案:

答案 0 :(得分:2)

跟踪函数可以强制实现其他未实现的延迟序列。

这些问题通常是“可怕的懒虫”的实例,其中一个函数的副作用(也就是工作)以懒惰的顺序运行。这具有令人费解的效果,即如果直接从REPL 调用该函数,则会在打印结果时发生副作用,如果使用trace调用它,则在跟踪打印结果时会实现延迟序列。虽然在正常情况下副作用永远不会发生,因为它没有实现懒惰序列。

调用doall(如果你需要结果)或dorun(如果你不需要结果)围绕每一方影响懒惰序列。