Clojure recursion, loop/recur.
;;; Clojure recursion
(defn every-other [coll]
(if (empty? coll)
'()
(conj (every-other (rest (rest coll))) (first coll))))
(every-other '(2 3 4))
(every-other [])
(every-other [2])
(every-other (take 10 (range)))
;; You can write this in tail-recursive fashion:
(defn every-other2 [coll result]
(if (empty? coll)
result
(every-other2 (rest (rest coll)) (conj result (first coll)))))
(every-other2 '(2 3 4) '())
(every-other2 [] '())
(every-other2 [2] '())
(every-other2 (take 10 (range)) '())
;; However, Java doesn't optimize tail recursion
;; Clojure has a loop-recur form for tail recursion:
(defn every-other-loop [coll]
(loop [c coll r '()]
(if (empty? c)
r
(recur (rest (rest c)) (conj r (first c))))))
;; This is almost correct, except the order is reversed (why?)
(every-other-loop '(2 3 4))
(every-other-loop [])
(every-other-loop [2])
(every-other-loop (take 10 (range)))
;; Passing [] as initial value for r in loop/recur
;; changes the order of adding elements via conj
(defn every-other-loop2 [coll]
(loop [c coll r []]
(if (empty? c)
r
(recur (rest (rest c)) (conj r (first c))))))
;; This is almost correct, except the order os reversed (why?)
(every-other-loop2 '(2 3 4))
(every-other-loop2 [])
(every-other-loop2 [2])
(every-other-loop2 (take 10 (range)))
CSci 4651
course web site.