(loop bindings & body)
Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein. Acts as a recur target.
;; looping is recursive in Clojure, the loop construct is a hack so that
;; something like tail-recursive-optimization works in clojure.
user=> (defn my-re-seq [re string]
"Something like re-seq"
(let [matcher (re-matcher re string)]
(loop [match (re-find matcher) ;loop starts with 2 set arguments
result []]
(if-not match
result
(recur (re-find matcher) ;loop with 2 new arguments
(conj result match))))))
#'user/my-re-seq
user=> (my-re-seq #"\\d" "0123456789")
["0" "1" "2" "3" "4" "5" "6" "7" "8" "9"]
;; Read decoded MP3 data in loop (requires mp3plugin.jar on class path)
;; http://java.sun.com/javase/technologies/desktop/media/jmf/mp3/download.html
(import '(javax.sound.sampled AudioSystem AudioFormat$Encoding))
(let [mp3-file (java.io.File. "tryout.mp3")
audio-in (AudioSystem/getAudioInputStream mp3-file)
audio-decoded-in (AudioSystem/getAudioInputStream AudioFormat$Encoding/PCM_SIGNED audio-in)
buffer (make-array Byte/TYPE 1024)]
(loop []
(let [size (.read audio-decoded-in buffer)]
(when (> size 0)
;do something with PCM data
\t(recur)))))
(loop [x 10]
(when (> x 1)
(println x)
(recur (- x 2))))
;;=> 10 8 6 4 2
(defn find-needle [needle haystack]
;loop binds initial values once,
;then binds values from each recursion call
(loop [needle needle
maybe-here haystack
not-here '()]
(let [needle? (first maybe-here)]
;test for return or recur
(if (or (= (str needle?) (str needle))
(empty? maybe-here))
;return results
[needle? maybe-here not-here]
;recur calls loop with new values
(recur needle
(rest maybe-here)
(concat not-here (list (first maybe-here))))))))
user=>(find-needle "|" "hay|stack")
[\\| (\\| \\s \\t \\a \\c \\k) (\\h \\a \\y)]
; makes a simple template function that can be used in mustache way: http://mustache.github.com/
(defn template [tpl env]
(loop [tpl tpl
env env]
(cond (empty? env)
tpl
:else
(let [[key value] (first env)]
(recur (try (clojure.string/replace tpl
(re-pattern (str "\\\\{\\\\{" (name key) "\\\\}\\\\}"))
value)
(catch Exception e tpl))
(rest env))))))
(loop [iter 1
acc 0]
(if (> iter 10)
(println acc)
(recur (inc iter) (+ acc iter))))
;; => 55
;; sum from 1 to 10
;; loop is the recursion point for recur. The symbols in loop's
;; binding-forms are bound to their respective init-exprs and
;; rebound to the values of recur's exprs before the next execution
;; of loop's body.
;; calculate the factorial of n
(loop [n (bigint 5), accumulator 1]
(if (zero? n)
accumulator ; we're done
(recur (dec n) (* accumulator n))))
;;=> 120N
;; square each number in the vector
(loop [xs (seq [1 2 3 4 5])
result []]
(if xs
(let [x (first xs)]
(recur (next xs) (conj result (* x x))))
result))
;; => [1 4 9 16 25]
; 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
))
;; Iterating over a collection using loop
;; 1. First call (seq xs) on the given argument and then check for nil
;; 2. Then call next/first and use these.
(loop [xs (seq [1 2 3 4 5])
result []]
(if xs
(let [x (first xs)]
(recur (next xs) (conj result (* x x))))
result))
;; the same loop can be written using destructing,
;; but the compiler will generate two consecutive
;; seq calls and is slightly less efficient.
(loop [[x & r :as xs] (seq [])
result []]
(if xs
(recur r (conj result (* x x)))
result))
;;basic loop example #1
(loop [x 0
result []]
(if (< x 10)
(recur
(inc x)
(conj result x)) result))
;;[0 1 2 3 4 5 6 7 8 9]
;;basic loop example #2
(def citrus-list ["lemon" "orange" "grapefruit"])
(defn display-citrus [citruses]
(loop [[citrus & citruses] citruses]
(println citrus)
(if citrus (recur citruses))))
(display-citrus citrus-list)