Reputation: 8700
While working on the Clojure Koans, I had to calculate the factorial of a number iterativly, I did find the solution, but I have a question about the difference between 2 solutions, one that works and one that doens't, although I don't understand why:
The one that works:
(defn factorial [n]
(loop [n n
acc 1]
(if (zero? n)
acc
(recur (dec n) (* n acc )))
)
The one that desn't:
(defn factorial [n]
(loop [n n
acc 1]
(if (zero? n)
1
(recur (dec n) (* n acc )))
)
Note that the only difference is the returned value of the If block if the condition is met.
Upvotes: 2
Views: 171
Reputation: 46882
it's hard to work out what you think should be happening for the question to make sense.
i think maybe you think loop
is doing more than it does? your code is almost equivalent to:
(defn factorial
([n] (factorial n 1)
([n acc]
(if (zero? n)
acc
(recur (dec n) (* n acc)))))
which is a stack-safe version of
(defn factorial
([n] (factorial n 1)
([n acc]
(if (zero? n)
acc
(factorial (dec n) (* n acc)))))
so the acc
(or 1
) is the final value returned from the function.
all that loop
does is give a different target for recur
, which is useful if you have some code between the start of the function and the point where you want to repeat. it's basically a label for a goto.
Upvotes: 1
Reputation: 25592
The second factorial
function always returns 1
. The code is built to use an accumulator variable (acc
), and the first code block gets it right by returning this accumulator variable.
A factorial
function can be written to return 1
, though, if an accumulator variable is not used. Since this method does not utilize loop
/ recur
, it can cause a stack overflow easily: try (fact 5000)
.
(defn factorial [x]
(if (<= x 1)
1
(* x (factorial (- x 1)))))
(source)
Upvotes: 5