Evaluates the exprs in order, then, in parallel, rebinds the bindings of the recursion point to the values of the exprs. See http://clojure.org/special_forms for more information.
(def factorial
(fn [n]
(loop [cnt n acc 1]
(if (zero? cnt)
acc
(recur (dec cnt) (* acc cnt))
; in loop cnt will take the value (dec cnt)
; and acc will take the value (* acc cnt)
))))
; A loop that sums the numbers 10 + 9 + 8 + ...
; Set initial values count (cnt) from 10 and down
(loop [sum 0 cnt 10]
; If count reaches 0 then exit the loop and return sum
(if (= cnt 0)
sum
; Otherwise add count to sum, decrease count and
; use recur to feed the new values back into the loop
(recur (+ cnt sum) (dec cnt))))
(loop [i 0]
(when (< i 5)
(println i)
(recur (inc i)); loop i will take this value
))
(defn compute-across [func elements value]
(if (empty? elements)
value
(recur func (rest elements) (func value (first elements)))))
(defn total-of [numbers]
(compute-across + numbers 0))
(defn larger-of [x y]
(if (> x y) x y))
(defn greatest-of [numbers]
(compute-across larger-of numbers (first numbers)))
; Note that recur can be surprising when using variadic functions.
(defn foo [& args]
(let [[x & more] args]
(prn x)
(if more (recur more) nil)))
(defn bar [& args]
(let [[x & more] args]
(prn x)
(if more (bar more) nil)))
; The key thing to note here is that foo and bar are identical, except
; that foo uses recur and bar uses "normal" recursion. And yet...
user=> (foo :a :b :c)
:a
:b
:c
nil
user=> (bar :a :b :c)
:a
(:b :c)
nil
; The difference arises because recur does not gather variadic/rest args
; into a seq.
;;This will generate the first 1000 Fibonacci numbers
;;(using incrementing and decrementing):
(loop [res [0 1]]
(if (>= (count res) 1000)
res
(recur (conj res (+' (inc (last res)) (dec (last (butlast res))))))))
;; The recursion point can be a 'loop' or a 'fn' method.
(loop [n (bigint 5), accumulator 1]
(if (zero? n)
accumulator ; we're done
(recur (dec n) (* accumulator n))))
;;=> 120N
((fn factorial
([n] (factorial n 1))
([n accumulator]
(if (zero? n)
accumulator ; we're done
(recur (dec n) (* accumulator n)))))
(bigint 5))
;;=> 120N