Is it possible to define two functions in clojure which recursively call each other? For example, this pair:
(defn a [x]
(if (= 0 x) 0 (b (dec x))))
(defn b [x]
(if (= 0 x) 0 (a (dec x))))
Compilation fails with:
Unable to resolve symbol: b in this context
Since I haven't defined b
when I try to call it in a
.
e.g., in ruby this works fine:
def a(x)
x == 0 ? x : b(x-1)
end
def b(x)
x == 0 ? x : a(x-1)
end
A function is called a recursive function if it calls itself again and again . Recursion can be direct as well as indirect. Direct recursion is when a function calls itself. Whereas indirect recursion is when a function calls another function and the called function in turn calls the calling function.
The functions that call itself are direct recursive and when two functions call each other mutually, then those functions are called indirect recursive functions.
In 'C', the "main" function is called by the operating system when the user runs the program and it is treated the same way as every function, it has a return type. Although you can call the main() function within itself and it is called recursion.
either:
(declare b)
... ; rest of your code can then be used as is
or:
(def mutual
(letfn [(a [ ... ] ...)
(b [ ... ] ...)]
[a b]))
(def a (first mutual))
(def b (second mutual))
Depending on the execution of your code, keep in mind that you might get stack overflow exception.
There is where (clojure.core/trampoline) function come into the play and do its magic.
trampoline can be used to convert algorithms requiring mutual recursion without stack consumption. Calls f with supplied args, if any. If f returns a fn, calls that fn with no arguments, and continues to repeat, until the return value is not a fn, then returns that non-fn value. Note that if you want to return a fn as a final value, you must wrap it in some data structure and unpack it after trampoline returns.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With