1.3.0 permalink Arrow_down_16x16
  • (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.

5 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)))))
    
  • (loop [x 10]
      (when (> x 1)
        (println x)
        (recur (- x 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))))))
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.