recur

added

ns
clojure.core

type
var

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