Clojure is saying that I can\'t call recur
from a non-tail-position.
Is this not the tail position?
What is the tail position in my loop th
Further to @JohnBaker's answer, any recur
refers to the (nearest) enclosing loop
or fn
(which may be dressed as a letfn
or a defn
). There is no such thing in your snippet. So there is nothing for the recur
to be in tail position to.
But just replace the for
with loop
, and you get
(loop [i 20]
(loop [x 1]
(if (zero? (rem i x))
i
(recur (+ i 1)))))
... which evaluates to 20
,no doubt what you intended.
However, the outer loop
is never recurred to, so might at well be a let
:
(let [i 20]
(loop [x 1]
(if (zero? (rem i x))
i
(recur (+ i 1)))))
The recur
is in tail position because there is nothing left to do in that control path through the loop
form: the recur
form is the returned value. Both arms of an if
have their own tail position.
There are some other disguised if
s that have their own tail position: or
s and and
s are such.
for
does not do what you think it does; it is not an imperative loop. It is a list comprehension, or sequence-generator. Therefore, there is not a return or iterate call at its end, so you cannot place recur
there.
It would seem you probably do not need either loop
or recur
in this expression at all; the for
is all you need to build a sequence, but it's not clear to me exactly what sequence you wish to build.