I'm very newbie with Clojure, and for practice I am trying to apply a simple algorithm for semi random numbers.
A few days ago, I read about loops in the docs of clojure, and how they work using recur
, so I tried to write a loop with this lines of code:
(def numbers_semi_random
(fn []
(loop[Xn 4 count 0]
(while (and (not (= Xn m)) (< count m))
(println (mod (+ (* 5.0 Xn) 7.0) m))
(recur (mod (+ (* 5.0 Xn) 7.0) m) (inc count))
))))
But when I execute the code, this error is displayed
CompilerException java.lang.UnsupportedOperationException: Can only recur from tail position, compiling
What's happening? recur
is not in the tail of the function?
The tail position is the last form that needs to be evaluated before leaving scope. When using loop
, the recur
statement must be able to start fresh with new bindings, no further calculations from the previous loop left to be done.
In your code, you have a while
block in the tail position of the loop
. The place where you try to call recur
is not in the loop's tail position (though it is in the tail of its tail).
Perhaps you intended for the recur
call to be outside the while
? But the comparison of loop bindings Xn
and count
to the global variable m
in the test for while
makes me think there is more to be untangled here. How many nested loops do you want here?