Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two functions which call each other recursively

Tags:

clojure

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
like image 525
spike Avatar asked Aug 24 '13 17:08

spike


People also ask

Is a function that calls another function recursive?

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.

Can two functions call each other?

The functions that call itself are direct recursive and when two functions call each other mutually, then those functions are called indirect recursive functions.

Can main () be called recursively?

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.


2 Answers

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))
like image 192
noisesmith Avatar answered Nov 10 '22 06:11

noisesmith


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.

like image 29
Chiron Avatar answered Nov 10 '22 07:11

Chiron