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))))
(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
;; Trailing position could be multiple (loop [x 1] (println "x= " x) (cond (> x 10) (println "ending at " x ) (even? x) (recur (* 2 x)) :else (recur (+ x 1))))
;; see `foo` and `bar` above ;; this `baz` uses normal recursion, this blows stacks but `foo` doesn't (defn baz [& args] (let [[x & more] args] (prn x) (if more (apply baz more) nil))) (baz :a :b :c) ;; :a ;; :b ;; :c ;;=> nil
Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to th...
trampoline can be used to convert algorithms requiring mutual recursion without stack consumption....
recur