从调用函数中的最后一个位置调用时,递归Clojure函数不会重复出现

时间:2014-05-22 17:47:16

标签: recursion clojure

这是我的来电者

(resolveEntity [r entity-id]
  (println "resolve" entity-id)
  (recursive-get r entity-id)
  (cache entity-id)
)

被叫功能

(defn recursive-get [r entity-id]
(println "recursive" entity-id)
  (let [e (f (merge {} (-> r :conns first d/db (d/entity entity-id))))]
    (alter-var-root #'cache assoc entity-id e)
    (for [[k v] e]
      (if (:db/isComponent (k components))
        (if (not= (class v) Long)
          (map #(recursive-get r %) v)
          (recursive-get r v)
      )))))

被调用的函数只调用一次。如果我删除调用者中的最后一行(cache entity-id),那么每次我想要它都会重复,但我需要返回其他内容(cache entity-id)。

我测试了一个类似但更简单的代码(一个不在调用函数尾部调用的递归函数)REPL并且它工作正常,所以我不顾一切地撞到桌子上。

1 个答案:

答案 0 :(得分:1)

你被Lazy-Bug咬了!

如果你删除了最后一行,那么函数的返回值就是(recursive-get r entity-id)的结果,然后repl会遍历,以便它可以打印出来。打印每个值的行为会导致计算延迟集合中的每个条目。当你在那之后添加另一行时,忽略map的结果:没有任何内容读取,并且它们永远保持在未实现的延迟状态,并且计算永远不会发生。

要解决此问题,请将其打包到dorun

的调用中
(dorun (recursive-get r entity-id))

或者如果您需要保存结果,请改用doall