Mercurial > lasercutter
view src/clojure/contrib/seq.clj @ 10:ef7dbbd6452c
added clojure source goodness
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 06:25:44 -0400 |
parents | |
children |
line wrap: on
line source
1 ;;; seq_utils.clj -- Sequence utilities for Clojure3 ;; by Stuart Sierra, http://stuartsierra.com/4 ;; last updated March 2, 20096 ;; Copyright (c) Stuart Sierra, 2008. All rights reserved. The use7 ;; and distribution terms for this software are covered by the Eclipse8 ;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)9 ;; which can be found in the file epl-v10.html at the root of this10 ;; distribution. By using this software in any fashion, you are11 ;; agreeing to be bound by the terms of this license. You must not12 ;; remove this notice, or any other, from this software.15 ;; Change Log16 ;;17 ;; January 10, 2009 (Stuart Sierra):18 ;;19 ;; * BREAKING CHANGE: "includes?" now takes collection as first20 ;; argument. This is more consistent with Clojure collection21 ;; functions; see discussion at http://groups.google.com/group/clojure/browse_thread/thread/8b2c8dc96b39ddd7/a8866d34b601ff4324 (ns25 ^{:author "Stuart Sierra (and others)",26 :doc "Sequence utilities for Clojure"}27 clojure.contrib.seq28 (:import (java.util.concurrent LinkedBlockingQueue TimeUnit)29 (java.lang.ref WeakReference))30 (:refer-clojure :exclude [frequencies shuffle partition-by reductions partition-all group-by flatten]))33 ;; 'flatten' written by Rich Hickey,34 ;; see http://groups.google.com/group/clojure/msg/385098fabfcaad9b35 (defn flatten36 "DEPRECATED. Prefer clojure.core version.37 Takes any nested combination of sequential things (lists, vectors,38 etc.) and returns their contents as a single, flat sequence.39 (flatten nil) returns nil."40 {:deprecated "1.2"}41 [x]42 (filter (complement sequential?)43 (rest (tree-seq sequential? seq x))))45 (defn separate46 "Returns a vector:47 [ (filter f s), (filter (complement f) s) ]"48 [f s]49 [(filter f s) (filter (complement f) s)])51 (defn indexed52 "Returns a lazy sequence of [index, item] pairs, where items come53 from 's' and indexes count up from zero.55 (indexed '(a b c d)) => ([0 a] [1 b] [2 c] [3 d])"56 [s]57 (map vector (iterate inc 0) s))59 ;; group-by written by Rich Hickey;60 ;; see http://paste.lisp.org/display/6419061 (defn group-by62 "DEPRECATED. Prefer clojure.core version.63 Returns a sorted map of the elements of coll keyed by the result of64 f on each element. The value at each key will be a vector of the65 corresponding elements, in the order they appeared in coll."66 {:deprecated "1.2"}67 [f coll]68 (reduce69 (fn [ret x]70 (let [k (f x)]71 (assoc ret k (conj (get ret k []) x))))72 (sorted-map) coll))74 ;; partition-by originally written by Rich Hickey;75 ;; modified by Stuart Sierra76 (defn partition-by77 "DEPRECATED. Prefer clojure.core version.78 Applies f to each value in coll, splitting it each time f returns79 a new value. Returns a lazy seq of lazy seqs."80 {:deprecated "1.2"}81 [f coll]82 (when-let [s (seq coll)]83 (let [fst (first s)84 fv (f fst)85 run (cons fst (take-while #(= fv (f %)) (rest s)))]86 (lazy-seq87 (cons run (partition-by f (drop (count run) s)))))))89 (defn frequencies90 "DEPRECATED. Prefer clojure.core version.91 Returns a map from distinct items in coll to the number of times92 they appear."93 {:deprecated "1.2"}94 [coll]95 (reduce (fn [counts x]96 (assoc counts x (inc (get counts x 0))))97 {} coll))99 ;; recursive sequence helpers by Christophe Grand100 ;; see http://clj-me.blogspot.com/2009/01/recursive-seqs.html101 (defmacro rec-seq102 "Similar to lazy-seq but binds the resulting seq to the supplied103 binding-name, allowing for recursive expressions."104 [binding-name & body]105 `(let [s# (atom nil)]106 (reset! s# (lazy-seq (let [~binding-name @s#] ~@body)))))108 (defmacro rec-cat109 "Similar to lazy-cat but binds the resulting sequence to the supplied110 binding-name, allowing for recursive expressions."111 [binding-name & exprs]112 `(rec-seq ~binding-name (lazy-cat ~@exprs)))115 ;; reductions by Chris Houser116 ;; see http://groups.google.com/group/clojure/browse_thread/thread/3edf6e82617e18e0/58d9e319ad92aa5f?#58d9e319ad92aa5f117 (defn reductions118 "DEPRECATED. Prefer clojure.core version.119 Returns a lazy seq of the intermediate values of the reduction (as120 per reduce) of coll by f, starting with init."121 {:deprecated "1.2"}122 ([f coll]123 (if (seq coll)124 (rec-seq self (cons (first coll) (map f self (rest coll))))125 (cons (f) nil)))126 ([f init coll]127 (rec-seq self (cons init (map f self coll)))))129 (defn rotations130 "Returns a lazy seq of all rotations of a seq"131 [x]132 (if (seq x)133 (map134 (fn [n _]135 (lazy-cat (drop n x) (take n x)))136 (iterate inc 0) x)137 (list nil)))139 (defn partition-all140 "DEPRECATED. Prefer clojure.core version.141 Returns a lazy sequence of lists like clojure.core/partition, but may142 include lists with fewer than n items at the end."143 {:deprecated "1.2"}144 ([n coll]145 (partition-all n n coll))146 ([n step coll]147 (lazy-seq148 (when-let [s (seq coll)]149 (cons (take n s) (partition-all n step (drop step s)))))))151 (defn shuffle152 "DEPRECATED. Prefer clojure.core version.153 Return a random permutation of coll"154 {:deprecated "1.2"}155 [coll]156 (let [l (java.util.ArrayList. coll)]157 (java.util.Collections/shuffle l)158 (seq l)))160 (defn rand-elt161 "DEPRECATED. Prefer clojure.core/rand-nth.162 Return a random element of this seq"163 {:deprecated "1.2"}164 [s]165 (nth s (rand-int (count s))))167 ;; seq-on written by Konrad Hinsen168 (defmulti seq-on169 "Returns a seq on the object s. Works like the built-in seq but as170 a multimethod that can have implementations for new classes and types."171 {:arglists '([s])}172 type)174 (defmethod seq-on :default175 [s]176 (seq s))179 (defn find-first180 "Returns the first item of coll for which (pred item) returns logical true.181 Consumes sequences up to the first match, will consume the entire sequence182 and return nil if no match is found."183 [pred coll]184 (first (filter pred coll)))186 ; based on work related to Rich Hickey's seque.187 ; blame Chouser for anything broken or ugly.188 (defn fill-queue189 "filler-func will be called in another thread with a single arg190 'fill'. filler-func may call fill repeatedly with one arg each191 time which will be pushed onto a queue, blocking if needed until192 this is possible. fill-queue will return a lazy seq of the values193 filler-func has pushed onto the queue, blocking if needed until each194 next element becomes available. filler-func's return value is ignored."195 ([filler-func & optseq]196 (let [opts (apply array-map optseq)197 apoll (:alive-poll opts 1)198 q (LinkedBlockingQueue. (:queue-size opts 1))199 NIL (Object.) ;nil sentinel since LBQ doesn't support nils200 weak-target (Object.)201 alive? (WeakReference. weak-target)202 fill (fn fill [x]203 (if (.get alive?)204 (if (.offer q (if (nil? x) NIL x) apoll TimeUnit/SECONDS)205 x206 (recur x))207 (throw (Exception. "abandoned"))))208 f (future209 (try210 (filler-func fill)211 (finally212 (.put q q))) ;q itself is eos sentinel213 nil)] ; set future's value to nil214 ((fn drain []215 weak-target ; force closing over this object216 (lazy-seq217 (let [x (.take q)]218 (if (identical? x q)219 @f ;will be nil, touch just to propagate errors220 (cons (if (identical? x NIL) nil x)221 (drain))))))))))223 (defn positions224 "Returns a lazy sequence containing the positions at which pred225 is true for items in coll."226 [pred coll]227 (for [[idx elt] (indexed coll) :when (pred elt)] idx))229 (defn includes?230 "Returns true if coll contains something equal (with =) to x,231 in linear time. Deprecated. Prefer 'contains?' for key testing,232 or 'some' for ad hoc linear searches."233 {:deprecated "1.2"}234 [coll x]235 (boolean (some (fn [y] (= y x)) coll)))