两个函数以递归方式相互调用

时间:2013-08-24 17:50:18

标签: clojure

是否可以在clojure中定义两个递归调用的函数?例如,这一对:

(defn a [x]
  (if (= 0 x) 0 (b (dec x))))

(defn b [x]
  (if (= 0 x) 0 (a (dec x))))

编译失败:

Unable to resolve symbol: b in this context

我尝试在b中调用a时未定义def a(x) x == 0 ? x : b(x-1) end def b(x) x == 0 ? x : a(x-1) end

例如,在ruby中这很好用:

{{1}}

2 个答案:

答案 0 :(得分:6)

或者:

(declare b) ...;其余的代码可以按原样使用

或:

(def mutual
 (letfn [(a [ ... ] ...)
         (b [ ... ] ...)]
  [a b]))

(def a (first mutual))
(def b (second mutual))

答案 1 :(得分:6)

根据代码的执行情况,请记住,您可能会遇到堆栈溢出异常。

有(clojure.core / trampoline)功能进入游戏并发挥其魔力。

  蹦床可用于转换需要相互作用的算法   没有堆栈消耗的递归。如果,使用提供的args调用f   任何。如果f返回一个fn,则调用没有参数的fn,和   继续重复,直到返回值不是fn,然后   返回非fn值。请注意,如果要将fn作为a返回   最终值,您必须将其包装在某些数据结构中并解压缩   蹦床回来后。