How to achieve mutual recursion to avoid names not being defined?

210 Views Asked by At

I've a clojure program in which two function recursively call each other:

(defn f1
...
(f2 ...)
)


(defn f2
...
(f1 ...)
)

The compiler is giving an error in f1. It's saying that f2 isn't defined. Is there a way to declare a function in clojure. I can verify that the recursion actually terminates.

2

There are 2 best solutions below

2
On

there is also a letfn form for (possibly) mutually recursive functions:

user=> (letfn [(f1 [x] (if (< x 10) (f2 x) x))
               (f2 [x] (f1 (inc x)))]
         (f2 0))

;;=> 10

update if you then need these functions globally, you can always use def inside letfn. As for me i find this approach to be a bit cleaner, than declare (especially for mutually recursive ones):

user> (letfn [(f1 [x] (if (< x 10) (f2 x) x))
              (f2 [x] (f1 (inc x)))]
        (def f1 f1)
        (def f2 f2))
#'user/f2

user> (f2 0)
;;=> 10
0
On

Literally declare:

(declare f2)
(defn f1 []
  (f2))

(defn f2 []
  (f1))