1

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.

Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
saga
  • 1,933
  • 2
  • 17
  • 44
  • Possible duplicate of [Mutually recursive definitions in Clojure](https://stackoverflow.com/questions/3213405/mutually-recursive-definitions-in-clojure) – glts May 27 '18 at 16:32

2 Answers2

9

Literally declare:

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

(defn f2 []
  (f1))
Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
2

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
leetwinski
  • 17,408
  • 2
  • 18
  • 42
  • Interesting. I didn't know `letfn` allowed this. Of course though, this only works if defining the functions locally is sufficient. – Carcigenicate May 27 '18 at 23:08
  • @Carcigenicate, well you can always use `def` inside `letfn`. I do it sometimes to emphasize that these functions are connected. Updated my answer. – leetwinski May 28 '18 at 06:58