ClojureDocs

Nav

Namespaces

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.
9 Examples
(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
;; 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
See Also

Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to th...

Added by kumarshantanu

trampoline can be used to convert algorithms requiring mutual recursion without stack consumption....

Added by kumarshantanu
0 Notes
No notes for recur