• (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.

2 Examples top

  • ;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
    	(recur)))))
    
Log in to add / edit an example.

See Also top

Log in to add a see also.

Plus_12x12 Minus_12x12 Source clojure/core.clj:4025 top

(defmacro loop
  "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."
  {:added "1.0", :special-form true, :forms '[(loop [bindings*] exprs*)]}
  [bindings & body]
    (assert-args loop
      (vector? bindings) "a vector for its binding"
      (even? (count bindings)) "an even number of forms in binding vector")
    (let [db (destructure bindings)]
      (if (= db bindings)
        `(loop* ~bindings ~@body)
        (let [vs (take-nth 2 (drop 1 bindings))
              bs (take-nth 2 bindings)
              gs (map (fn [b] (if (symbol? b) b (gensym))) bs)
              bfs (reduce1 (fn [ret [b v g]]
                            (if (symbol? b)
                              (conj ret g v)
                              (conj ret g v b g)))
                          [] (map vector bs vs gs))]
          `(let ~bfs
             (loop* ~(vec (interleave gs gs))
               (let ~(vec (interleave bs gs))
                 ~@body)))))))
Vars in clojure.core/loop:
Used in 0 other vars

Comments top

No comments for loop. Log in to add a comment.