diff src/clojure/core.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 diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/clojure/core.clj	Sat Aug 21 06:25:44 2010 -0400
     1.3 @@ -0,0 +1,5710 @@
     1.4 +;   Copyright (c) Rich Hickey. All rights reserved.
     1.5 +;   The use and distribution terms for this software are covered by the
     1.6 +;   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
     1.7 +;   which can be found in the file epl-v10.html at the root of this distribution.
     1.8 +;   By using this software in any fashion, you are agreeing to be bound by
     1.9 +;   the terms of this license.
    1.10 +;   You must not remove this notice, or any other, from this software.
    1.11 +
    1.12 +(ns clojure.core)
    1.13 +
    1.14 +(def unquote)
    1.15 +(def unquote-splicing)
    1.16 +
    1.17 +(def
    1.18 + ^{:arglists '([& items])
    1.19 +   :doc "Creates a new list containing the items."
    1.20 +   :added "1.0"}
    1.21 +  list (. clojure.lang.PersistentList creator))
    1.22 +
    1.23 +(def
    1.24 + ^{:arglists '([x seq])
    1.25 +    :doc "Returns a new seq where x is the first element and seq is
    1.26 +    the rest."
    1.27 +   :added "1.0"}
    1.28 +
    1.29 + cons (fn* cons [x seq] (. clojure.lang.RT (cons x seq))))
    1.30 +
    1.31 +;during bootstrap we don't have destructuring let, loop or fn, will redefine later
    1.32 +(def
    1.33 +  ^{:macro true
    1.34 +    :added "1.0"}
    1.35 +  let (fn* let [&form &env & decl] (cons 'let* decl)))
    1.36 +
    1.37 +(def
    1.38 + ^{:macro true
    1.39 +   :added "1.0"}
    1.40 + loop (fn* loop [&form &env & decl] (cons 'loop* decl)))
    1.41 +
    1.42 +(def
    1.43 + ^{:macro true
    1.44 +   :added "1.0"}
    1.45 + fn (fn* fn [&form &env & decl] 
    1.46 +         (.withMeta ^clojure.lang.IObj (cons 'fn* decl) 
    1.47 +                    (.meta ^clojure.lang.IMeta &form))))
    1.48 +
    1.49 +(def
    1.50 + ^{:arglists '([coll])
    1.51 +   :doc "Returns the first item in the collection. Calls seq on its
    1.52 +    argument. If coll is nil, returns nil."
    1.53 +   :added "1.0"}
    1.54 + first (fn first [coll] (. clojure.lang.RT (first coll))))
    1.55 +
    1.56 +(def
    1.57 + ^{:arglists '([coll])
    1.58 +   :tag clojure.lang.ISeq
    1.59 +   :doc "Returns a seq of the items after the first. Calls seq on its
    1.60 +  argument.  If there are no more items, returns nil."
    1.61 +   :added "1.0"}  
    1.62 + next (fn next [x] (. clojure.lang.RT (next x))))
    1.63 +
    1.64 +(def
    1.65 + ^{:arglists '([coll])
    1.66 +   :tag clojure.lang.ISeq
    1.67 +   :doc "Returns a possibly empty seq of the items after the first. Calls seq on its
    1.68 +  argument."
    1.69 +   :added "1.0"}  
    1.70 + rest (fn rest [x] (. clojure.lang.RT (more x))))
    1.71 +
    1.72 +(def
    1.73 + ^{:arglists '([coll x] [coll x & xs])
    1.74 +   :doc "conj[oin]. Returns a new collection with the xs
    1.75 +    'added'. (conj nil item) returns (item).  The 'addition' may
    1.76 +    happen at different 'places' depending on the concrete type."
    1.77 +   :added "1.0"}
    1.78 + conj (fn conj 
    1.79 +        ([coll x] (. clojure.lang.RT (conj coll x)))
    1.80 +        ([coll x & xs]
    1.81 +         (if xs
    1.82 +           (recur (conj coll x) (first xs) (next xs))
    1.83 +           (conj coll x)))))
    1.84 +
    1.85 +(def
    1.86 + ^{:doc "Same as (first (next x))"
    1.87 +   :arglists '([x])
    1.88 +   :added "1.0"}
    1.89 + second (fn second [x] (first (next x))))
    1.90 +
    1.91 +(def
    1.92 + ^{:doc "Same as (first (first x))"
    1.93 +   :arglists '([x])
    1.94 +   :added "1.0"}
    1.95 + ffirst (fn ffirst [x] (first (first x))))
    1.96 +
    1.97 +(def
    1.98 + ^{:doc "Same as (next (first x))"
    1.99 +   :arglists '([x])
   1.100 +   :added "1.0"}
   1.101 + nfirst (fn nfirst [x] (next (first x))))
   1.102 +
   1.103 +(def
   1.104 + ^{:doc "Same as (first (next x))"
   1.105 +   :arglists '([x])
   1.106 +   :added "1.0"}
   1.107 + fnext (fn fnext [x] (first (next x))))
   1.108 +
   1.109 +(def
   1.110 + ^{:doc "Same as (next (next x))"
   1.111 +   :arglists '([x])
   1.112 +   :added "1.0"}
   1.113 + nnext (fn nnext [x] (next (next x))))
   1.114 +
   1.115 +(def
   1.116 + ^{:arglists '([coll])
   1.117 +   :doc "Returns a seq on the collection. If the collection is
   1.118 +    empty, returns nil.  (seq nil) returns nil. seq also works on
   1.119 +    Strings, native Java arrays (of reference types) and any objects
   1.120 +    that implement Iterable."
   1.121 +   :tag clojure.lang.ISeq
   1.122 +   :added "1.0"}
   1.123 + seq (fn seq [coll] (. clojure.lang.RT (seq coll))))
   1.124 +
   1.125 +(def
   1.126 + ^{:arglists '([^Class c x])
   1.127 +   :doc "Evaluates x and tests if it is an instance of the class
   1.128 +    c. Returns true or false"
   1.129 +   :added "1.0"}
   1.130 + instance? (fn instance? [^Class c x] (. c (isInstance x))))
   1.131 +
   1.132 +(def
   1.133 + ^{:arglists '([x])
   1.134 +   :doc "Return true if x implements ISeq"
   1.135 +   :added "1.0"}
   1.136 + seq? (fn seq? [x] (instance? clojure.lang.ISeq x)))
   1.137 +
   1.138 +(def
   1.139 + ^{:arglists '([x])
   1.140 +   :doc "Return true if x is a Character"
   1.141 +   :added "1.0"}
   1.142 + char? (fn char? [x] (instance? Character x)))
   1.143 +
   1.144 +(def
   1.145 + ^{:arglists '([x])
   1.146 +   :doc "Return true if x is a String"
   1.147 +   :added "1.0"}
   1.148 + string? (fn string? [x] (instance? String x)))
   1.149 +
   1.150 +(def
   1.151 + ^{:arglists '([x])
   1.152 +   :doc "Return true if x implements IPersistentMap"
   1.153 +   :added "1.0"}
   1.154 + map? (fn map? [x] (instance? clojure.lang.IPersistentMap x)))
   1.155 +
   1.156 +(def
   1.157 + ^{:arglists '([x])
   1.158 +   :doc "Return true if x implements IPersistentVector"
   1.159 +   :added "1.0"}
   1.160 + vector? (fn vector? [x] (instance? clojure.lang.IPersistentVector x)))
   1.161 +
   1.162 +(def
   1.163 + ^{:arglists '([map key val] [map key val & kvs])
   1.164 +   :doc "assoc[iate]. When applied to a map, returns a new map of the
   1.165 +    same (hashed/sorted) type, that contains the mapping of key(s) to
   1.166 +    val(s). When applied to a vector, returns a new vector that
   1.167 +    contains val at index. Note - index must be <= (count vector)."
   1.168 +   :added "1.0"}
   1.169 + assoc
   1.170 + (fn assoc
   1.171 +   ([map key val] (. clojure.lang.RT (assoc map key val)))
   1.172 +   ([map key val & kvs]
   1.173 +    (let [ret (assoc map key val)]
   1.174 +      (if kvs
   1.175 +        (recur ret (first kvs) (second kvs) (nnext kvs))
   1.176 +        ret)))))
   1.177 +
   1.178 +;;;;;;;;;;;;;;;;; metadata ;;;;;;;;;;;;;;;;;;;;;;;;;;;
   1.179 +(def
   1.180 + ^{:arglists '([obj])
   1.181 +   :doc "Returns the metadata of obj, returns nil if there is no metadata."
   1.182 +   :added "1.0"}
   1.183 + meta (fn meta [x]
   1.184 +        (if (instance? clojure.lang.IMeta x)
   1.185 +          (. ^clojure.lang.IMeta x (meta)))))
   1.186 +
   1.187 +(def
   1.188 + ^{:arglists '([^clojure.lang.IObj obj m])
   1.189 +   :doc "Returns an object of the same type and value as obj, with
   1.190 +    map m as its metadata."
   1.191 +   :added "1.0"}
   1.192 + with-meta (fn with-meta [^clojure.lang.IObj x m]
   1.193 +             (. x (withMeta m))))
   1.194 +
   1.195 +(def ^{:private true :dynamic true}
   1.196 +  assert-valid-fdecl (fn [fdecl]))
   1.197 +
   1.198 +(def
   1.199 + ^{:private true}
   1.200 + sigs
   1.201 + (fn [fdecl]
   1.202 +   (assert-valid-fdecl fdecl)
   1.203 +   (let [asig 
   1.204 +         (fn [fdecl]
   1.205 +           (let [arglist (first fdecl)
   1.206 +                 ;elide implicit macro args
   1.207 +                 arglist (if (clojure.lang.Util/equals '&form (first arglist)) 
   1.208 +                           (clojure.lang.RT/subvec arglist 2 (clojure.lang.RT/count arglist))
   1.209 +                           arglist)
   1.210 +                 body (next fdecl)]
   1.211 +             (if (map? (first body))
   1.212 +               (if (next body)
   1.213 +                 (with-meta arglist (conj (if (meta arglist) (meta arglist) {}) (first body)))
   1.214 +                 arglist)
   1.215 +               arglist)))]
   1.216 +     (if (seq? (first fdecl))
   1.217 +       (loop [ret [] fdecls fdecl]
   1.218 +         (if fdecls
   1.219 +           (recur (conj ret (asig (first fdecls))) (next fdecls))
   1.220 +           (seq ret)))
   1.221 +       (list (asig fdecl))))))
   1.222 +
   1.223 +
   1.224 +(def 
   1.225 + ^{:arglists '([coll])
   1.226 +   :doc "Return the last item in coll, in linear time"
   1.227 +   :added "1.0"}
   1.228 + last (fn last [s]
   1.229 +        (if (next s)
   1.230 +          (recur (next s))
   1.231 +          (first s))))
   1.232 +
   1.233 +(def 
   1.234 + ^{:arglists '([coll])
   1.235 +   :doc "Return a seq of all but the last item in coll, in linear time"
   1.236 +   :added "1.0"}
   1.237 + butlast (fn butlast [s]
   1.238 +           (loop [ret [] s s]
   1.239 +             (if (next s)
   1.240 +               (recur (conj ret (first s)) (next s))
   1.241 +               (seq ret)))))
   1.242 +
   1.243 +(def 
   1.244 +
   1.245 + ^{:doc "Same as (def name (fn [params* ] exprs*)) or (def
   1.246 +    name (fn ([params* ] exprs*)+)) with any doc-string or attrs added
   1.247 +    to the var metadata"
   1.248 +   :arglists '([name doc-string? attr-map? [params*] body]
   1.249 +                [name doc-string? attr-map? ([params*] body)+ attr-map?])
   1.250 +   :added "1.0"}
   1.251 + defn (fn defn [&form &env name & fdecl]
   1.252 +        (let [m (if (string? (first fdecl))
   1.253 +                  {:doc (first fdecl)}
   1.254 +                  {})
   1.255 +              fdecl (if (string? (first fdecl))
   1.256 +                      (next fdecl)
   1.257 +                      fdecl)
   1.258 +              m (if (map? (first fdecl))
   1.259 +                  (conj m (first fdecl))
   1.260 +                  m)
   1.261 +              fdecl (if (map? (first fdecl))
   1.262 +                      (next fdecl)
   1.263 +                      fdecl)
   1.264 +              fdecl (if (vector? (first fdecl))
   1.265 +                      (list fdecl)
   1.266 +                      fdecl)
   1.267 +              m (if (map? (last fdecl))
   1.268 +                  (conj m (last fdecl))
   1.269 +                  m)
   1.270 +              fdecl (if (map? (last fdecl))
   1.271 +                      (butlast fdecl)
   1.272 +                      fdecl)
   1.273 +              m (conj {:arglists (list 'quote (sigs fdecl))} m)
   1.274 +              m (let [inline (:inline m)
   1.275 +                      ifn (first inline)
   1.276 +                      iname (second inline)]
   1.277 +                  ;; same as: (if (and (= 'fn ifn) (not (symbol? iname))) ...)
   1.278 +                  (if (if (clojure.lang.Util/equiv 'fn ifn)
   1.279 +                        (if (instance? clojure.lang.Symbol iname) false true))
   1.280 +                    ;; inserts the same fn name to the inline fn if it does not have one
   1.281 +                    (assoc m :inline (cons ifn (cons (clojure.lang.Symbol/intern (.concat (.getName name) "__inliner"))
   1.282 +                                                     (next inline))))
   1.283 +                    m))
   1.284 +              m (conj (if (meta name) (meta name) {}) m)]
   1.285 +          (list 'def (with-meta name m)
   1.286 +                (list '.withMeta (cons `fn (cons name fdecl)) (list '.meta (list 'var name)))))))
   1.287 +
   1.288 +(. (var defn) (setMacro))
   1.289 +
   1.290 +(defn cast
   1.291 +  "Throws a ClassCastException if x is not a c, else returns x."
   1.292 +  {:added "1.0"}
   1.293 +  [^Class c x] 
   1.294 +  (. c (cast x)))
   1.295 +
   1.296 +(defn to-array
   1.297 +  "Returns an array of Objects containing the contents of coll, which
   1.298 +  can be any Collection.  Maps to java.util.Collection.toArray()."
   1.299 +  {:tag "[Ljava.lang.Object;"
   1.300 +   :added "1.0"}
   1.301 +  [coll] (. clojure.lang.RT (toArray coll)))
   1.302 + 
   1.303 +(defn vector
   1.304 +  "Creates a new vector containing the args."
   1.305 +  {:added "1.0"}
   1.306 +  ([] [])
   1.307 +  ([a] [a])
   1.308 +  ([a b] [a b])
   1.309 +  ([a b c] [a b c])
   1.310 +  ([a b c d] [a b c d])
   1.311 +  ([a b c d & args]
   1.312 +     (. clojure.lang.LazilyPersistentVector (create (cons a (cons b (cons c (cons d args))))))))
   1.313 +
   1.314 +(defn vec
   1.315 +  "Creates a new vector containing the contents of coll."
   1.316 +  {:added "1.0"}
   1.317 +  ([coll]
   1.318 +   (if (instance? java.util.Collection coll)
   1.319 +     (clojure.lang.LazilyPersistentVector/create coll)
   1.320 +     (. clojure.lang.LazilyPersistentVector (createOwning (to-array coll))))))
   1.321 +
   1.322 +(defn hash-map
   1.323 +  "keyval => key val
   1.324 +  Returns a new hash map with supplied mappings."
   1.325 +  {:added "1.0"}
   1.326 +  ([] {})
   1.327 +  ([& keyvals]
   1.328 +   (. clojure.lang.PersistentHashMap (createWithCheck keyvals))))
   1.329 +
   1.330 +(defn hash-set
   1.331 +  "Returns a new hash set with supplied keys."
   1.332 +  {:added "1.0"}
   1.333 +  ([] #{})
   1.334 +  ([& keys]
   1.335 +   (clojure.lang.PersistentHashSet/createWithCheck keys)))
   1.336 +
   1.337 +(defn sorted-map
   1.338 +  "keyval => key val
   1.339 +  Returns a new sorted map with supplied mappings."
   1.340 +  {:added "1.0"}
   1.341 +  ([& keyvals]
   1.342 +   (clojure.lang.PersistentTreeMap/create keyvals)))
   1.343 +
   1.344 +(defn sorted-map-by
   1.345 +  "keyval => key val
   1.346 +  Returns a new sorted map with supplied mappings, using the supplied comparator."
   1.347 +  {:added "1.0"}
   1.348 +  ([comparator & keyvals]
   1.349 +   (clojure.lang.PersistentTreeMap/create comparator keyvals)))
   1.350 +
   1.351 +(defn sorted-set
   1.352 +  "Returns a new sorted set with supplied keys."
   1.353 +  {:added "1.0"}
   1.354 +  ([& keys]
   1.355 +   (clojure.lang.PersistentTreeSet/create keys)))
   1.356 +
   1.357 +(defn sorted-set-by
   1.358 +  "Returns a new sorted set with supplied keys, using the supplied comparator."
   1.359 +  {:added "1.1"} 
   1.360 +  ([comparator & keys]
   1.361 +   (clojure.lang.PersistentTreeSet/create comparator keys)))
   1.362 +
   1.363 + 
   1.364 +;;;;;;;;;;;;;;;;;;;;
   1.365 +(defn nil?
   1.366 +  "Returns true if x is nil, false otherwise."
   1.367 +  {:tag Boolean
   1.368 +   :added "1.0"}
   1.369 +  [x] (clojure.lang.Util/identical x nil))
   1.370 +
   1.371 +(def
   1.372 +
   1.373 + ^{:doc "Like defn, but the resulting function name is declared as a
   1.374 +  macro and will be used as a macro by the compiler when it is
   1.375 +  called."
   1.376 +   :arglists '([name doc-string? attr-map? [params*] body]
   1.377 +                 [name doc-string? attr-map? ([params*] body)+ attr-map?])
   1.378 +   :added "1.0"}
   1.379 + defmacro (fn [&form &env 
   1.380 +                name & args]
   1.381 +             (let [prefix (loop [p (list name) args args]
   1.382 +                            (let [f (first args)]
   1.383 +                              (if (string? f)
   1.384 +                                (recur (cons f p) (next args))
   1.385 +                                (if (map? f)
   1.386 +                                  (recur (cons f p) (next args))
   1.387 +                                  p))))
   1.388 +                   fdecl (loop [fd args]
   1.389 +                           (if (string? (first fd))
   1.390 +                             (recur (next fd))
   1.391 +                             (if (map? (first fd))
   1.392 +                               (recur (next fd))
   1.393 +                               fd)))
   1.394 +                   fdecl (if (vector? (first fdecl))
   1.395 +                           (list fdecl)
   1.396 +                           fdecl)
   1.397 +                   add-implicit-args (fn [fd]
   1.398 +                             (let [args (first fd)]
   1.399 +                               (cons (vec (cons '&form (cons '&env args))) (next fd))))
   1.400 +                   add-args (fn [acc ds]
   1.401 +                              (if (nil? ds)
   1.402 +                                acc
   1.403 +                                (let [d (first ds)]
   1.404 +                                  (if (map? d)
   1.405 +                                    (conj acc d)
   1.406 +                                    (recur (conj acc (add-implicit-args d)) (next ds))))))
   1.407 +                   fdecl (seq (add-args [] fdecl))
   1.408 +                   decl (loop [p prefix d fdecl]
   1.409 +                          (if p
   1.410 +                            (recur (next p) (cons (first p) d))
   1.411 +                            d))]
   1.412 +               (list 'do
   1.413 +                     (cons `defn decl)
   1.414 +                     (list '. (list 'var name) '(setMacro))
   1.415 +                     (list 'var name)))))
   1.416 +
   1.417 +
   1.418 +(. (var defmacro) (setMacro))
   1.419 +
   1.420 +(defmacro when
   1.421 +  "Evaluates test. If logical true, evaluates body in an implicit do."
   1.422 +  {:added "1.0"}
   1.423 +  [test & body]
   1.424 +  (list 'if test (cons 'do body)))
   1.425 +
   1.426 +(defmacro when-not
   1.427 +  "Evaluates test. If logical false, evaluates body in an implicit do."
   1.428 +  {:added "1.0"}
   1.429 +  [test & body]
   1.430 +    (list 'if test nil (cons 'do body)))
   1.431 +
   1.432 +(defn false?
   1.433 +  "Returns true if x is the value false, false otherwise."
   1.434 +  {:tag Boolean,
   1.435 +   :added "1.0"}
   1.436 +  [x] (clojure.lang.Util/identical x false))
   1.437 +
   1.438 +(defn true?
   1.439 +  "Returns true if x is the value true, false otherwise."
   1.440 +  {:tag Boolean,
   1.441 +   :added "1.0"}
   1.442 +  [x] (clojure.lang.Util/identical x true))
   1.443 +
   1.444 +(defn not
   1.445 +  "Returns true if x is logical false, false otherwise."
   1.446 +  {:tag Boolean
   1.447 +   :added "1.0"}
   1.448 +  [x] (if x false true))
   1.449 +
   1.450 +(defn str
   1.451 +  "With no args, returns the empty string. With one arg x, returns
   1.452 +  x.toString().  (str nil) returns the empty string. With more than
   1.453 +  one arg, returns the concatenation of the str values of the args."
   1.454 +  {:tag String
   1.455 +   :added "1.0"}
   1.456 +  ([] "")
   1.457 +  ([^Object x]
   1.458 +   (if (nil? x) "" (. x (toString))))
   1.459 +  ([x & ys]
   1.460 +     ((fn [^StringBuilder sb more]
   1.461 +          (if more
   1.462 +            (recur (. sb  (append (str (first more)))) (next more))
   1.463 +            (str sb)))
   1.464 +      (new StringBuilder ^String (str x)) ys)))
   1.465 +
   1.466 +
   1.467 +(defn symbol?
   1.468 +  "Return true if x is a Symbol"
   1.469 +  {:added "1.0"}
   1.470 +  [x] (instance? clojure.lang.Symbol x))
   1.471 +
   1.472 +(defn keyword?
   1.473 +  "Return true if x is a Keyword"
   1.474 +  {:added "1.0"}
   1.475 +  [x] (instance? clojure.lang.Keyword x))
   1.476 +
   1.477 +(defn symbol
   1.478 +  "Returns a Symbol with the given namespace and name."
   1.479 +  {:tag clojure.lang.Symbol
   1.480 +   :added "1.0"}
   1.481 +  ([name] (if (symbol? name) name (clojure.lang.Symbol/intern name)))
   1.482 +  ([ns name] (clojure.lang.Symbol/intern ns name)))
   1.483 +
   1.484 +(defn gensym
   1.485 +  "Returns a new symbol with a unique name. If a prefix string is
   1.486 +  supplied, the name is prefix# where # is some unique number. If
   1.487 +  prefix is not supplied, the prefix is 'G__'."
   1.488 +  {:added "1.0"}
   1.489 +  ([] (gensym "G__"))
   1.490 +  ([prefix-string] (. clojure.lang.Symbol (intern (str prefix-string (str (. clojure.lang.RT (nextID))))))))
   1.491 +
   1.492 +(defmacro cond
   1.493 +  "Takes a set of test/expr pairs. It evaluates each test one at a
   1.494 +  time.  If a test returns logical true, cond evaluates and returns
   1.495 +  the value of the corresponding expr and doesn't evaluate any of the
   1.496 +  other tests or exprs. (cond) returns nil."
   1.497 +  {:added "1.0"}
   1.498 +  [& clauses]
   1.499 +    (when clauses
   1.500 +      (list 'if (first clauses)
   1.501 +            (if (next clauses)
   1.502 +                (second clauses)
   1.503 +                (throw (IllegalArgumentException.
   1.504 +                         "cond requires an even number of forms")))
   1.505 +            (cons 'clojure.core/cond (next (next clauses))))))
   1.506 +
   1.507 +(defn keyword
   1.508 +  "Returns a Keyword with the given namespace and name.  Do not use :
   1.509 +  in the keyword strings, it will be added automatically."
   1.510 +  {:tag clojure.lang.Keyword
   1.511 +   :added "1.0"}
   1.512 +  ([name] (cond (keyword? name) name
   1.513 +                (symbol? name) (clojure.lang.Keyword/intern ^clojure.lang.Symbol name)
   1.514 +                (string? name) (clojure.lang.Keyword/intern ^String name)))
   1.515 +  ([ns name] (clojure.lang.Keyword/intern ns name)))
   1.516 +
   1.517 +(defn spread
   1.518 +  {:private true}
   1.519 +  [arglist]
   1.520 +  (cond
   1.521 +   (nil? arglist) nil
   1.522 +   (nil? (next arglist)) (seq (first arglist))
   1.523 +   :else (cons (first arglist) (spread (next arglist)))))
   1.524 +
   1.525 +(defn list*
   1.526 +  "Creates a new list containing the items prepended to the rest, the
   1.527 +  last of which will be treated as a sequence."
   1.528 +  {:added "1.0"}
   1.529 +  ([args] (seq args))
   1.530 +  ([a args] (cons a args))
   1.531 +  ([a b args] (cons a (cons b args)))
   1.532 +  ([a b c args] (cons a (cons b (cons c args))))
   1.533 +  ([a b c d & more]
   1.534 +     (cons a (cons b (cons c (cons d (spread more)))))))
   1.535 +
   1.536 +(defn apply
   1.537 +  "Applies fn f to the argument list formed by prepending args to argseq."
   1.538 +  {:arglists '([f args* argseq])
   1.539 +   :added "1.0"}
   1.540 +  ([^clojure.lang.IFn f args]
   1.541 +     (. f (applyTo (seq args))))
   1.542 +  ([^clojure.lang.IFn f x args]
   1.543 +     (. f (applyTo (list* x args))))
   1.544 +  ([^clojure.lang.IFn f x y args]
   1.545 +     (. f (applyTo (list* x y args))))
   1.546 +  ([^clojure.lang.IFn f x y z args]
   1.547 +     (. f (applyTo (list* x y z args))))
   1.548 +  ([^clojure.lang.IFn f a b c d & args]
   1.549 +     (. f (applyTo (cons a (cons b (cons c (cons d (spread args)))))))))
   1.550 +
   1.551 +(defn vary-meta
   1.552 + "Returns an object of the same type and value as obj, with
   1.553 +  (apply f (meta obj) args) as its metadata."
   1.554 + {:added "1.0"}
   1.555 + [obj f & args]
   1.556 +  (with-meta obj (apply f (meta obj) args)))
   1.557 +
   1.558 +(defmacro lazy-seq
   1.559 +  "Takes a body of expressions that returns an ISeq or nil, and yields
   1.560 +  a Seqable object that will invoke the body only the first time seq
   1.561 +  is called, and will cache the result and return it on all subsequent
   1.562 +  seq calls."
   1.563 +  {:added "1.0"}
   1.564 +  [& body]
   1.565 +  (list 'new 'clojure.lang.LazySeq (list* '^{:once true} fn* [] body)))    
   1.566 +
   1.567 +(defn ^clojure.lang.ChunkBuffer chunk-buffer [capacity]
   1.568 +  (clojure.lang.ChunkBuffer. capacity))
   1.569 +
   1.570 +(defn chunk-append [^clojure.lang.ChunkBuffer b x]
   1.571 +  (.add b x))
   1.572 +
   1.573 +(defn chunk [^clojure.lang.ChunkBuffer b]
   1.574 +  (.chunk b))
   1.575 +
   1.576 +(defn ^clojure.lang.IChunk chunk-first [^clojure.lang.IChunkedSeq s]
   1.577 +  (.chunkedFirst s))
   1.578 +
   1.579 +(defn ^clojure.lang.ISeq chunk-rest [^clojure.lang.IChunkedSeq s]
   1.580 +  (.chunkedMore s))
   1.581 +
   1.582 +(defn ^clojure.lang.ISeq chunk-next [^clojure.lang.IChunkedSeq s]
   1.583 +  (.chunkedNext s))
   1.584 +
   1.585 +(defn chunk-cons [chunk rest]
   1.586 +  (if (clojure.lang.Numbers/isZero (clojure.lang.RT/count chunk))
   1.587 +    rest
   1.588 +    (clojure.lang.ChunkedCons. chunk rest)))
   1.589 +  
   1.590 +(defn chunked-seq? [s]
   1.591 +  (instance? clojure.lang.IChunkedSeq s))
   1.592 +
   1.593 +(defn concat
   1.594 +  "Returns a lazy seq representing the concatenation of the elements in the supplied colls."
   1.595 +  {:added "1.0"}
   1.596 +  ([] (lazy-seq nil))
   1.597 +  ([x] (lazy-seq x))
   1.598 +  ([x y]
   1.599 +    (lazy-seq
   1.600 +      (let [s (seq x)]
   1.601 +        (if s
   1.602 +          (if (chunked-seq? s)
   1.603 +            (chunk-cons (chunk-first s) (concat (chunk-rest s) y))
   1.604 +            (cons (first s) (concat (rest s) y)))
   1.605 +          y))))
   1.606 +  ([x y & zs]
   1.607 +     (let [cat (fn cat [xys zs]
   1.608 +                 (lazy-seq
   1.609 +                   (let [xys (seq xys)]
   1.610 +                     (if xys
   1.611 +                       (if (chunked-seq? xys)
   1.612 +                         (chunk-cons (chunk-first xys)
   1.613 +                                     (cat (chunk-rest xys) zs))
   1.614 +                         (cons (first xys) (cat (rest xys) zs)))
   1.615 +                       (when zs
   1.616 +                         (cat (first zs) (next zs)))))))]
   1.617 +       (cat (concat x y) zs))))
   1.618 +
   1.619 +;;;;;;;;;;;;;;;;at this point all the support for syntax-quote exists;;;;;;;;;;;;;;;;;;;;;;
   1.620 +(defmacro delay
   1.621 +  "Takes a body of expressions and yields a Delay object that will
   1.622 +  invoke the body only the first time it is forced (with force or deref/@), and
   1.623 +  will cache the result and return it on all subsequent force
   1.624 +  calls."
   1.625 +  {:added "1.0"}
   1.626 +  [& body]
   1.627 +    (list 'new 'clojure.lang.Delay (list* `^{:once true} fn* [] body)))
   1.628 +
   1.629 +(defn delay?
   1.630 +  "returns true if x is a Delay created with delay"
   1.631 +  {:added "1.0"}
   1.632 +  [x] (instance? clojure.lang.Delay x))
   1.633 +
   1.634 +(defn force
   1.635 +  "If x is a Delay, returns the (possibly cached) value of its expression, else returns x"
   1.636 +  {:added "1.0"}
   1.637 +  [x] (. clojure.lang.Delay (force x)))
   1.638 +
   1.639 +(defmacro if-not
   1.640 +  "Evaluates test. If logical false, evaluates and returns then expr, 
   1.641 +  otherwise else expr, if supplied, else nil."
   1.642 +  {:added "1.0"}
   1.643 +  ([test then] `(if-not ~test ~then nil))
   1.644 +  ([test then else]
   1.645 +   `(if (not ~test) ~then ~else)))
   1.646 +
   1.647 +(defn identical?
   1.648 +  "Tests if 2 arguments are the same object"
   1.649 +  {:inline (fn [x y] `(. clojure.lang.Util identical ~x ~y))
   1.650 +   :inline-arities #{2}
   1.651 +   :added "1.0"}
   1.652 +  ([x y] (clojure.lang.Util/identical x y)))
   1.653 +
   1.654 +(defn =
   1.655 +  "Equality. Returns true if x equals y, false if not. Same as
   1.656 +  Java x.equals(y) except it also works for nil, and compares
   1.657 +  numbers and collections in a type-independent manner.  Clojure's immutable data
   1.658 +  structures define equals() (and thus =) as a value, not an identity,
   1.659 +  comparison."
   1.660 +  {:inline (fn [x y] `(. clojure.lang.Util equiv ~x ~y))
   1.661 +   :inline-arities #{2}
   1.662 +   :added "1.0"}
   1.663 +  ([x] true)
   1.664 +  ([x y] (clojure.lang.Util/equiv x y))
   1.665 +  ([x y & more]
   1.666 +   (if (= x y)
   1.667 +     (if (next more)
   1.668 +       (recur y (first more) (next more))
   1.669 +       (= y (first more)))
   1.670 +     false)))
   1.671 +
   1.672 +(defn not=
   1.673 +  "Same as (not (= obj1 obj2))"
   1.674 +  {:tag Boolean
   1.675 +   :added "1.0"}
   1.676 +  ([x] false)
   1.677 +  ([x y] (not (= x y)))
   1.678 +  ([x y & more]
   1.679 +   (not (apply = x y more))))
   1.680 +
   1.681 +
   1.682 +
   1.683 +(defn compare
   1.684 +  "Comparator. Returns a negative number, zero, or a positive number
   1.685 +  when x is logically 'less than', 'equal to', or 'greater than'
   1.686 +  y. Same as Java x.compareTo(y) except it also works for nil, and
   1.687 +  compares numbers and collections in a type-independent manner. x
   1.688 +  must implement Comparable"
   1.689 +  {
   1.690 +   :inline (fn [x y] `(. clojure.lang.Util compare ~x ~y))
   1.691 +   :added "1.0"}
   1.692 +  [x y] (. clojure.lang.Util (compare x y)))
   1.693 +
   1.694 +(defmacro and
   1.695 +  "Evaluates exprs one at a time, from left to right. If a form
   1.696 +  returns logical false (nil or false), and returns that value and
   1.697 +  doesn't evaluate any of the other expressions, otherwise it returns
   1.698 +  the value of the last expr. (and) returns true."
   1.699 +  {:added "1.0"}
   1.700 +  ([] true)
   1.701 +  ([x] x)
   1.702 +  ([x & next]
   1.703 +   `(let [and# ~x]
   1.704 +      (if and# (and ~@next) and#))))
   1.705 +
   1.706 +(defmacro or
   1.707 +  "Evaluates exprs one at a time, from left to right. If a form
   1.708 +  returns a logical true value, or returns that value and doesn't
   1.709 +  evaluate any of the other expressions, otherwise it returns the
   1.710 +  value of the last expression. (or) returns nil."
   1.711 +  {:added "1.0"}
   1.712 +  ([] nil)
   1.713 +  ([x] x)
   1.714 +  ([x & next]
   1.715 +      `(let [or# ~x]
   1.716 +         (if or# or# (or ~@next)))))
   1.717 +
   1.718 +;;;;;;;;;;;;;;;;;;; sequence fns  ;;;;;;;;;;;;;;;;;;;;;;;
   1.719 +(defn zero?
   1.720 +  "Returns true if num is zero, else false"
   1.721 +  {
   1.722 +   :inline (fn [x] `(. clojure.lang.Numbers (isZero ~x)))
   1.723 +   :added "1.0"}
   1.724 +  [x] (. clojure.lang.Numbers (isZero x)))
   1.725 +
   1.726 +(defn count
   1.727 +  "Returns the number of items in the collection. (count nil) returns
   1.728 +  0.  Also works on strings, arrays, and Java Collections and Maps"
   1.729 +  {
   1.730 +   :inline (fn  [x] `(. clojure.lang.RT (count ~x)))
   1.731 +   :added "1.0"}
   1.732 +  [coll] (clojure.lang.RT/count coll))
   1.733 +
   1.734 +(defn int
   1.735 +  "Coerce to int"
   1.736 +  {
   1.737 +   :inline (fn  [x] `(. clojure.lang.RT (intCast ~x)))
   1.738 +   :added "1.0"}
   1.739 +  [x] (. clojure.lang.RT (intCast x)))
   1.740 +
   1.741 +(defn nth
   1.742 +  "Returns the value at the index. get returns nil if index out of
   1.743 +  bounds, nth throws an exception unless not-found is supplied.  nth
   1.744 +  also works for strings, Java arrays, regex Matchers and Lists, and,
   1.745 +  in O(n) time, for sequences."
   1.746 +  {:inline (fn  [c i & nf] `(. clojure.lang.RT (nth ~c ~i ~@nf)))
   1.747 +   :inline-arities #{2 3}
   1.748 +   :added "1.0"}
   1.749 +  ([coll index] (. clojure.lang.RT (nth coll index)))
   1.750 +  ([coll index not-found] (. clojure.lang.RT (nth coll index not-found))))
   1.751 +
   1.752 +(defn <
   1.753 +  "Returns non-nil if nums are in monotonically increasing order,
   1.754 +  otherwise false."
   1.755 +  {:inline (fn [x y] `(. clojure.lang.Numbers (lt ~x ~y)))
   1.756 +   :inline-arities #{2}
   1.757 +   :added "1.0"}
   1.758 +  ([x] true)
   1.759 +  ([x y] (. clojure.lang.Numbers (lt x y)))
   1.760 +  ([x y & more]
   1.761 +   (if (< x y)
   1.762 +     (if (next more)
   1.763 +       (recur y (first more) (next more))
   1.764 +       (< y (first more)))
   1.765 +     false)))
   1.766 +
   1.767 +(defn inc
   1.768 +  "Returns a number one greater than num."
   1.769 +  {:inline (fn [x] `(. clojure.lang.Numbers (inc ~x)))
   1.770 +   :added "1.0"}
   1.771 +  [x] (. clojure.lang.Numbers (inc x)))
   1.772 +
   1.773 +;; reduce is defined again later after InternalReduce loads
   1.774 +(def
   1.775 +    ^{:arglists '([f coll] [f val coll])
   1.776 +      :doc "f should be a function of 2 arguments. If val is not supplied,
   1.777 +  returns the result of applying f to the first 2 items in coll, then
   1.778 +  applying f to that result and the 3rd item, etc. If coll contains no
   1.779 +  items, f must accept no arguments as well, and reduce returns the
   1.780 +  result of calling f with no arguments.  If coll has only 1 item, it
   1.781 +  is returned and f is not called.  If val is supplied, returns the
   1.782 +  result of applying f to val and the first item in coll, then
   1.783 +  applying f to that result and the 2nd item, etc. If coll contains no
   1.784 +  items, returns val and f is not called."
   1.785 +      :added "1.0"}    
   1.786 +    reduce
   1.787 +     (fn r
   1.788 +       ([f coll]
   1.789 +             (let [s (seq coll)]
   1.790 +               (if s
   1.791 +                 (r f (first s) (next s))
   1.792 +                 (f))))
   1.793 +       ([f val coll]
   1.794 +          (let [s (seq coll)]
   1.795 +            (if s
   1.796 +              (if (chunked-seq? s)
   1.797 +                (recur f 
   1.798 +                       (.reduce (chunk-first s) f val)
   1.799 +                       (chunk-next s))
   1.800 +                (recur f (f val (first s)) (next s)))
   1.801 +              val)))))
   1.802 +
   1.803 +(defn reverse
   1.804 +  "Returns a seq of the items in coll in reverse order. Not lazy."
   1.805 +  {:added "1.0"}
   1.806 +  [coll]
   1.807 +    (reduce conj () coll))
   1.808 +
   1.809 +;;math stuff
   1.810 +(defn +
   1.811 +  "Returns the sum of nums. (+) returns 0."
   1.812 +  {:inline (fn [x y] `(. clojure.lang.Numbers (add ~x ~y)))
   1.813 +   :inline-arities #{2}
   1.814 +   :added "1.0"}
   1.815 +  ([] 0)
   1.816 +  ([x] (cast Number x))
   1.817 +  ([x y] (. clojure.lang.Numbers (add x y)))
   1.818 +  ([x y & more]
   1.819 +   (reduce + (+ x y) more)))
   1.820 +
   1.821 +(defn *
   1.822 +  "Returns the product of nums. (*) returns 1."
   1.823 +  {:inline (fn [x y] `(. clojure.lang.Numbers (multiply ~x ~y)))
   1.824 +   :inline-arities #{2}
   1.825 +   :added "1.0"}
   1.826 +  ([] 1)
   1.827 +  ([x] (cast Number x))
   1.828 +  ([x y] (. clojure.lang.Numbers (multiply x y)))
   1.829 +  ([x y & more]
   1.830 +   (reduce * (* x y) more)))
   1.831 +
   1.832 +(defn /
   1.833 +  "If no denominators are supplied, returns 1/numerator,
   1.834 +  else returns numerator divided by all of the denominators."
   1.835 +  {:inline (fn [x y] `(. clojure.lang.Numbers (divide ~x ~y)))
   1.836 +   :inline-arities #{2}
   1.837 +   :added "1.0"}
   1.838 +  ([x] (/ 1 x))
   1.839 +  ([x y] (. clojure.lang.Numbers (divide x y)))
   1.840 +  ([x y & more]
   1.841 +   (reduce / (/ x y) more)))
   1.842 +
   1.843 +(defn -
   1.844 +  "If no ys are supplied, returns the negation of x, else subtracts
   1.845 +  the ys from x and returns the result."
   1.846 +  {:inline (fn [& args] `(. clojure.lang.Numbers (minus ~@args)))
   1.847 +   :inline-arities #{1 2}
   1.848 +   :added "1.0"}
   1.849 +  ([x] (. clojure.lang.Numbers (minus x)))
   1.850 +  ([x y] (. clojure.lang.Numbers (minus x y)))
   1.851 +  ([x y & more]
   1.852 +   (reduce - (- x y) more)))
   1.853 +
   1.854 +(defn <=
   1.855 +  "Returns non-nil if nums are in monotonically non-decreasing order,
   1.856 +  otherwise false."
   1.857 +  {:inline (fn [x y] `(. clojure.lang.Numbers (lte ~x ~y)))
   1.858 +   :inline-arities #{2}
   1.859 +   :added "1.0"}
   1.860 +  ([x] true)
   1.861 +  ([x y] (. clojure.lang.Numbers (lte x y)))
   1.862 +  ([x y & more]
   1.863 +   (if (<= x y)
   1.864 +     (if (next more)
   1.865 +       (recur y (first more) (next more))
   1.866 +       (<= y (first more)))
   1.867 +     false)))
   1.868 +
   1.869 +(defn >
   1.870 +  "Returns non-nil if nums are in monotonically decreasing order,
   1.871 +  otherwise false."
   1.872 +  {:inline (fn [x y] `(. clojure.lang.Numbers (gt ~x ~y)))
   1.873 +   :inline-arities #{2}
   1.874 +   :added "1.0"}
   1.875 +  ([x] true)
   1.876 +  ([x y] (. clojure.lang.Numbers (gt x y)))
   1.877 +  ([x y & more]
   1.878 +   (if (> x y)
   1.879 +     (if (next more)
   1.880 +       (recur y (first more) (next more))
   1.881 +       (> y (first more)))
   1.882 +     false)))
   1.883 +
   1.884 +(defn >=
   1.885 +  "Returns non-nil if nums are in monotonically non-increasing order,
   1.886 +  otherwise false."
   1.887 +  {:inline (fn [x y] `(. clojure.lang.Numbers (gte ~x ~y)))
   1.888 +   :inline-arities #{2}
   1.889 +   :added "1.0"}
   1.890 +  ([x] true)
   1.891 +  ([x y] (. clojure.lang.Numbers (gte x y)))
   1.892 +  ([x y & more]
   1.893 +   (if (>= x y)
   1.894 +     (if (next more)
   1.895 +       (recur y (first more) (next more))
   1.896 +       (>= y (first more)))
   1.897 +     false)))
   1.898 +
   1.899 +(defn ==
   1.900 +  "Returns non-nil if nums all have the same value, otherwise false"
   1.901 +  {:inline (fn [x y] `(. clojure.lang.Numbers (equiv ~x ~y)))
   1.902 +   :inline-arities #{2}
   1.903 +   :added "1.0"}
   1.904 +  ([x] true)
   1.905 +  ([x y] (. clojure.lang.Numbers (equiv x y)))
   1.906 +  ([x y & more]
   1.907 +   (if (== x y)
   1.908 +     (if (next more)
   1.909 +       (recur y (first more) (next more))
   1.910 +       (== y (first more)))
   1.911 +     false)))
   1.912 +
   1.913 +(defn max
   1.914 +  "Returns the greatest of the nums."
   1.915 +  {:added "1.0"}
   1.916 +  ([x] x)
   1.917 +  ([x y] (if (> x y) x y))
   1.918 +  ([x y & more]
   1.919 +   (reduce max (max x y) more)))
   1.920 +
   1.921 +(defn min
   1.922 +  "Returns the least of the nums."
   1.923 +  {:added "1.0"}
   1.924 +  ([x] x)
   1.925 +  ([x y] (if (< x y) x y))
   1.926 +  ([x y & more]
   1.927 +   (reduce min (min x y) more)))
   1.928 +
   1.929 +(defn dec
   1.930 +  "Returns a number one less than num."
   1.931 +  {:inline (fn [x] `(. clojure.lang.Numbers (dec ~x)))
   1.932 +   :added "1.0"}
   1.933 +  [x] (. clojure.lang.Numbers (dec x)))
   1.934 +
   1.935 +(defn unchecked-inc
   1.936 +  "Returns a number one greater than x, an int or long.
   1.937 +  Note - uses a primitive operator subject to overflow."
   1.938 +  {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_inc ~x)))
   1.939 +   :added "1.0"}
   1.940 +  [x] (. clojure.lang.Numbers (unchecked_inc x)))
   1.941 +
   1.942 +(defn unchecked-dec
   1.943 +  "Returns a number one less than x, an int or long.
   1.944 +  Note - uses a primitive operator subject to overflow."
   1.945 +  {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_dec ~x)))
   1.946 +   :added "1.0"}
   1.947 +  [x] (. clojure.lang.Numbers (unchecked_dec x)))
   1.948 +
   1.949 +(defn unchecked-negate
   1.950 +  "Returns the negation of x, an int or long.
   1.951 +  Note - uses a primitive operator subject to overflow."
   1.952 +  {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_negate ~x)))
   1.953 +   :added "1.0"}
   1.954 +  [x] (. clojure.lang.Numbers (unchecked_negate x)))
   1.955 +
   1.956 +(defn unchecked-add
   1.957 +  "Returns the sum of x and y, both int or long.
   1.958 +  Note - uses a primitive operator subject to overflow."
   1.959 +  {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_add ~x ~y)))
   1.960 +   :added "1.0"}
   1.961 +  [x y] (. clojure.lang.Numbers (unchecked_add x y)))
   1.962 +
   1.963 +(defn unchecked-subtract
   1.964 +  "Returns the difference of x and y, both int or long.
   1.965 +  Note - uses a primitive operator subject to overflow."
   1.966 +  {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_subtract ~x ~y)))
   1.967 +   :added "1.0"}
   1.968 +  [x y] (. clojure.lang.Numbers (unchecked_subtract x y)))
   1.969 +
   1.970 +(defn unchecked-multiply
   1.971 +  "Returns the product of x and y, both int or long.
   1.972 +  Note - uses a primitive operator subject to overflow."
   1.973 +  {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_multiply ~x ~y)))
   1.974 +   :added "1.0"}
   1.975 +  [x y] (. clojure.lang.Numbers (unchecked_multiply x y)))
   1.976 +
   1.977 +(defn unchecked-divide
   1.978 +  "Returns the division of x by y, both int or long.
   1.979 +  Note - uses a primitive operator subject to truncation."
   1.980 +  {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_divide ~x ~y)))
   1.981 +   :added "1.0"}
   1.982 +  [x y] (. clojure.lang.Numbers (unchecked_divide x y)))
   1.983 +
   1.984 +(defn unchecked-remainder
   1.985 +  "Returns the remainder of division of x by y, both int or long.
   1.986 +  Note - uses a primitive operator subject to truncation."
   1.987 +  {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_remainder ~x ~y)))
   1.988 +   :added "1.0"}
   1.989 +  [x y] (. clojure.lang.Numbers (unchecked_remainder x y)))
   1.990 +
   1.991 +(defn pos?
   1.992 +  "Returns true if num is greater than zero, else false"
   1.993 +  {
   1.994 +   :inline (fn [x] `(. clojure.lang.Numbers (isPos ~x)))
   1.995 +   :added "1.0"}
   1.996 +  [x] (. clojure.lang.Numbers (isPos x)))
   1.997 +
   1.998 +(defn neg?
   1.999 +  "Returns true if num is less than zero, else false"
  1.1000 +  {
  1.1001 +   :inline (fn [x] `(. clojure.lang.Numbers (isNeg ~x)))
  1.1002 +   :added "1.0"}
  1.1003 +  [x] (. clojure.lang.Numbers (isNeg x)))
  1.1004 +
  1.1005 +(defn quot
  1.1006 +  "quot[ient] of dividing numerator by denominator."
  1.1007 +  {:added "1.0"}
  1.1008 +  [num div]
  1.1009 +    (. clojure.lang.Numbers (quotient num div)))
  1.1010 +
  1.1011 +(defn rem
  1.1012 +  "remainder of dividing numerator by denominator."
  1.1013 +  {:added "1.0"}
  1.1014 +  [num div]
  1.1015 +    (. clojure.lang.Numbers (remainder num div)))
  1.1016 +
  1.1017 +(defn rationalize
  1.1018 +  "returns the rational value of num"
  1.1019 +  {:added "1.0"}
  1.1020 +  [num]
  1.1021 +  (. clojure.lang.Numbers (rationalize num)))
  1.1022 +
  1.1023 +;;Bit ops
  1.1024 +
  1.1025 +(defn bit-not
  1.1026 +  "Bitwise complement"
  1.1027 +  {:inline (fn [x] `(. clojure.lang.Numbers (not ~x)))
  1.1028 +   :added "1.0"}
  1.1029 +  [x] (. clojure.lang.Numbers not x))
  1.1030 +
  1.1031 +
  1.1032 +(defn bit-and
  1.1033 +  "Bitwise and"
  1.1034 +   {:inline (fn [x y] `(. clojure.lang.Numbers (and ~x ~y)))
  1.1035 +    :added "1.0"}
  1.1036 +  [x y] (. clojure.lang.Numbers and x y))
  1.1037 +
  1.1038 +(defn bit-or
  1.1039 +  "Bitwise or"
  1.1040 +  {:inline (fn [x y] `(. clojure.lang.Numbers (or ~x ~y)))
  1.1041 +   :added "1.0"}
  1.1042 +  [x y] (. clojure.lang.Numbers or x y))
  1.1043 +
  1.1044 +(defn bit-xor
  1.1045 +  "Bitwise exclusive or"
  1.1046 +  {:inline (fn [x y] `(. clojure.lang.Numbers (xor ~x ~y)))
  1.1047 +   :added "1.0"}
  1.1048 +  [x y] (. clojure.lang.Numbers xor x y))
  1.1049 +
  1.1050 +(defn bit-and-not
  1.1051 +  "Bitwise and with complement"
  1.1052 +  {:added "1.0"}
  1.1053 +  [x y] (. clojure.lang.Numbers andNot x y))
  1.1054 +
  1.1055 +
  1.1056 +(defn bit-clear
  1.1057 +  "Clear bit at index n"
  1.1058 +  {:added "1.0"}
  1.1059 +  [x n] (. clojure.lang.Numbers clearBit x n))
  1.1060 +
  1.1061 +(defn bit-set
  1.1062 +  "Set bit at index n"
  1.1063 +  {:added "1.0"}
  1.1064 +  [x n] (. clojure.lang.Numbers setBit x n))
  1.1065 +
  1.1066 +(defn bit-flip
  1.1067 +  "Flip bit at index n"
  1.1068 +  {:added "1.0"}
  1.1069 +  [x n] (. clojure.lang.Numbers flipBit x n))
  1.1070 +
  1.1071 +(defn bit-test
  1.1072 +  "Test bit at index n"
  1.1073 +  {:added "1.0"}
  1.1074 +  [x n] (. clojure.lang.Numbers testBit x n))
  1.1075 +
  1.1076 +
  1.1077 +(defn bit-shift-left
  1.1078 +  "Bitwise shift left"
  1.1079 +  {:inline (fn [x n] `(. clojure.lang.Numbers (shiftLeft ~x ~n)))
  1.1080 +   :added "1.0"}
  1.1081 +  [x n] (. clojure.lang.Numbers shiftLeft x n))
  1.1082 +
  1.1083 +(defn bit-shift-right
  1.1084 +  "Bitwise shift right"
  1.1085 +  {:inline (fn [x n] `(. clojure.lang.Numbers (shiftRight ~x ~n)))
  1.1086 +   :added "1.0"}
  1.1087 +  [x n] (. clojure.lang.Numbers shiftRight x n))
  1.1088 +
  1.1089 +(defn even?
  1.1090 +  "Returns true if n is even, throws an exception if n is not an integer"
  1.1091 +  {:added "1.0"}
  1.1092 +  [n] (zero? (bit-and n 1)))
  1.1093 +
  1.1094 +(defn odd?
  1.1095 +  "Returns true if n is odd, throws an exception if n is not an integer"
  1.1096 +  {:added "1.0"}
  1.1097 +  [n] (not (even? n)))
  1.1098 +
  1.1099 +
  1.1100 +;;
  1.1101 +
  1.1102 +(defn complement
  1.1103 +  "Takes a fn f and returns a fn that takes the same arguments as f,
  1.1104 +  has the same effects, if any, and returns the opposite truth value."
  1.1105 +  {:added "1.0"}
  1.1106 +  [f] 
  1.1107 +  (fn 
  1.1108 +    ([] (not (f)))
  1.1109 +    ([x] (not (f x)))
  1.1110 +    ([x y] (not (f x y)))
  1.1111 +    ([x y & zs] (not (apply f x y zs)))))
  1.1112 +
  1.1113 +(defn constantly
  1.1114 +  "Returns a function that takes any number of arguments and returns x."
  1.1115 +  {:added "1.0"}
  1.1116 +  [x] (fn [& args] x))
  1.1117 +
  1.1118 +(defn identity
  1.1119 +  "Returns its argument."
  1.1120 +  {:added "1.0"}
  1.1121 +  [x] x)
  1.1122 +
  1.1123 +;;Collection stuff
  1.1124 +
  1.1125 +
  1.1126 +
  1.1127 +
  1.1128 +
  1.1129 +;;list stuff
  1.1130 +(defn peek
  1.1131 +  "For a list or queue, same as first, for a vector, same as, but much
  1.1132 +  more efficient than, last. If the collection is empty, returns nil."
  1.1133 +  {:added "1.0"}
  1.1134 +  [coll] (. clojure.lang.RT (peek coll)))
  1.1135 +
  1.1136 +(defn pop
  1.1137 +  "For a list or queue, returns a new list/queue without the first
  1.1138 +  item, for a vector, returns a new vector without the last item. If
  1.1139 +  the collection is empty, throws an exception.  Note - not the same
  1.1140 +  as next/butlast."
  1.1141 +  {:added "1.0"}
  1.1142 +  [coll] (. clojure.lang.RT (pop coll)))
  1.1143 +
  1.1144 +;;map stuff
  1.1145 +
  1.1146 +(defn contains?
  1.1147 +  "Returns true if key is present in the given collection, otherwise
  1.1148 +  returns false.  Note that for numerically indexed collections like
  1.1149 +  vectors and Java arrays, this tests if the numeric key is within the
  1.1150 +  range of indexes. 'contains?' operates constant or logarithmic time;
  1.1151 +  it will not perform a linear search for a value.  See also 'some'."
  1.1152 +  {:added "1.0"}
  1.1153 +  [coll key] (. clojure.lang.RT (contains coll key)))
  1.1154 +
  1.1155 +(defn get
  1.1156 +  "Returns the value mapped to key, not-found or nil if key not present."
  1.1157 +  {:inline (fn  [m k & nf] `(. clojure.lang.RT (get ~m ~k ~@nf)))
  1.1158 +   :inline-arities #{2 3}
  1.1159 +   :added "1.0"}
  1.1160 +  ([map key]
  1.1161 +   (. clojure.lang.RT (get map key)))
  1.1162 +  ([map key not-found]
  1.1163 +   (. clojure.lang.RT (get map key not-found))))
  1.1164 +
  1.1165 +(defn dissoc
  1.1166 +  "dissoc[iate]. Returns a new map of the same (hashed/sorted) type,
  1.1167 +  that does not contain a mapping for key(s)."
  1.1168 +  {:added "1.0"}
  1.1169 +  ([map] map)
  1.1170 +  ([map key]
  1.1171 +   (. clojure.lang.RT (dissoc map key)))
  1.1172 +  ([map key & ks]
  1.1173 +   (let [ret (dissoc map key)]
  1.1174 +     (if ks
  1.1175 +       (recur ret (first ks) (next ks))
  1.1176 +       ret))))
  1.1177 +
  1.1178 +(defn disj
  1.1179 +  "disj[oin]. Returns a new set of the same (hashed/sorted) type, that
  1.1180 +  does not contain key(s)."
  1.1181 +  {:added "1.0"}
  1.1182 +  ([set] set)
  1.1183 +  ([^clojure.lang.IPersistentSet set key]
  1.1184 +   (when set
  1.1185 +     (. set (disjoin key))))
  1.1186 +  ([set key & ks]
  1.1187 +   (when set
  1.1188 +     (let [ret (disj set key)]
  1.1189 +       (if ks
  1.1190 +         (recur ret (first ks) (next ks))
  1.1191 +         ret)))))
  1.1192 +
  1.1193 +(defn find
  1.1194 +  "Returns the map entry for key, or nil if key not present."
  1.1195 +  {:added "1.0"}
  1.1196 +  [map key] (. clojure.lang.RT (find map key)))
  1.1197 +
  1.1198 +(defn select-keys
  1.1199 +  "Returns a map containing only those entries in map whose key is in keys"
  1.1200 +  {:added "1.0"}
  1.1201 +  [map keyseq]
  1.1202 +    (loop [ret {} keys (seq keyseq)]
  1.1203 +      (if keys
  1.1204 +        (let [entry (. clojure.lang.RT (find map (first keys)))]
  1.1205 +          (recur
  1.1206 +           (if entry
  1.1207 +             (conj ret entry)
  1.1208 +             ret)
  1.1209 +           (next keys)))
  1.1210 +        ret)))
  1.1211 +
  1.1212 +(defn keys
  1.1213 +  "Returns a sequence of the map's keys."
  1.1214 +  {:added "1.0"}
  1.1215 +  [map] (. clojure.lang.RT (keys map)))
  1.1216 +
  1.1217 +(defn vals
  1.1218 +  "Returns a sequence of the map's values."
  1.1219 +  {:added "1.0"}
  1.1220 +  [map] (. clojure.lang.RT (vals map)))
  1.1221 +
  1.1222 +(defn key
  1.1223 +  "Returns the key of the map entry."
  1.1224 +  {:added "1.0"}
  1.1225 +  [^java.util.Map$Entry e]
  1.1226 +    (. e (getKey)))
  1.1227 +
  1.1228 +(defn val
  1.1229 +  "Returns the value in the map entry."
  1.1230 +  {:added "1.0"}
  1.1231 +  [^java.util.Map$Entry e]
  1.1232 +    (. e (getValue)))
  1.1233 +
  1.1234 +(defn rseq
  1.1235 +  "Returns, in constant time, a seq of the items in rev (which
  1.1236 +  can be a vector or sorted-map), in reverse order. If rev is empty returns nil"
  1.1237 +  {:added "1.0"}
  1.1238 +  [^clojure.lang.Reversible rev]
  1.1239 +    (. rev (rseq)))
  1.1240 +
  1.1241 +(defn name
  1.1242 +  "Returns the name String of a string, symbol or keyword."
  1.1243 +  {:tag String
  1.1244 +   :added "1.0"}
  1.1245 +  [^clojure.lang.Named x]
  1.1246 +  (if (string? x) x (. x (getName))))
  1.1247 +
  1.1248 +(defn namespace
  1.1249 +  "Returns the namespace String of a symbol or keyword, or nil if not present."
  1.1250 +  {:tag String
  1.1251 +   :added "1.0"}
  1.1252 +  [^clojure.lang.Named x]
  1.1253 +    (. x (getNamespace)))
  1.1254 +
  1.1255 +(defmacro locking
  1.1256 +  "Executes exprs in an implicit do, while holding the monitor of x.
  1.1257 +  Will release the monitor of x in all circumstances."
  1.1258 +  {:added "1.0"}
  1.1259 +  [x & body]
  1.1260 +  `(let [lockee# ~x]
  1.1261 +     (try
  1.1262 +      (monitor-enter lockee#)
  1.1263 +      ~@body
  1.1264 +      (finally
  1.1265 +       (monitor-exit lockee#)))))
  1.1266 +
  1.1267 +(defmacro ..
  1.1268 +  "form => fieldName-symbol or (instanceMethodName-symbol args*)
  1.1269 +
  1.1270 +  Expands into a member access (.) of the first member on the first
  1.1271 +  argument, followed by the next member on the result, etc. For
  1.1272 +  instance:
  1.1273 +
  1.1274 +  (.. System (getProperties) (get \"os.name\"))
  1.1275 +
  1.1276 +  expands to:
  1.1277 +
  1.1278 +  (. (. System (getProperties)) (get \"os.name\"))
  1.1279 +
  1.1280 +  but is easier to write, read, and understand."
  1.1281 +  {:added "1.0"}
  1.1282 +  ([x form] `(. ~x ~form))
  1.1283 +  ([x form & more] `(.. (. ~x ~form) ~@more)))
  1.1284 +
  1.1285 +(defmacro ->
  1.1286 +  "Threads the expr through the forms. Inserts x as the
  1.1287 +  second item in the first form, making a list of it if it is not a
  1.1288 +  list already. If there are more forms, inserts the first form as the
  1.1289 +  second item in second form, etc."
  1.1290 +  {:added "1.0"}
  1.1291 +  ([x] x)
  1.1292 +  ([x form] (if (seq? form)
  1.1293 +              (with-meta `(~(first form) ~x ~@(next form)) (meta form))
  1.1294 +              (list form x)))
  1.1295 +  ([x form & more] `(-> (-> ~x ~form) ~@more)))
  1.1296 +
  1.1297 +(defmacro ->>
  1.1298 +  "Threads the expr through the forms. Inserts x as the
  1.1299 +  last item in the first form, making a list of it if it is not a
  1.1300 +  list already. If there are more forms, inserts the first form as the
  1.1301 +  last item in second form, etc."
  1.1302 +  {:added "1.1"} 
  1.1303 +  ([x form] (if (seq? form)
  1.1304 +              (with-meta `(~(first form) ~@(next form)  ~x) (meta form))
  1.1305 +              (list form x)))
  1.1306 +  ([x form & more] `(->> (->> ~x ~form) ~@more)))
  1.1307 +
  1.1308 +;;multimethods
  1.1309 +(def global-hierarchy)
  1.1310 +
  1.1311 +(defmacro defmulti
  1.1312 +  "Creates a new multimethod with the associated dispatch function.
  1.1313 +  The docstring and attribute-map are optional.
  1.1314 +
  1.1315 +  Options are key-value pairs and may be one of:
  1.1316 +    :default    the default dispatch value, defaults to :default
  1.1317 +    :hierarchy  the isa? hierarchy to use for dispatching
  1.1318 +                defaults to the global hierarchy"
  1.1319 +  {:arglists '([name docstring? attr-map? dispatch-fn & options])
  1.1320 +   :added "1.0"}
  1.1321 +  [mm-name & options]
  1.1322 +  (let [docstring   (if (string? (first options))
  1.1323 +                      (first options)
  1.1324 +                      nil)
  1.1325 +        options     (if (string? (first options))
  1.1326 +                      (next options)
  1.1327 +                      options)
  1.1328 +        m           (if (map? (first options))
  1.1329 +                      (first options)
  1.1330 +                      {})
  1.1331 +        options     (if (map? (first options))
  1.1332 +                      (next options)
  1.1333 +                      options)
  1.1334 +        dispatch-fn (first options)
  1.1335 +        options     (next options)
  1.1336 +        m           (assoc m :tag 'clojure.lang.MultiFn)
  1.1337 +        m           (if docstring
  1.1338 +                      (assoc m :doc docstring)
  1.1339 +                      m)
  1.1340 +        m           (if (meta mm-name)
  1.1341 +                      (conj (meta mm-name) m)
  1.1342 +                      m)]
  1.1343 +    (when (= (count options) 1)
  1.1344 +      (throw (Exception. "The syntax for defmulti has changed. Example: (defmulti name dispatch-fn :default dispatch-value)")))
  1.1345 +    (let [options   (apply hash-map options)
  1.1346 +          default   (get options :default :default)
  1.1347 +          hierarchy (get options :hierarchy #'global-hierarchy)]
  1.1348 +      `(let [v# (def ~mm-name)]
  1.1349 +         (when-not (and (.hasRoot v#) (instance? clojure.lang.MultiFn (deref v#)))
  1.1350 +           (def ~(with-meta mm-name m)
  1.1351 +                (new clojure.lang.MultiFn ~(name mm-name) ~dispatch-fn ~default ~hierarchy)))))))
  1.1352 +
  1.1353 +(defmacro defmethod
  1.1354 +  "Creates and installs a new method of multimethod associated with dispatch-value. "
  1.1355 +  {:added "1.0"}
  1.1356 +  [multifn dispatch-val & fn-tail]
  1.1357 +  `(. ~(with-meta multifn {:tag 'clojure.lang.MultiFn}) addMethod ~dispatch-val (fn ~@fn-tail)))
  1.1358 +
  1.1359 +(defn remove-all-methods
  1.1360 +  "Removes all of the methods of multimethod."
  1.1361 +  {:added "1.2"} 
  1.1362 + [^clojure.lang.MultiFn multifn]
  1.1363 + (.reset multifn))
  1.1364 +
  1.1365 +(defn remove-method
  1.1366 +  "Removes the method of multimethod associated with dispatch-value."
  1.1367 +  {:added "1.0"}
  1.1368 + [^clojure.lang.MultiFn multifn dispatch-val]
  1.1369 + (. multifn removeMethod dispatch-val))
  1.1370 +
  1.1371 +(defn prefer-method
  1.1372 +  "Causes the multimethod to prefer matches of dispatch-val-x over dispatch-val-y 
  1.1373 +   when there is a conflict"
  1.1374 +  {:added "1.0"}
  1.1375 +  [^clojure.lang.MultiFn multifn dispatch-val-x dispatch-val-y]
  1.1376 +  (. multifn preferMethod dispatch-val-x dispatch-val-y))
  1.1377 +
  1.1378 +(defn methods
  1.1379 +  "Given a multimethod, returns a map of dispatch values -> dispatch fns"
  1.1380 +  {:added "1.0"}
  1.1381 +  [^clojure.lang.MultiFn multifn] (.getMethodTable multifn))
  1.1382 +
  1.1383 +(defn get-method
  1.1384 +  "Given a multimethod and a dispatch value, returns the dispatch fn
  1.1385 +  that would apply to that value, or nil if none apply and no default"
  1.1386 +  {:added "1.0"}
  1.1387 +  [^clojure.lang.MultiFn multifn dispatch-val] (.getMethod multifn dispatch-val))
  1.1388 +
  1.1389 +(defn prefers
  1.1390 +  "Given a multimethod, returns a map of preferred value -> set of other values"
  1.1391 +  {:added "1.0"}
  1.1392 +  [^clojure.lang.MultiFn multifn] (.getPreferTable multifn))
  1.1393 +
  1.1394 +;;;;;;;;; var stuff
  1.1395 +
  1.1396 +(defmacro ^{:private true} assert-args [fnname & pairs]
  1.1397 +  `(do (when-not ~(first pairs)
  1.1398 +         (throw (IllegalArgumentException.
  1.1399 +                  ~(str fnname " requires " (second pairs)))))
  1.1400 +     ~(let [more (nnext pairs)]
  1.1401 +        (when more
  1.1402 +          (list* `assert-args fnname more)))))
  1.1403 +
  1.1404 +(defmacro if-let
  1.1405 +  "bindings => binding-form test
  1.1406 +
  1.1407 +  If test is true, evaluates then with binding-form bound to the value of 
  1.1408 +  test, if not, yields else"
  1.1409 +  {:added "1.0"}
  1.1410 +  ([bindings then]
  1.1411 +   `(if-let ~bindings ~then nil))
  1.1412 +  ([bindings then else & oldform]
  1.1413 +   (assert-args if-let
  1.1414 +     (and (vector? bindings) (nil? oldform)) "a vector for its binding"
  1.1415 +     (= 2 (count bindings)) "exactly 2 forms in binding vector")
  1.1416 +   (let [form (bindings 0) tst (bindings 1)]
  1.1417 +     `(let [temp# ~tst]
  1.1418 +        (if temp#
  1.1419 +          (let [~form temp#]
  1.1420 +            ~then)
  1.1421 +          ~else)))))
  1.1422 +
  1.1423 +(defmacro when-let
  1.1424 +  "bindings => binding-form test
  1.1425 +
  1.1426 +  When test is true, evaluates body with binding-form bound to the value of test"
  1.1427 +  {:added "1.0"}
  1.1428 +  [bindings & body]
  1.1429 +  (assert-args when-let
  1.1430 +     (vector? bindings) "a vector for its binding"
  1.1431 +     (= 2 (count bindings)) "exactly 2 forms in binding vector")
  1.1432 +   (let [form (bindings 0) tst (bindings 1)]
  1.1433 +    `(let [temp# ~tst]
  1.1434 +       (when temp#
  1.1435 +         (let [~form temp#]
  1.1436 +           ~@body)))))
  1.1437 +
  1.1438 +(defn push-thread-bindings
  1.1439 +  "WARNING: This is a low-level function. Prefer high-level macros like
  1.1440 +  binding where ever possible.
  1.1441 +
  1.1442 +  Takes a map of Var/value pairs. Binds each Var to the associated value for
  1.1443 +  the current thread. Each call *MUST* be accompanied by a matching call to
  1.1444 +  pop-thread-bindings wrapped in a try-finally!
  1.1445 +  
  1.1446 +      (push-thread-bindings bindings)
  1.1447 +      (try
  1.1448 +        ...
  1.1449 +        (finally
  1.1450 +          (pop-thread-bindings)))"
  1.1451 +  {:added "1.1"} 
  1.1452 +  [bindings]
  1.1453 +  (clojure.lang.Var/pushThreadBindings bindings))
  1.1454 +
  1.1455 +(defn pop-thread-bindings
  1.1456 +  "Pop one set of bindings pushed with push-binding before. It is an error to
  1.1457 +  pop bindings without pushing before."
  1.1458 +  {:added "1.1"}
  1.1459 +  []
  1.1460 +  (clojure.lang.Var/popThreadBindings))
  1.1461 +
  1.1462 +(defn get-thread-bindings
  1.1463 +  "Get a map with the Var/value pairs which is currently in effect for the
  1.1464 +  current thread."
  1.1465 +  {:added "1.1"}
  1.1466 +  []
  1.1467 +  (clojure.lang.Var/getThreadBindings))
  1.1468 +
  1.1469 +(defmacro binding
  1.1470 +  "binding => var-symbol init-expr
  1.1471 +
  1.1472 +  Creates new bindings for the (already-existing) vars, with the
  1.1473 +  supplied initial values, executes the exprs in an implicit do, then
  1.1474 +  re-establishes the bindings that existed before.  The new bindings
  1.1475 +  are made in parallel (unlike let); all init-exprs are evaluated
  1.1476 +  before the vars are bound to their new values."
  1.1477 +  {:added "1.0"}
  1.1478 +  [bindings & body]
  1.1479 +  (assert-args binding
  1.1480 +    (vector? bindings) "a vector for its binding"
  1.1481 +    (even? (count bindings)) "an even number of forms in binding vector")
  1.1482 +  (let [var-ize (fn [var-vals]
  1.1483 +                  (loop [ret [] vvs (seq var-vals)]
  1.1484 +                    (if vvs
  1.1485 +                      (recur  (conj (conj ret `(var ~(first vvs))) (second vvs))
  1.1486 +                             (next (next vvs)))
  1.1487 +                      (seq ret))))]
  1.1488 +    `(let []
  1.1489 +       (push-thread-bindings (hash-map ~@(var-ize bindings)))
  1.1490 +       (try
  1.1491 +         ~@body
  1.1492 +         (finally
  1.1493 +           (pop-thread-bindings))))))
  1.1494 +
  1.1495 +(defn with-bindings*
  1.1496 +  "Takes a map of Var/value pairs. Installs for the given Vars the associated
  1.1497 +  values as thread-local bindings. Then calls f with the supplied arguments.
  1.1498 +  Pops the installed bindings after f returned. Returns whatever f returns."
  1.1499 +  {:added "1.1"}
  1.1500 +  [binding-map f & args]
  1.1501 +  (push-thread-bindings binding-map)
  1.1502 +  (try
  1.1503 +    (apply f args)
  1.1504 +    (finally
  1.1505 +      (pop-thread-bindings))))
  1.1506 +
  1.1507 +(defmacro with-bindings
  1.1508 +  "Takes a map of Var/value pairs. Installs for the given Vars the associated
  1.1509 +  values as thread-local bindings. The executes body. Pops the installed
  1.1510 +  bindings after body was evaluated. Returns the value of body."
  1.1511 +  {:added "1.1"}
  1.1512 +  [binding-map & body]
  1.1513 +  `(with-bindings* ~binding-map (fn [] ~@body)))
  1.1514 +
  1.1515 +(defn bound-fn*
  1.1516 +  "Returns a function, which will install the same bindings in effect as in
  1.1517 +  the thread at the time bound-fn* was called and then call f with any given
  1.1518 +  arguments. This may be used to define a helper function which runs on a
  1.1519 +  different thread, but needs the same bindings in place."
  1.1520 +  {:added "1.1"}
  1.1521 +  [f]
  1.1522 +  (let [bindings (get-thread-bindings)]
  1.1523 +    (fn [& args]
  1.1524 +      (apply with-bindings* bindings f args))))
  1.1525 +
  1.1526 +(defmacro bound-fn
  1.1527 +  "Returns a function defined by the given fntail, which will install the
  1.1528 +  same bindings in effect as in the thread at the time bound-fn was called.
  1.1529 +  This may be used to define a helper function which runs on a different
  1.1530 +  thread, but needs the same bindings in place."
  1.1531 +  {:added "1.1"}
  1.1532 +  [& fntail]
  1.1533 +  `(bound-fn* (fn ~@fntail)))
  1.1534 +
  1.1535 +(defn find-var
  1.1536 +  "Returns the global var named by the namespace-qualified symbol, or
  1.1537 +  nil if no var with that name."
  1.1538 +  {:added "1.0"}
  1.1539 + [sym] (. clojure.lang.Var (find sym)))
  1.1540 +
  1.1541 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Refs ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1.1542 +(defn ^{:private true}
  1.1543 +  setup-reference [^clojure.lang.ARef r options]
  1.1544 +  (let [opts (apply hash-map options)]
  1.1545 +    (when (:meta opts)
  1.1546 +      (.resetMeta r (:meta opts)))
  1.1547 +    (when (:validator opts)
  1.1548 +      (.setValidator r (:validator opts)))
  1.1549 +    r))
  1.1550 +
  1.1551 +(defn agent
  1.1552 +  "Creates and returns an agent with an initial value of state and
  1.1553 +  zero or more options (in any order):
  1.1554 +
  1.1555 +  :meta metadata-map
  1.1556 +
  1.1557 +  :validator validate-fn
  1.1558 +
  1.1559 +  :error-handler handler-fn
  1.1560 +
  1.1561 +  :error-mode mode-keyword
  1.1562 +
  1.1563 +  If metadata-map is supplied, it will be come the metadata on the
  1.1564 +  agent. validate-fn must be nil or a side-effect-free fn of one
  1.1565 +  argument, which will be passed the intended new state on any state
  1.1566 +  change. If the new state is unacceptable, the validate-fn should
  1.1567 +  return false or throw an exception.  handler-fn is called if an
  1.1568 +  action throws an exception or if validate-fn rejects a new state --
  1.1569 +  see set-error-handler! for details.  The mode-keyword may be either
  1.1570 +  :continue (the default if an error-handler is given) or :fail (the
  1.1571 +  default if no error-handler is given) -- see set-error-mode! for
  1.1572 +  details."
  1.1573 +  {:added "1.0"}
  1.1574 +  ([state & options]
  1.1575 +     (let [a (new clojure.lang.Agent state)
  1.1576 +           opts (apply hash-map options)]
  1.1577 +       (setup-reference a options)
  1.1578 +       (when (:error-handler opts)
  1.1579 +         (.setErrorHandler a (:error-handler opts)))
  1.1580 +       (.setErrorMode a (or (:error-mode opts)
  1.1581 +                            (if (:error-handler opts) :continue :fail)))
  1.1582 +       a)))
  1.1583 +
  1.1584 +(defn send
  1.1585 +  "Dispatch an action to an agent. Returns the agent immediately.
  1.1586 +  Subsequently, in a thread from a thread pool, the state of the agent
  1.1587 +  will be set to the value of:
  1.1588 +
  1.1589 +  (apply action-fn state-of-agent args)"
  1.1590 +  {:added "1.0"}
  1.1591 +  [^clojure.lang.Agent a f & args]
  1.1592 +    (. a (dispatch f args false)))
  1.1593 +
  1.1594 +(defn send-off
  1.1595 +  "Dispatch a potentially blocking action to an agent. Returns the
  1.1596 +  agent immediately. Subsequently, in a separate thread, the state of
  1.1597 +  the agent will be set to the value of:
  1.1598 +
  1.1599 +  (apply action-fn state-of-agent args)"
  1.1600 +  {:added "1.0"}
  1.1601 +  [^clojure.lang.Agent a f & args]
  1.1602 +    (. a (dispatch f args true)))
  1.1603 +
  1.1604 +(defn release-pending-sends
  1.1605 +  "Normally, actions sent directly or indirectly during another action
  1.1606 +  are held until the action completes (changes the agent's
  1.1607 +  state). This function can be used to dispatch any pending sent
  1.1608 +  actions immediately. This has no impact on actions sent during a
  1.1609 +  transaction, which are still held until commit. If no action is
  1.1610 +  occurring, does nothing. Returns the number of actions dispatched."
  1.1611 +  {:added "1.0"}
  1.1612 +  [] (clojure.lang.Agent/releasePendingSends))
  1.1613 +
  1.1614 +(defn add-watch
  1.1615 +  "Alpha - subject to change.
  1.1616 +  Adds a watch function to an agent/atom/var/ref reference. The watch
  1.1617 +  fn must be a fn of 4 args: a key, the reference, its old-state, its
  1.1618 +  new-state. Whenever the reference's state might have been changed,
  1.1619 +  any registered watches will have their functions called. The watch fn
  1.1620 +  will be called synchronously, on the agent's thread if an agent,
  1.1621 +  before any pending sends if agent or ref. Note that an atom's or
  1.1622 +  ref's state may have changed again prior to the fn call, so use
  1.1623 +  old/new-state rather than derefing the reference. Note also that watch
  1.1624 +  fns may be called from multiple threads simultaneously. Var watchers
  1.1625 +  are triggered only by root binding changes, not thread-local
  1.1626 +  set!s. Keys must be unique per reference, and can be used to remove
  1.1627 +  the watch with remove-watch, but are otherwise considered opaque by
  1.1628 +  the watch mechanism."
  1.1629 +  {:added "1.0"}
  1.1630 +  [^clojure.lang.IRef reference key fn] (.addWatch reference key fn))
  1.1631 +
  1.1632 +(defn remove-watch
  1.1633 +  "Alpha - subject to change.
  1.1634 +  Removes a watch (set by add-watch) from a reference"
  1.1635 +  {:added "1.0"}
  1.1636 +  [^clojure.lang.IRef reference key]
  1.1637 +  (.removeWatch reference key))
  1.1638 +
  1.1639 +(defn agent-error
  1.1640 +  "Returns the exception thrown during an asynchronous action of the
  1.1641 +  agent if the agent is failed.  Returns nil if the agent is not
  1.1642 +  failed."
  1.1643 +  {:added "1.2"}
  1.1644 +  [^clojure.lang.Agent a] (.getError a))
  1.1645 +
  1.1646 +(defn restart-agent
  1.1647 +  "When an agent is failed, changes the agent state to new-state and
  1.1648 +  then un-fails the agent so that sends are allowed again.  If
  1.1649 +  a :clear-actions true option is given, any actions queued on the
  1.1650 +  agent that were being held while it was failed will be discarded,
  1.1651 +  otherwise those held actions will proceed.  The new-state must pass
  1.1652 +  the validator if any, or restart will throw an exception and the
  1.1653 +  agent will remain failed with its old state and error.  Watchers, if
  1.1654 +  any, will NOT be notified of the new state.  Throws an exception if
  1.1655 +  the agent is not failed."
  1.1656 +  {:added "1.2"}
  1.1657 +  [^clojure.lang.Agent a, new-state & options]
  1.1658 +  (let [opts (apply hash-map options)]
  1.1659 +    (.restart a new-state (if (:clear-actions opts) true false))))
  1.1660 +
  1.1661 +(defn set-error-handler!
  1.1662 +  "Sets the error-handler of agent a to handler-fn.  If an action
  1.1663 +  being run by the agent throws an exception or doesn't pass the
  1.1664 +  validator fn, handler-fn will be called with two arguments: the
  1.1665 +  agent and the exception."
  1.1666 +  {:added "1.2"}
  1.1667 +  [^clojure.lang.Agent a, handler-fn]
  1.1668 +  (.setErrorHandler a handler-fn))
  1.1669 +
  1.1670 +(defn error-handler
  1.1671 +  "Returns the error-handler of agent a, or nil if there is none.
  1.1672 +  See set-error-handler!"
  1.1673 +  {:added "1.2"}
  1.1674 +  [^clojure.lang.Agent a]
  1.1675 +  (.getErrorHandler a))
  1.1676 +
  1.1677 +(defn set-error-mode!
  1.1678 +  "Sets the error-mode of agent a to mode-keyword, which must be
  1.1679 +  either :fail or :continue.  If an action being run by the agent
  1.1680 +  throws an exception or doesn't pass the validator fn, an
  1.1681 +  error-handler may be called (see set-error-handler!), after which,
  1.1682 +  if the mode is :continue, the agent will continue as if neither the
  1.1683 +  action that caused the error nor the error itself ever happened.
  1.1684 +  
  1.1685 +  If the mode is :fail, the agent will become failed and will stop
  1.1686 +  accepting new 'send' and 'send-off' actions, and any previously
  1.1687 +  queued actions will be held until a 'restart-agent'.  Deref will
  1.1688 +  still work, returning the state of the agent before the error."
  1.1689 +  {:added "1.2"}
  1.1690 +  [^clojure.lang.Agent a, mode-keyword]
  1.1691 +  (.setErrorMode a mode-keyword))
  1.1692 +
  1.1693 +(defn error-mode
  1.1694 +  "Returns the error-mode of agent a.  See set-error-mode!"
  1.1695 +  {:added "1.2"}
  1.1696 +  [^clojure.lang.Agent a]
  1.1697 +  (.getErrorMode a))
  1.1698 +
  1.1699 +(defn agent-errors
  1.1700 +  "DEPRECATED: Use 'agent-error' instead.
  1.1701 +  Returns a sequence of the exceptions thrown during asynchronous
  1.1702 +  actions of the agent."
  1.1703 +  {:added "1.0"
  1.1704 +   :deprecated "1.2"}
  1.1705 +  [a]
  1.1706 +  (when-let [e (agent-error a)]
  1.1707 +    (list e)))
  1.1708 +
  1.1709 +(defn clear-agent-errors
  1.1710 +  "DEPRECATED: Use 'restart-agent' instead.
  1.1711 +  Clears any exceptions thrown during asynchronous actions of the
  1.1712 +  agent, allowing subsequent actions to occur."
  1.1713 +  {:added "1.0"
  1.1714 +   :deprecated "1.2"}
  1.1715 +  [^clojure.lang.Agent a] (restart-agent a (.deref a)))
  1.1716 +
  1.1717 +(defn shutdown-agents
  1.1718 +  "Initiates a shutdown of the thread pools that back the agent
  1.1719 +  system. Running actions will complete, but no new actions will be
  1.1720 +  accepted"
  1.1721 +  {:added "1.0"}
  1.1722 +  [] (. clojure.lang.Agent shutdown))
  1.1723 +
  1.1724 +(defn ref
  1.1725 +  "Creates and returns a Ref with an initial value of x and zero or
  1.1726 +  more options (in any order):
  1.1727 +
  1.1728 +  :meta metadata-map
  1.1729 +
  1.1730 +  :validator validate-fn
  1.1731 +
  1.1732 +  :min-history (default 0)
  1.1733 +  :max-history (default 10)
  1.1734 +
  1.1735 +  If metadata-map is supplied, it will be come the metadata on the
  1.1736 +  ref. validate-fn must be nil or a side-effect-free fn of one
  1.1737 +  argument, which will be passed the intended new state on any state
  1.1738 +  change. If the new state is unacceptable, the validate-fn should
  1.1739 +  return false or throw an exception. validate-fn will be called on
  1.1740 +  transaction commit, when all refs have their final values.
  1.1741 +
  1.1742 +  Normally refs accumulate history dynamically as needed to deal with
  1.1743 +  read demands. If you know in advance you will need history you can
  1.1744 +  set :min-history to ensure it will be available when first needed (instead
  1.1745 +  of after a read fault). History is limited, and the limit can be set
  1.1746 +  with :max-history."
  1.1747 +  {:added "1.0"}
  1.1748 +  ([x] (new clojure.lang.Ref x))
  1.1749 +  ([x & options] 
  1.1750 +   (let [r  ^clojure.lang.Ref (setup-reference (ref x) options)
  1.1751 +         opts (apply hash-map options)]
  1.1752 +    (when (:max-history opts)
  1.1753 +      (.setMaxHistory r (:max-history opts)))
  1.1754 +    (when (:min-history opts)
  1.1755 +      (.setMinHistory r (:min-history opts)))
  1.1756 +    r)))
  1.1757 +
  1.1758 +(defn deref
  1.1759 +  "Also reader macro: @ref/@agent/@var/@atom/@delay/@future. Within a transaction,
  1.1760 +  returns the in-transaction-value of ref, else returns the
  1.1761 +  most-recently-committed value of ref. When applied to a var, agent
  1.1762 +  or atom, returns its current state. When applied to a delay, forces
  1.1763 +  it if not already forced. When applied to a future, will block if
  1.1764 +  computation not complete"
  1.1765 +  {:added "1.0"}
  1.1766 +  [^clojure.lang.IDeref ref] (.deref ref))
  1.1767 +
  1.1768 +(defn atom
  1.1769 +  "Creates and returns an Atom with an initial value of x and zero or
  1.1770 +  more options (in any order):
  1.1771 +
  1.1772 +  :meta metadata-map
  1.1773 +
  1.1774 +  :validator validate-fn
  1.1775 +
  1.1776 +  If metadata-map is supplied, it will be come the metadata on the
  1.1777 +  atom. validate-fn must be nil or a side-effect-free fn of one
  1.1778 +  argument, which will be passed the intended new state on any state
  1.1779 +  change. If the new state is unacceptable, the validate-fn should
  1.1780 +  return false or throw an exception."
  1.1781 +  {:added "1.0"}
  1.1782 +  ([x] (new clojure.lang.Atom x))
  1.1783 +  ([x & options] (setup-reference (atom x) options)))
  1.1784 +
  1.1785 +(defn swap!
  1.1786 +  "Atomically swaps the value of atom to be:
  1.1787 +  (apply f current-value-of-atom args). Note that f may be called
  1.1788 +  multiple times, and thus should be free of side effects.  Returns
  1.1789 +  the value that was swapped in."
  1.1790 +  {:added "1.0"}
  1.1791 +  ([^clojure.lang.Atom atom f] (.swap atom f))
  1.1792 +  ([^clojure.lang.Atom atom f x] (.swap atom f x))
  1.1793 +  ([^clojure.lang.Atom atom f x y] (.swap atom f x y))
  1.1794 +  ([^clojure.lang.Atom atom f x y & args] (.swap atom f x y args)))
  1.1795 +
  1.1796 +(defn compare-and-set!
  1.1797 +  "Atomically sets the value of atom to newval if and only if the
  1.1798 +  current value of the atom is identical to oldval. Returns true if
  1.1799 +  set happened, else false"
  1.1800 +  {:added "1.0"}
  1.1801 +  [^clojure.lang.Atom atom oldval newval] (.compareAndSet atom oldval newval))
  1.1802 +
  1.1803 +(defn reset!
  1.1804 +  "Sets the value of atom to newval without regard for the
  1.1805 +  current value. Returns newval."
  1.1806 +  {:added "1.0"}
  1.1807 +  [^clojure.lang.Atom atom newval] (.reset atom newval))
  1.1808 +
  1.1809 +(defn set-validator!
  1.1810 +  "Sets the validator-fn for a var/ref/agent/atom. validator-fn must be nil or a
  1.1811 +  side-effect-free fn of one argument, which will be passed the intended
  1.1812 +  new state on any state change. If the new state is unacceptable, the
  1.1813 +  validator-fn should return false or throw an exception. If the current state (root
  1.1814 +  value if var) is not acceptable to the new validator, an exception
  1.1815 +  will be thrown and the validator will not be changed."
  1.1816 +  {:added "1.0"}
  1.1817 +  [^clojure.lang.IRef iref validator-fn] (. iref (setValidator validator-fn)))
  1.1818 +
  1.1819 +(defn get-validator
  1.1820 +  "Gets the validator-fn for a var/ref/agent/atom."
  1.1821 +  {:added "1.0"}
  1.1822 + [^clojure.lang.IRef iref] (. iref (getValidator)))
  1.1823 +
  1.1824 +(defn alter-meta!
  1.1825 +  "Atomically sets the metadata for a namespace/var/ref/agent/atom to be:
  1.1826 +
  1.1827 +  (apply f its-current-meta args)
  1.1828 +
  1.1829 +  f must be free of side-effects"
  1.1830 +  {:added "1.0"}
  1.1831 + [^clojure.lang.IReference iref f & args] (.alterMeta iref f args))
  1.1832 +
  1.1833 +(defn reset-meta!
  1.1834 +  "Atomically resets the metadata for a namespace/var/ref/agent/atom"
  1.1835 +  {:added "1.0"}
  1.1836 + [^clojure.lang.IReference iref metadata-map] (.resetMeta iref metadata-map))
  1.1837 +
  1.1838 +(defn commute
  1.1839 +  "Must be called in a transaction. Sets the in-transaction-value of
  1.1840 +  ref to:
  1.1841 +
  1.1842 +  (apply fun in-transaction-value-of-ref args)
  1.1843 +
  1.1844 +  and returns the in-transaction-value of ref.
  1.1845 +
  1.1846 +  At the commit point of the transaction, sets the value of ref to be:
  1.1847 +
  1.1848 +  (apply fun most-recently-committed-value-of-ref args)
  1.1849 +
  1.1850 +  Thus fun should be commutative, or, failing that, you must accept
  1.1851 +  last-one-in-wins behavior.  commute allows for more concurrency than
  1.1852 +  ref-set."
  1.1853 +  {:added "1.0"}
  1.1854 +
  1.1855 +  [^clojure.lang.Ref ref fun & args]
  1.1856 +    (. ref (commute fun args)))
  1.1857 +
  1.1858 +(defn alter
  1.1859 +  "Must be called in a transaction. Sets the in-transaction-value of
  1.1860 +  ref to:
  1.1861 +
  1.1862 +  (apply fun in-transaction-value-of-ref args)
  1.1863 +
  1.1864 +  and returns the in-transaction-value of ref."
  1.1865 +  {:added "1.0"}
  1.1866 +  [^clojure.lang.Ref ref fun & args]
  1.1867 +    (. ref (alter fun args)))
  1.1868 +
  1.1869 +(defn ref-set
  1.1870 +  "Must be called in a transaction. Sets the value of ref.
  1.1871 +  Returns val."
  1.1872 +  {:added "1.0"}
  1.1873 +  [^clojure.lang.Ref ref val]
  1.1874 +    (. ref (set val)))
  1.1875 +
  1.1876 +(defn ref-history-count
  1.1877 +  "Returns the history count of a ref"
  1.1878 +  {:added "1.1"}
  1.1879 +  [^clojure.lang.Ref ref]
  1.1880 +    (.getHistoryCount ref))
  1.1881 +
  1.1882 +(defn ref-min-history
  1.1883 +  "Gets the min-history of a ref, or sets it and returns the ref"
  1.1884 +  {:added "1.1"}
  1.1885 +  ([^clojure.lang.Ref ref]
  1.1886 +    (.getMinHistory ref))
  1.1887 +  ([^clojure.lang.Ref ref n]
  1.1888 +    (.setMinHistory ref n)))
  1.1889 +
  1.1890 +(defn ref-max-history
  1.1891 +  "Gets the max-history of a ref, or sets it and returns the ref"
  1.1892 +  {:added "1.1"}
  1.1893 +  ([^clojure.lang.Ref ref]
  1.1894 +    (.getMaxHistory ref))
  1.1895 +  ([^clojure.lang.Ref ref n]
  1.1896 +    (.setMaxHistory ref n)))
  1.1897 +
  1.1898 +(defn ensure
  1.1899 +  "Must be called in a transaction. Protects the ref from modification
  1.1900 +  by other transactions.  Returns the in-transaction-value of
  1.1901 +  ref. Allows for more concurrency than (ref-set ref @ref)"
  1.1902 +  {:added "1.0"}
  1.1903 +  [^clojure.lang.Ref ref]
  1.1904 +    (. ref (touch))
  1.1905 +    (. ref (deref)))
  1.1906 +
  1.1907 +(defmacro sync
  1.1908 +  "transaction-flags => TBD, pass nil for now
  1.1909 +
  1.1910 +  Runs the exprs (in an implicit do) in a transaction that encompasses
  1.1911 +  exprs and any nested calls.  Starts a transaction if none is already
  1.1912 +  running on this thread. Any uncaught exception will abort the
  1.1913 +  transaction and flow out of sync. The exprs may be run more than
  1.1914 +  once, but any effects on Refs will be atomic."
  1.1915 +  {:added "1.0"}
  1.1916 +  [flags-ignored-for-now & body]
  1.1917 +  `(. clojure.lang.LockingTransaction
  1.1918 +      (runInTransaction (fn [] ~@body))))
  1.1919 +
  1.1920 +
  1.1921 +(defmacro io!
  1.1922 +  "If an io! block occurs in a transaction, throws an
  1.1923 +  IllegalStateException, else runs body in an implicit do. If the
  1.1924 +  first expression in body is a literal string, will use that as the
  1.1925 +  exception message."
  1.1926 +  {:added "1.0"}
  1.1927 +  [& body]
  1.1928 +  (let [message (when (string? (first body)) (first body))
  1.1929 +        body (if message (next body) body)]
  1.1930 +    `(if (clojure.lang.LockingTransaction/isRunning)
  1.1931 +       (throw (new IllegalStateException ~(or message "I/O in transaction")))
  1.1932 +       (do ~@body))))
  1.1933 +
  1.1934 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; fn stuff ;;;;;;;;;;;;;;;;
  1.1935 +
  1.1936 +
  1.1937 +(defn comp
  1.1938 +  "Takes a set of functions and returns a fn that is the composition
  1.1939 +  of those fns.  The returned fn takes a variable number of args,
  1.1940 +  applies the rightmost of fns to the args, the next
  1.1941 +  fn (right-to-left) to the result, etc."
  1.1942 +  {:added "1.0"}
  1.1943 +  ([f] f)
  1.1944 +  ([f g] 
  1.1945 +     (fn 
  1.1946 +       ([] (f (g)))
  1.1947 +       ([x] (f (g x)))
  1.1948 +       ([x y] (f (g x y)))
  1.1949 +       ([x y z] (f (g x y z)))
  1.1950 +       ([x y z & args] (f (apply g x y z args)))))
  1.1951 +  ([f g h] 
  1.1952 +     (fn 
  1.1953 +       ([] (f (g (h))))
  1.1954 +       ([x] (f (g (h x))))
  1.1955 +       ([x y] (f (g (h x y))))
  1.1956 +       ([x y z] (f (g (h x y z))))
  1.1957 +       ([x y z & args] (f (g (apply h x y z args))))))
  1.1958 +  ([f1 f2 f3 & fs]
  1.1959 +    (let [fs (reverse (list* f1 f2 f3 fs))]
  1.1960 +      (fn [& args]
  1.1961 +        (loop [ret (apply (first fs) args) fs (next fs)]
  1.1962 +          (if fs
  1.1963 +            (recur ((first fs) ret) (next fs))
  1.1964 +            ret))))))
  1.1965 +
  1.1966 +(defn juxt 
  1.1967 +  "Alpha - name subject to change.
  1.1968 +  Takes a set of functions and returns a fn that is the juxtaposition
  1.1969 +  of those fns.  The returned fn takes a variable number of args, and
  1.1970 +  returns a vector containing the result of applying each fn to the
  1.1971 +  args (left-to-right).
  1.1972 +  ((juxt a b c) x) => [(a x) (b x) (c x)]"
  1.1973 +  {:added "1.1"}
  1.1974 +  ([f] 
  1.1975 +     (fn
  1.1976 +       ([] [(f)])
  1.1977 +       ([x] [(f x)])
  1.1978 +       ([x y] [(f x y)])
  1.1979 +       ([x y z] [(f x y z)])
  1.1980 +       ([x y z & args] [(apply f x y z args)])))
  1.1981 +  ([f g] 
  1.1982 +     (fn
  1.1983 +       ([] [(f) (g)])
  1.1984 +       ([x] [(f x) (g x)])
  1.1985 +       ([x y] [(f x y) (g x y)])
  1.1986 +       ([x y z] [(f x y z) (g x y z)])
  1.1987 +       ([x y z & args] [(apply f x y z args) (apply g x y z args)])))
  1.1988 +  ([f g h] 
  1.1989 +     (fn
  1.1990 +       ([] [(f) (g) (h)])
  1.1991 +       ([x] [(f x) (g x) (h x)])
  1.1992 +       ([x y] [(f x y) (g x y) (h x y)])
  1.1993 +       ([x y z] [(f x y z) (g x y z) (h x y z)])
  1.1994 +       ([x y z & args] [(apply f x y z args) (apply g x y z args) (apply h x y z args)])))
  1.1995 +  ([f g h & fs]
  1.1996 +     (let [fs (list* f g h fs)]
  1.1997 +       (fn
  1.1998 +         ([] (reduce #(conj %1 (%2)) [] fs))
  1.1999 +         ([x] (reduce #(conj %1 (%2 x)) [] fs))
  1.2000 +         ([x y] (reduce #(conj %1 (%2 x y)) [] fs))
  1.2001 +         ([x y z] (reduce #(conj %1 (%2 x y z)) [] fs))
  1.2002 +         ([x y z & args] (reduce #(conj %1 (apply %2 x y z args)) [] fs))))))
  1.2003 +
  1.2004 +(defn partial
  1.2005 +  "Takes a function f and fewer than the normal arguments to f, and
  1.2006 +  returns a fn that takes a variable number of additional args. When
  1.2007 +  called, the returned function calls f with args + additional args."
  1.2008 +  {:added "1.0"}
  1.2009 +  ([f arg1]
  1.2010 +   (fn [& args] (apply f arg1 args)))
  1.2011 +  ([f arg1 arg2]
  1.2012 +   (fn [& args] (apply f arg1 arg2 args)))
  1.2013 +  ([f arg1 arg2 arg3]
  1.2014 +   (fn [& args] (apply f arg1 arg2 arg3 args)))
  1.2015 +  ([f arg1 arg2 arg3 & more]
  1.2016 +   (fn [& args] (apply f arg1 arg2 arg3 (concat more args)))))
  1.2017 +
  1.2018 +;;;;;;;;;;;;;;;;;;; sequence fns  ;;;;;;;;;;;;;;;;;;;;;;;
  1.2019 +(defn sequence
  1.2020 +  "Coerces coll to a (possibly empty) sequence, if it is not already
  1.2021 +  one. Will not force a lazy seq. (sequence nil) yields ()"
  1.2022 +  {:added "1.0"}
  1.2023 +  [coll]
  1.2024 +   (if (seq? coll) coll
  1.2025 +    (or (seq coll) ())))
  1.2026 +
  1.2027 +(defn every?
  1.2028 +  "Returns true if (pred x) is logical true for every x in coll, else
  1.2029 +  false."
  1.2030 +  {:tag Boolean
  1.2031 +   :added "1.0"}
  1.2032 +  [pred coll]
  1.2033 +  (cond
  1.2034 +   (nil? (seq coll)) true
  1.2035 +   (pred (first coll)) (recur pred (next coll))
  1.2036 +   :else false))
  1.2037 +
  1.2038 +(def
  1.2039 + ^{:tag Boolean
  1.2040 +   :doc "Returns false if (pred x) is logical true for every x in
  1.2041 +  coll, else true."
  1.2042 +   :arglists '([pred coll])
  1.2043 +   :added "1.0"}
  1.2044 + not-every? (comp not every?))
  1.2045 +
  1.2046 +(defn some
  1.2047 +  "Returns the first logical true value of (pred x) for any x in coll,
  1.2048 +  else nil.  One common idiom is to use a set as pred, for example
  1.2049 +  this will return :fred if :fred is in the sequence, otherwise nil:
  1.2050 +  (some #{:fred} coll)"
  1.2051 +  {:added "1.0"}
  1.2052 +  [pred coll]
  1.2053 +    (when (seq coll)
  1.2054 +      (or (pred (first coll)) (recur pred (next coll)))))
  1.2055 +
  1.2056 +(def
  1.2057 + ^{:tag Boolean
  1.2058 +   :doc "Returns false if (pred x) is logical true for any x in coll,
  1.2059 +  else true."
  1.2060 +   :arglists '([pred coll])
  1.2061 +   :added "1.0"}
  1.2062 + not-any? (comp not some))
  1.2063 +
  1.2064 +;will be redefed later with arg checks
  1.2065 +(defmacro dotimes
  1.2066 +  "bindings => name n
  1.2067 +
  1.2068 +  Repeatedly executes body (presumably for side-effects) with name
  1.2069 +  bound to integers from 0 through n-1."
  1.2070 +  {:added "1.0"}
  1.2071 +  [bindings & body]
  1.2072 +  (let [i (first bindings)
  1.2073 +        n (second bindings)]
  1.2074 +    `(let [n# (int ~n)]
  1.2075 +       (loop [~i (int 0)]
  1.2076 +         (when (< ~i n#)
  1.2077 +           ~@body
  1.2078 +           (recur (inc ~i)))))))
  1.2079 +
  1.2080 +(defn map
  1.2081 +  "Returns a lazy sequence consisting of the result of applying f to the
  1.2082 +  set of first items of each coll, followed by applying f to the set
  1.2083 +  of second items in each coll, until any one of the colls is
  1.2084 +  exhausted.  Any remaining items in other colls are ignored. Function
  1.2085 +  f should accept number-of-colls arguments."
  1.2086 +  {:added "1.0"}
  1.2087 +  ([f coll]
  1.2088 +   (lazy-seq
  1.2089 +    (when-let [s (seq coll)]
  1.2090 +      (if (chunked-seq? s)
  1.2091 +        (let [c (chunk-first s)
  1.2092 +              size (int (count c))
  1.2093 +              b (chunk-buffer size)]
  1.2094 +          (dotimes [i size]
  1.2095 +              (chunk-append b (f (.nth c i))))
  1.2096 +          (chunk-cons (chunk b) (map f (chunk-rest s))))
  1.2097 +        (cons (f (first s)) (map f (rest s)))))))
  1.2098 +  ([f c1 c2]
  1.2099 +   (lazy-seq
  1.2100 +    (let [s1 (seq c1) s2 (seq c2)]
  1.2101 +      (when (and s1 s2)
  1.2102 +        (cons (f (first s1) (first s2))
  1.2103 +              (map f (rest s1) (rest s2)))))))
  1.2104 +  ([f c1 c2 c3]
  1.2105 +   (lazy-seq
  1.2106 +    (let [s1 (seq c1) s2 (seq c2) s3 (seq c3)]
  1.2107 +      (when (and  s1 s2 s3)
  1.2108 +        (cons (f (first s1) (first s2) (first s3))
  1.2109 +              (map f (rest s1) (rest s2) (rest s3)))))))
  1.2110 +  ([f c1 c2 c3 & colls]
  1.2111 +   (let [step (fn step [cs]
  1.2112 +                 (lazy-seq
  1.2113 +                  (let [ss (map seq cs)]
  1.2114 +                    (when (every? identity ss)
  1.2115 +                      (cons (map first ss) (step (map rest ss)))))))]
  1.2116 +     (map #(apply f %) (step (conj colls c3 c2 c1))))))
  1.2117 +
  1.2118 +(defn mapcat
  1.2119 +  "Returns the result of applying concat to the result of applying map
  1.2120 +  to f and colls.  Thus function f should return a collection."
  1.2121 +  {:added "1.0"}
  1.2122 +  [f & colls]
  1.2123 +    (apply concat (apply map f colls)))
  1.2124 +
  1.2125 +(defn filter
  1.2126 +  "Returns a lazy sequence of the items in coll for which
  1.2127 +  (pred item) returns true. pred must be free of side-effects."
  1.2128 +  {:added "1.0"}
  1.2129 +  ([pred coll]
  1.2130 +   (lazy-seq
  1.2131 +    (when-let [s (seq coll)]
  1.2132 +      (if (chunked-seq? s)
  1.2133 +        (let [c (chunk-first s)
  1.2134 +              size (count c)
  1.2135 +              b (chunk-buffer size)]
  1.2136 +          (dotimes [i size]
  1.2137 +              (when (pred (.nth c i))
  1.2138 +                (chunk-append b (.nth c i))))
  1.2139 +          (chunk-cons (chunk b) (filter pred (chunk-rest s))))
  1.2140 +        (let [f (first s) r (rest s)]
  1.2141 +          (if (pred f)
  1.2142 +            (cons f (filter pred r))
  1.2143 +            (filter pred r))))))))
  1.2144 +
  1.2145 +
  1.2146 +(defn remove
  1.2147 +  "Returns a lazy sequence of the items in coll for which
  1.2148 +  (pred item) returns false. pred must be free of side-effects."
  1.2149 +  {:added "1.0"}
  1.2150 +  [pred coll]
  1.2151 +  (filter (complement pred) coll))
  1.2152 +
  1.2153 +(defn take
  1.2154 +  "Returns a lazy sequence of the first n items in coll, or all items if
  1.2155 +  there are fewer than n."
  1.2156 +  {:added "1.0"}
  1.2157 +  [n coll]
  1.2158 +  (lazy-seq
  1.2159 +   (when (pos? n) 
  1.2160 +     (when-let [s (seq coll)]
  1.2161 +      (cons (first s) (take (dec n) (rest s)))))))
  1.2162 +
  1.2163 +(defn take-while
  1.2164 +  "Returns a lazy sequence of successive items from coll while
  1.2165 +  (pred item) returns true. pred must be free of side-effects."
  1.2166 +  {:added "1.0"}
  1.2167 +  [pred coll]
  1.2168 +  (lazy-seq
  1.2169 +   (when-let [s (seq coll)]
  1.2170 +       (when (pred (first s))
  1.2171 +         (cons (first s) (take-while pred (rest s)))))))
  1.2172 +
  1.2173 +(defn drop
  1.2174 +  "Returns a lazy sequence of all but the first n items in coll."
  1.2175 +  {:added "1.0"}
  1.2176 +  [n coll]
  1.2177 +  (let [step (fn [n coll]
  1.2178 +               (let [s (seq coll)]
  1.2179 +                 (if (and (pos? n) s)
  1.2180 +                   (recur (dec n) (rest s))
  1.2181 +                   s)))]
  1.2182 +    (lazy-seq (step n coll))))
  1.2183 +
  1.2184 +(defn drop-last
  1.2185 +  "Return a lazy sequence of all but the last n (default 1) items in coll"
  1.2186 +  {:added "1.0"}
  1.2187 +  ([s] (drop-last 1 s))
  1.2188 +  ([n s] (map (fn [x _] x) s (drop n s))))
  1.2189 +
  1.2190 +(defn take-last
  1.2191 +  "Returns a seq of the last n items in coll.  Depending on the type
  1.2192 +  of coll may be no better than linear time.  For vectors, see also subvec."
  1.2193 +  {:added "1.1"}
  1.2194 +  [n coll]
  1.2195 +  (loop [s (seq coll), lead (seq (drop n coll))]
  1.2196 +    (if lead
  1.2197 +      (recur (next s) (next lead))
  1.2198 +      s)))
  1.2199 +
  1.2200 +(defn drop-while
  1.2201 +  "Returns a lazy sequence of the items in coll starting from the first
  1.2202 +  item for which (pred item) returns nil."
  1.2203 +  {:added "1.0"}
  1.2204 +  [pred coll]
  1.2205 +  (let [step (fn [pred coll]
  1.2206 +               (let [s (seq coll)]
  1.2207 +                 (if (and s (pred (first s)))
  1.2208 +                   (recur pred (rest s))
  1.2209 +                   s)))]
  1.2210 +    (lazy-seq (step pred coll))))
  1.2211 +
  1.2212 +(defn cycle
  1.2213 +  "Returns a lazy (infinite!) sequence of repetitions of the items in coll."
  1.2214 +  {:added "1.0"}
  1.2215 +  [coll] (lazy-seq 
  1.2216 +          (when-let [s (seq coll)] 
  1.2217 +              (concat s (cycle s)))))
  1.2218 +
  1.2219 +(defn split-at
  1.2220 +  "Returns a vector of [(take n coll) (drop n coll)]"
  1.2221 +  {:added "1.0"}
  1.2222 +  [n coll]
  1.2223 +    [(take n coll) (drop n coll)])
  1.2224 +
  1.2225 +(defn split-with
  1.2226 +  "Returns a vector of [(take-while pred coll) (drop-while pred coll)]"
  1.2227 +  {:added "1.0"}
  1.2228 +  [pred coll]
  1.2229 +    [(take-while pred coll) (drop-while pred coll)])
  1.2230 +
  1.2231 +(defn repeat
  1.2232 +  "Returns a lazy (infinite!, or length n if supplied) sequence of xs."
  1.2233 +  {:added "1.0"}
  1.2234 +  ([x] (lazy-seq (cons x (repeat x))))
  1.2235 +  ([n x] (take n (repeat x))))
  1.2236 +
  1.2237 +(defn replicate
  1.2238 +  "Returns a lazy seq of n xs."
  1.2239 +  {:added "1.0"}
  1.2240 +  [n x] (take n (repeat x)))
  1.2241 +
  1.2242 +(defn iterate
  1.2243 +  "Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects"
  1.2244 +  {:added "1.0"}
  1.2245 +  [f x] (cons x (lazy-seq (iterate f (f x)))))
  1.2246 +
  1.2247 +(defn range 
  1.2248 +  "Returns a lazy seq of nums from start (inclusive) to end
  1.2249 +  (exclusive), by step, where start defaults to 0, step to 1, and end
  1.2250 +  to infinity."
  1.2251 +  {:added "1.0"}
  1.2252 +  ([] (range 0 Double/POSITIVE_INFINITY 1))
  1.2253 +  ([end] (range 0 end 1))
  1.2254 +  ([start end] (range start end 1))
  1.2255 +  ([start end step]
  1.2256 +   (lazy-seq
  1.2257 +    (let [b (chunk-buffer 32)
  1.2258 +          comp (if (pos? step) < >)]
  1.2259 +      (loop [i start]
  1.2260 +        (if (and (< (count b) 32)
  1.2261 +                 (comp i end))
  1.2262 +          (do
  1.2263 +            (chunk-append b i)
  1.2264 +            (recur (+ i step)))
  1.2265 +          (chunk-cons (chunk b) 
  1.2266 +                      (when (comp i end) 
  1.2267 +                        (range i end step)))))))))
  1.2268 +
  1.2269 +(defn merge
  1.2270 +  "Returns a map that consists of the rest of the maps conj-ed onto
  1.2271 +  the first.  If a key occurs in more than one map, the mapping from
  1.2272 +  the latter (left-to-right) will be the mapping in the result."
  1.2273 +  {:added "1.0"}
  1.2274 +  [& maps]
  1.2275 +  (when (some identity maps)
  1.2276 +    (reduce #(conj (or %1 {}) %2) maps)))
  1.2277 +
  1.2278 +(defn merge-with
  1.2279 +  "Returns a map that consists of the rest of the maps conj-ed onto
  1.2280 +  the first.  If a key occurs in more than one map, the mapping(s)
  1.2281 +  from the latter (left-to-right) will be combined with the mapping in
  1.2282 +  the result by calling (f val-in-result val-in-latter)."
  1.2283 +  {:added "1.0"}
  1.2284 +  [f & maps]
  1.2285 +  (when (some identity maps)
  1.2286 +    (let [merge-entry (fn [m e]
  1.2287 +			(let [k (key e) v (val e)]
  1.2288 +			  (if (contains? m k)
  1.2289 +			    (assoc m k (f (get m k) v))
  1.2290 +			    (assoc m k v))))
  1.2291 +          merge2 (fn [m1 m2]
  1.2292 +		   (reduce merge-entry (or m1 {}) (seq m2)))]
  1.2293 +      (reduce merge2 maps))))
  1.2294 +
  1.2295 +
  1.2296 +
  1.2297 +(defn zipmap
  1.2298 +  "Returns a map with the keys mapped to the corresponding vals."
  1.2299 +  {:added "1.0"}
  1.2300 +  [keys vals]
  1.2301 +    (loop [map {}
  1.2302 +           ks (seq keys)
  1.2303 +           vs (seq vals)]
  1.2304 +      (if (and ks vs)
  1.2305 +        (recur (assoc map (first ks) (first vs))
  1.2306 +               (next ks)
  1.2307 +               (next vs))
  1.2308 +        map)))
  1.2309 +
  1.2310 +(defmacro declare
  1.2311 +  "defs the supplied var names with no bindings, useful for making forward declarations."
  1.2312 +  {:added "1.0"}
  1.2313 +  [& names] `(do ~@(map #(list 'def (vary-meta % assoc :declared true)) names)))
  1.2314 +
  1.2315 +(defn line-seq
  1.2316 +  "Returns the lines of text from rdr as a lazy sequence of strings.
  1.2317 +  rdr must implement java.io.BufferedReader."
  1.2318 +  {:added "1.0"}
  1.2319 +  [^java.io.BufferedReader rdr]
  1.2320 +  (when-let [line (.readLine rdr)]
  1.2321 +    (cons line (lazy-seq (line-seq rdr)))))
  1.2322 +
  1.2323 +(defn comparator
  1.2324 +  "Returns an implementation of java.util.Comparator based upon pred."
  1.2325 +  {:added "1.0"}
  1.2326 +  [pred]
  1.2327 +    (fn [x y]
  1.2328 +      (cond (pred x y) -1 (pred y x) 1 :else 0)))
  1.2329 +
  1.2330 +(defn sort
  1.2331 +  "Returns a sorted sequence of the items in coll. If no comparator is
  1.2332 +  supplied, uses compare. comparator must
  1.2333 +  implement java.util.Comparator."
  1.2334 +  {:added "1.0"}
  1.2335 +  ([coll]
  1.2336 +   (sort compare coll))
  1.2337 +  ([^java.util.Comparator comp coll]
  1.2338 +   (if (seq coll)
  1.2339 +     (let [a (to-array coll)]
  1.2340 +       (. java.util.Arrays (sort a comp))
  1.2341 +       (seq a))
  1.2342 +     ())))
  1.2343 +
  1.2344 +(defn sort-by
  1.2345 +  "Returns a sorted sequence of the items in coll, where the sort
  1.2346 +  order is determined by comparing (keyfn item).  If no comparator is
  1.2347 +  supplied, uses compare. comparator must
  1.2348 +  implement java.util.Comparator."
  1.2349 +  {:added "1.0"}
  1.2350 +  ([keyfn coll]
  1.2351 +   (sort-by keyfn compare coll))
  1.2352 +  ([keyfn ^java.util.Comparator comp coll]
  1.2353 +   (sort (fn [x y] (. comp (compare (keyfn x) (keyfn y)))) coll)))
  1.2354 +
  1.2355 +(defn partition
  1.2356 +  "Returns a lazy sequence of lists of n items each, at offsets step
  1.2357 +  apart. If step is not supplied, defaults to n, i.e. the partitions
  1.2358 +  do not overlap. If a pad collection is supplied, use its elements as
  1.2359 +  necessary to complete last partition upto n items. In case there are
  1.2360 +  not enough padding elements, return a partition with less than n items."
  1.2361 +  {:added "1.0"}
  1.2362 +  ([n coll]
  1.2363 +     (partition n n coll))
  1.2364 +  ([n step coll]
  1.2365 +     (lazy-seq
  1.2366 +       (when-let [s (seq coll)]
  1.2367 +         (let [p (take n s)]
  1.2368 +           (when (= n (count p))
  1.2369 +             (cons p (partition n step (drop step s))))))))
  1.2370 +  ([n step pad coll]
  1.2371 +     (lazy-seq
  1.2372 +       (when-let [s (seq coll)]
  1.2373 +         (let [p (take n s)]
  1.2374 +           (if (= n (count p))
  1.2375 +             (cons p (partition n step pad (drop step s)))
  1.2376 +             (list (take n (concat p pad)))))))))
  1.2377 +
  1.2378 +;; evaluation
  1.2379 +
  1.2380 +(defn eval
  1.2381 +  "Evaluates the form data structure (not text!) and returns the result."
  1.2382 +  {:added "1.0"}
  1.2383 +  [form] (. clojure.lang.Compiler (eval form)))
  1.2384 +
  1.2385 +(defmacro doseq
  1.2386 +  "Repeatedly executes body (presumably for side-effects) with
  1.2387 +  bindings and filtering as provided by \"for\".  Does not retain
  1.2388 +  the head of the sequence. Returns nil."
  1.2389 +  {:added "1.0"}
  1.2390 +  [seq-exprs & body]
  1.2391 +  (assert-args doseq
  1.2392 +     (vector? seq-exprs) "a vector for its binding"
  1.2393 +     (even? (count seq-exprs)) "an even number of forms in binding vector")
  1.2394 +  (let [step (fn step [recform exprs]
  1.2395 +               (if-not exprs
  1.2396 +                 [true `(do ~@body)]
  1.2397 +                 (let [k (first exprs)
  1.2398 +                       v (second exprs)]
  1.2399 +                   (if (keyword? k)
  1.2400 +                     (let [steppair (step recform (nnext exprs))
  1.2401 +                           needrec (steppair 0)
  1.2402 +                           subform (steppair 1)]
  1.2403 +                       (cond
  1.2404 +                         (= k :let) [needrec `(let ~v ~subform)]
  1.2405 +                         (= k :while) [false `(when ~v
  1.2406 +                                                ~subform
  1.2407 +                                                ~@(when needrec [recform]))]
  1.2408 +                         (= k :when) [false `(if ~v
  1.2409 +                                               (do
  1.2410 +                                                 ~subform
  1.2411 +                                                 ~@(when needrec [recform]))
  1.2412 +                                               ~recform)]))
  1.2413 +                     (let [seq- (gensym "seq_")
  1.2414 +                           chunk- (with-meta (gensym "chunk_")
  1.2415 +                                             {:tag 'clojure.lang.IChunk})
  1.2416 +                           count- (gensym "count_")
  1.2417 +                           i- (gensym "i_")
  1.2418 +                           recform `(recur (next ~seq-) nil (int 0) (int 0))
  1.2419 +                           steppair (step recform (nnext exprs))
  1.2420 +                           needrec (steppair 0)
  1.2421 +                           subform (steppair 1)
  1.2422 +                           recform-chunk 
  1.2423 +                             `(recur ~seq- ~chunk- ~count- (unchecked-inc ~i-))
  1.2424 +                           steppair-chunk (step recform-chunk (nnext exprs))
  1.2425 +                           subform-chunk (steppair-chunk 1)]
  1.2426 +                       [true
  1.2427 +                        `(loop [~seq- (seq ~v), ~chunk- nil,
  1.2428 +                                ~count- (int 0), ~i- (int 0)]
  1.2429 +                           (if (< ~i- ~count-)
  1.2430 +                             (let [~k (.nth ~chunk- ~i-)]
  1.2431 +                               ~subform-chunk
  1.2432 +                               ~@(when needrec [recform-chunk]))
  1.2433 +                             (when-let [~seq- (seq ~seq-)]
  1.2434 +                               (if (chunked-seq? ~seq-)
  1.2435 +                                 (let [c# (chunk-first ~seq-)]
  1.2436 +                                   (recur (chunk-rest ~seq-) c#
  1.2437 +                                          (int (count c#)) (int 0)))
  1.2438 +                                 (let [~k (first ~seq-)]
  1.2439 +                                   ~subform
  1.2440 +                                   ~@(when needrec [recform]))))))])))))]
  1.2441 +    (nth (step nil (seq seq-exprs)) 1)))
  1.2442 +
  1.2443 +(defn dorun
  1.2444 +  "When lazy sequences are produced via functions that have side
  1.2445 +  effects, any effects other than those needed to produce the first
  1.2446 +  element in the seq do not occur until the seq is consumed. dorun can
  1.2447 +  be used to force any effects. Walks through the successive nexts of
  1.2448 +  the seq, does not retain the head and returns nil."
  1.2449 +  {:added "1.0"}
  1.2450 +  ([coll]
  1.2451 +   (when (seq coll)
  1.2452 +     (recur (next coll))))
  1.2453 +  ([n coll]
  1.2454 +   (when (and (seq coll) (pos? n))
  1.2455 +     (recur (dec n) (next coll)))))
  1.2456 +
  1.2457 +(defn doall
  1.2458 +  "When lazy sequences are produced via functions that have side
  1.2459 +  effects, any effects other than those needed to produce the first
  1.2460 +  element in the seq do not occur until the seq is consumed. doall can
  1.2461 +  be used to force any effects. Walks through the successive nexts of
  1.2462 +  the seq, retains the head and returns it, thus causing the entire
  1.2463 +  seq to reside in memory at one time."
  1.2464 +  {:added "1.0"}
  1.2465 +  ([coll]
  1.2466 +   (dorun coll)
  1.2467 +   coll)
  1.2468 +  ([n coll]
  1.2469 +   (dorun n coll)
  1.2470 +   coll))
  1.2471 +
  1.2472 +(defn await
  1.2473 +  "Blocks the current thread (indefinitely!) until all actions
  1.2474 +  dispatched thus far, from this thread or agent, to the agent(s) have
  1.2475 +  occurred.  Will block on failed agents.  Will never return if
  1.2476 +  a failed agent is restarted with :clear-actions true."
  1.2477 +  {:added "1.0"}
  1.2478 +  [& agents]
  1.2479 +  (io! "await in transaction"
  1.2480 +    (when *agent*
  1.2481 +      (throw (new Exception "Can't await in agent action")))
  1.2482 +    (let [latch (new java.util.concurrent.CountDownLatch (count agents))
  1.2483 +          count-down (fn [agent] (. latch (countDown)) agent)]
  1.2484 +      (doseq [agent agents]
  1.2485 +        (send agent count-down))
  1.2486 +      (. latch (await)))))
  1.2487 +
  1.2488 +(defn await1 [^clojure.lang.Agent a]
  1.2489 +  (when (pos? (.getQueueCount a))
  1.2490 +    (await a))
  1.2491 +    a)
  1.2492 +
  1.2493 +(defn await-for
  1.2494 +  "Blocks the current thread until all actions dispatched thus
  1.2495 +  far (from this thread or agent) to the agents have occurred, or the
  1.2496 +  timeout (in milliseconds) has elapsed. Returns nil if returning due
  1.2497 +  to timeout, non-nil otherwise."
  1.2498 +  {:added "1.0"}
  1.2499 +  [timeout-ms & agents]
  1.2500 +    (io! "await-for in transaction"
  1.2501 +     (when *agent*
  1.2502 +       (throw (new Exception "Can't await in agent action")))
  1.2503 +     (let [latch (new java.util.concurrent.CountDownLatch (count agents))
  1.2504 +           count-down (fn [agent] (. latch (countDown)) agent)]
  1.2505 +       (doseq [agent agents]
  1.2506 +           (send agent count-down))
  1.2507 +       (. latch (await  timeout-ms (. java.util.concurrent.TimeUnit MILLISECONDS))))))
  1.2508 +
  1.2509 +(defmacro dotimes
  1.2510 +  "bindings => name n
  1.2511 +
  1.2512 +  Repeatedly executes body (presumably for side-effects) with name
  1.2513 +  bound to integers from 0 through n-1."
  1.2514 +  {:added "1.0"}
  1.2515 +  [bindings & body]
  1.2516 +  (assert-args dotimes
  1.2517 +     (vector? bindings) "a vector for its binding"
  1.2518 +     (= 2 (count bindings)) "exactly 2 forms in binding vector")
  1.2519 +  (let [i (first bindings)
  1.2520 +        n (second bindings)]
  1.2521 +    `(let [n# (int ~n)]
  1.2522 +       (loop [~i (int 0)]
  1.2523 +         (when (< ~i n#)
  1.2524 +           ~@body
  1.2525 +           (recur (unchecked-inc ~i)))))))
  1.2526 +
  1.2527 +#_(defn into
  1.2528 +  "Returns a new coll consisting of to-coll with all of the items of
  1.2529 +  from-coll conjoined."
  1.2530 +  {:added "1.0"}
  1.2531 +  [to from]
  1.2532 +    (let [ret to items (seq from)]
  1.2533 +      (if items
  1.2534 +        (recur (conj ret (first items)) (next items))
  1.2535 +        ret)))
  1.2536 +
  1.2537 +;;;;;;;;;;;;;;;;;;;;; editable collections ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1.2538 +(defn transient 
  1.2539 +  "Alpha - subject to change.
  1.2540 +  Returns a new, transient version of the collection, in constant time."
  1.2541 +  {:added "1.1"}
  1.2542 +  [^clojure.lang.IEditableCollection coll] 
  1.2543 +  (.asTransient coll))
  1.2544 +
  1.2545 +(defn persistent! 
  1.2546 +  "Alpha - subject to change.
  1.2547 +  Returns a new, persistent version of the transient collection, in
  1.2548 +  constant time. The transient collection cannot be used after this
  1.2549 +  call, any such use will throw an exception."
  1.2550 +  {:added "1.1"}
  1.2551 +  [^clojure.lang.ITransientCollection coll]
  1.2552 +  (.persistent coll))
  1.2553 +
  1.2554 +(defn conj!
  1.2555 +  "Alpha - subject to change.
  1.2556 +  Adds x to the transient collection, and return coll. The 'addition'
  1.2557 +  may happen at different 'places' depending on the concrete type."
  1.2558 +  {:added "1.1"}
  1.2559 +  [^clojure.lang.ITransientCollection coll x]
  1.2560 +  (.conj coll x))
  1.2561 +
  1.2562 +(defn assoc!
  1.2563 +  "Alpha - subject to change.
  1.2564 +  When applied to a transient map, adds mapping of key(s) to
  1.2565 +  val(s). When applied to a transient vector, sets the val at index.
  1.2566 +  Note - index must be <= (count vector). Returns coll."
  1.2567 +  {:added "1.1"}
  1.2568 +  ([^clojure.lang.ITransientAssociative coll key val] (.assoc coll key val))
  1.2569 +  ([^clojure.lang.ITransientAssociative coll key val & kvs]
  1.2570 +   (let [ret (.assoc coll key val)]
  1.2571 +     (if kvs
  1.2572 +       (recur ret (first kvs) (second kvs) (nnext kvs))
  1.2573 +       ret))))
  1.2574 +
  1.2575 +(defn dissoc!
  1.2576 +  "Alpha - subject to change.
  1.2577 +  Returns a transient map that doesn't contain a mapping for key(s)."
  1.2578 +  {:added "1.1"}
  1.2579 +  ([^clojure.lang.ITransientMap map key] (.without map key))
  1.2580 +  ([^clojure.lang.ITransientMap map key & ks]
  1.2581 +   (let [ret (.without map key)]
  1.2582 +     (if ks
  1.2583 +       (recur ret (first ks) (next ks))
  1.2584 +       ret))))
  1.2585 +
  1.2586 +(defn pop!
  1.2587 +  "Alpha - subject to change.
  1.2588 +  Removes the last item from a transient vector. If
  1.2589 +  the collection is empty, throws an exception. Returns coll"
  1.2590 +  {:added "1.1"}
  1.2591 +  [^clojure.lang.ITransientVector coll] 
  1.2592 +  (.pop coll)) 
  1.2593 +
  1.2594 +(defn disj!
  1.2595 +  "Alpha - subject to change.
  1.2596 +  disj[oin]. Returns a transient set of the same (hashed/sorted) type, that
  1.2597 +  does not contain key(s)."
  1.2598 +  {:added "1.1"}
  1.2599 +  ([set] set)
  1.2600 +  ([^clojure.lang.ITransientSet set key]
  1.2601 +   (. set (disjoin key)))
  1.2602 +  ([set key & ks]
  1.2603 +   (let [ret (disj set key)]
  1.2604 +     (if ks
  1.2605 +       (recur ret (first ks) (next ks))
  1.2606 +       ret))))
  1.2607 +
  1.2608 +;redef into with batch support
  1.2609 +(defn into
  1.2610 +  "Returns a new coll consisting of to-coll with all of the items of
  1.2611 +  from-coll conjoined."
  1.2612 +  {:added "1.0"}
  1.2613 +  [to from]
  1.2614 +  (if (instance? clojure.lang.IEditableCollection to)
  1.2615 +    (persistent! (reduce conj! (transient to) from))
  1.2616 +    (reduce conj to from)))
  1.2617 +
  1.2618 +(defmacro import 
  1.2619 +  "import-list => (package-symbol class-name-symbols*)
  1.2620 +
  1.2621 +  For each name in class-name-symbols, adds a mapping from name to the
  1.2622 +  class named by package.name to the current namespace. Use :import in the ns
  1.2623 +  macro in preference to calling this directly."
  1.2624 +  {:added "1.0"}
  1.2625 +  [& import-symbols-or-lists]
  1.2626 +  (let [specs (map #(if (and (seq? %) (= 'quote (first %))) (second %) %) 
  1.2627 +                   import-symbols-or-lists)]
  1.2628 +    `(do ~@(map #(list 'clojure.core/import* %)
  1.2629 +                (reduce (fn [v spec] 
  1.2630 +                          (if (symbol? spec)
  1.2631 +                            (conj v (name spec))
  1.2632 +                            (let [p (first spec) cs (rest spec)]
  1.2633 +                              (into v (map #(str p "." %) cs)))))
  1.2634 +                        [] specs)))))
  1.2635 +
  1.2636 +(defn into-array
  1.2637 +  "Returns an array with components set to the values in aseq. The array's
  1.2638 +  component type is type if provided, or the type of the first value in
  1.2639 +  aseq if present, or Object. All values in aseq must be compatible with
  1.2640 +  the component type. Class objects for the primitive types can be obtained
  1.2641 +  using, e.g., Integer/TYPE."
  1.2642 +  {:added "1.0"}
  1.2643 +  ([aseq]
  1.2644 +     (clojure.lang.RT/seqToTypedArray (seq aseq)))
  1.2645 +  ([type aseq]
  1.2646 +     (clojure.lang.RT/seqToTypedArray type (seq aseq))))
  1.2647 +
  1.2648 +(defn ^{:private true}
  1.2649 +  array [& items]
  1.2650 +    (into-array items))
  1.2651 +
  1.2652 +(defn ^Class class
  1.2653 +  "Returns the Class of x"
  1.2654 +  {:added "1.0"}
  1.2655 +  [^Object x] (if (nil? x) x (. x (getClass))))
  1.2656 +
  1.2657 +(defn type 
  1.2658 +  "Returns the :type metadata of x, or its Class if none"
  1.2659 +  {:added "1.0"}
  1.2660 +  [x]
  1.2661 +  (or (:type (meta x)) (class x)))
  1.2662 +
  1.2663 +(defn num
  1.2664 +  "Coerce to Number"
  1.2665 +  {:tag Number
  1.2666 +   :inline (fn  [x] `(. clojure.lang.Numbers (num ~x)))
  1.2667 +   :added "1.0"}
  1.2668 +  [x] (. clojure.lang.Numbers (num x)))
  1.2669 +
  1.2670 +(defn long
  1.2671 +  "Coerce to long"
  1.2672 +  {:tag Long
  1.2673 +   :inline (fn  [x] `(. clojure.lang.RT (longCast ~x)))
  1.2674 +   :added "1.0"}
  1.2675 +  [^Number x] (clojure.lang.RT/longCast x))
  1.2676 +
  1.2677 +(defn float
  1.2678 +  "Coerce to float"
  1.2679 +  {:tag Float
  1.2680 +   :inline (fn  [x] `(. clojure.lang.RT (floatCast ~x)))
  1.2681 +   :added "1.0"}
  1.2682 +  [^Number x] (clojure.lang.RT/floatCast x))
  1.2683 +
  1.2684 +(defn double
  1.2685 +  "Coerce to double"
  1.2686 +  {:tag Double
  1.2687 +   :inline (fn  [x] `(. clojure.lang.RT (doubleCast ~x)))
  1.2688 +   :added "1.0"}
  1.2689 +  [^Number x] (clojure.lang.RT/doubleCast x))
  1.2690 +
  1.2691 +(defn short
  1.2692 +  "Coerce to short"
  1.2693 +  {:tag Short
  1.2694 +   :inline (fn  [x] `(. clojure.lang.RT (shortCast ~x)))
  1.2695 +   :added "1.0"}
  1.2696 +  [^Number x] (clojure.lang.RT/shortCast x))
  1.2697 +
  1.2698 +(defn byte
  1.2699 +  "Coerce to byte"
  1.2700 +  {:tag Byte
  1.2701 +   :inline (fn  [x] `(. clojure.lang.RT (byteCast ~x)))
  1.2702 +   :added "1.0"}
  1.2703 +  [^Number x] (clojure.lang.RT/byteCast x))
  1.2704 +
  1.2705 +(defn char
  1.2706 +  "Coerce to char"
  1.2707 +  {:tag Character
  1.2708 +   :inline (fn  [x] `(. clojure.lang.RT (charCast ~x)))
  1.2709 +   :added "1.1"}
  1.2710 +  [x] (. clojure.lang.RT (charCast x)))
  1.2711 +
  1.2712 +(defn boolean
  1.2713 +  "Coerce to boolean"
  1.2714 +  {
  1.2715 +   :inline (fn  [x] `(. clojure.lang.RT (booleanCast ~x)))
  1.2716 +   :added "1.0"}
  1.2717 +  [x] (clojure.lang.RT/booleanCast x))
  1.2718 +
  1.2719 +(defn number?
  1.2720 +  "Returns true if x is a Number"
  1.2721 +  {:added "1.0"}
  1.2722 +  [x]
  1.2723 +  (instance? Number x))
  1.2724 +
  1.2725 +(defn integer?
  1.2726 +  "Returns true if n is an integer"
  1.2727 +  {:added "1.0"}
  1.2728 +  [n]
  1.2729 +  (or (instance? Integer n)
  1.2730 +      (instance? Long n)
  1.2731 +      (instance? BigInteger n)
  1.2732 +      (instance? Short n)
  1.2733 +      (instance? Byte n)))
  1.2734 +
  1.2735 +(defn mod
  1.2736 +  "Modulus of num and div. Truncates toward negative infinity."
  1.2737 +  {:added "1.0"}
  1.2738 +  [num div] 
  1.2739 +  (let [m (rem num div)] 
  1.2740 +    (if (or (zero? m) (pos? (* num div))) 
  1.2741 +      m 
  1.2742 +      (+ m div))))
  1.2743 +
  1.2744 +(defn ratio?
  1.2745 +  "Returns true if n is a Ratio"
  1.2746 +  {:added "1.0"}
  1.2747 +  [n] (instance? clojure.lang.Ratio n))
  1.2748 +
  1.2749 +(defn numerator
  1.2750 +  "Returns the numerator part of a Ratio."
  1.2751 +  {:tag BigInteger
  1.2752 +   :added "1.2"}
  1.2753 +  [r]
  1.2754 +  (.numerator ^clojure.lang.Ratio r))
  1.2755 +
  1.2756 +(defn denominator
  1.2757 +  "Returns the denominator part of a Ratio."
  1.2758 +  {:tag BigInteger
  1.2759 +   :added "1.2"}
  1.2760 +  [r]
  1.2761 +  (.denominator ^clojure.lang.Ratio r))
  1.2762 +
  1.2763 +(defn decimal?
  1.2764 +  "Returns true if n is a BigDecimal"
  1.2765 +  {:added "1.0"}
  1.2766 +  [n] (instance? BigDecimal n))
  1.2767 +
  1.2768 +(defn float?
  1.2769 +  "Returns true if n is a floating point number"
  1.2770 +  {:added "1.0"}
  1.2771 +  [n]
  1.2772 +  (or (instance? Double n)
  1.2773 +      (instance? Float n)))
  1.2774 +
  1.2775 +(defn rational? [n]
  1.2776 +  "Returns true if n is a rational number"
  1.2777 +  {:added "1.0"}
  1.2778 +  (or (integer? n) (ratio? n) (decimal? n)))
  1.2779 +
  1.2780 +(defn bigint
  1.2781 +  "Coerce to BigInteger"
  1.2782 +  {:tag BigInteger
  1.2783 +   :added "1.0"}
  1.2784 +  [x] (cond
  1.2785 +       (instance? BigInteger x) x
  1.2786 +       (decimal? x) (.toBigInteger ^BigDecimal x)
  1.2787 +       (ratio? x) (.bigIntegerValue ^clojure.lang.Ratio x)
  1.2788 +       (number? x) (BigInteger/valueOf (long x))
  1.2789 +       :else (BigInteger. x)))
  1.2790 +
  1.2791 +(defn bigdec
  1.2792 +  "Coerce to BigDecimal"
  1.2793 +  {:tag BigDecimal
  1.2794 +   :added "1.0"}
  1.2795 +  [x] (cond
  1.2796 +       (decimal? x) x
  1.2797 +       (float? x) (. BigDecimal valueOf (double x))
  1.2798 +       (ratio? x) (/ (BigDecimal. (.numerator x)) (.denominator x))
  1.2799 +       (instance? BigInteger x) (BigDecimal. ^BigInteger x)
  1.2800 +       (number? x) (BigDecimal/valueOf (long x))
  1.2801 +       :else (BigDecimal. x)))
  1.2802 +
  1.2803 +(def ^{:private true} print-initialized false)
  1.2804 +
  1.2805 +(defmulti print-method (fn [x writer] (type x)))
  1.2806 +(defmulti print-dup (fn [x writer] (class x)))
  1.2807 +
  1.2808 +(defn pr-on
  1.2809 +  {:private true}
  1.2810 +  [x w]
  1.2811 +  (if *print-dup*
  1.2812 +    (print-dup x w)
  1.2813 +    (print-method x w))
  1.2814 +  nil)
  1.2815 +
  1.2816 +(defn pr
  1.2817 +  "Prints the object(s) to the output stream that is the current value
  1.2818 +  of *out*.  Prints the object(s), separated by spaces if there is
  1.2819 +  more than one.  By default, pr and prn print in a way that objects
  1.2820 +  can be read by the reader"
  1.2821 +  {:dynamic true
  1.2822 +   :added "1.0"}
  1.2823 +  ([] nil)
  1.2824 +  ([x]
  1.2825 +     (pr-on x *out*))
  1.2826 +  ([x & more]
  1.2827 +   (pr x)
  1.2828 +   (. *out* (append \space))
  1.2829 +   (if-let [nmore (next more)]
  1.2830 +     (recur (first more) nmore)
  1.2831 +     (apply pr more))))
  1.2832 +
  1.2833 +(defn newline
  1.2834 +  "Writes a newline to the output stream that is the current value of
  1.2835 +  *out*"
  1.2836 +  {:added "1.0"}
  1.2837 +  []
  1.2838 +    (. *out* (append \newline))
  1.2839 +    nil)
  1.2840 +
  1.2841 +(defn flush
  1.2842 +  "Flushes the output stream that is the current value of
  1.2843 +  *out*"
  1.2844 +  {:added "1.0"}
  1.2845 +  []
  1.2846 +    (. *out* (flush))
  1.2847 +    nil)
  1.2848 +
  1.2849 +(defn prn
  1.2850 +  "Same as pr followed by (newline). Observes *flush-on-newline*"
  1.2851 +  {:added "1.0"}
  1.2852 +  [& more]
  1.2853 +    (apply pr more)
  1.2854 +    (newline)
  1.2855 +    (when *flush-on-newline*
  1.2856 +      (flush)))
  1.2857 +
  1.2858 +(defn print
  1.2859 +  "Prints the object(s) to the output stream that is the current value
  1.2860 +  of *out*.  print and println produce output for human consumption."
  1.2861 +  {:added "1.0"}
  1.2862 +  [& more]
  1.2863 +    (binding [*print-readably* nil]
  1.2864 +      (apply pr more)))
  1.2865 +
  1.2866 +(defn println
  1.2867 +  "Same as print followed by (newline)"
  1.2868 +  {:added "1.0"}
  1.2869 +  [& more]
  1.2870 +    (binding [*print-readably* nil]
  1.2871 +      (apply prn more)))
  1.2872 +
  1.2873 +(defn read
  1.2874 +  "Reads the next object from stream, which must be an instance of
  1.2875 +  java.io.PushbackReader or some derivee.  stream defaults to the
  1.2876 +  current value of *in* ."
  1.2877 +  {:added "1.0"}
  1.2878 +  ([]
  1.2879 +   (read *in*))
  1.2880 +  ([stream]
  1.2881 +   (read stream true nil))
  1.2882 +  ([stream eof-error? eof-value]
  1.2883 +   (read stream eof-error? eof-value false))
  1.2884 +  ([stream eof-error? eof-value recursive?]
  1.2885 +   (. clojure.lang.LispReader (read stream (boolean eof-error?) eof-value recursive?))))
  1.2886 +
  1.2887 +(defn read-line
  1.2888 +  "Reads the next line from stream that is the current value of *in* ."
  1.2889 +  {:added "1.0"}
  1.2890 +  []
  1.2891 +  (if (instance? clojure.lang.LineNumberingPushbackReader *in*)
  1.2892 +    (.readLine ^clojure.lang.LineNumberingPushbackReader *in*)
  1.2893 +    (.readLine ^java.io.BufferedReader *in*)))
  1.2894 +
  1.2895 +(defn read-string
  1.2896 +  "Reads one object from the string s"
  1.2897 +  {:added "1.0"}
  1.2898 +  [s] (clojure.lang.RT/readString s))
  1.2899 +
  1.2900 +(defn subvec
  1.2901 +  "Returns a persistent vector of the items in vector from
  1.2902 +  start (inclusive) to end (exclusive).  If end is not supplied,
  1.2903 +  defaults to (count vector). This operation is O(1) and very fast, as
  1.2904 +  the resulting vector shares structure with the original and no
  1.2905 +  trimming is done."
  1.2906 +  {:added "1.0"}
  1.2907 +  ([v start]
  1.2908 +   (subvec v start (count v)))
  1.2909 +  ([v start end]
  1.2910 +   (. clojure.lang.RT (subvec v start end))))
  1.2911 +
  1.2912 +(defmacro with-open
  1.2913 +  "bindings => [name init ...]
  1.2914 +
  1.2915 +  Evaluates body in a try expression with names bound to the values
  1.2916 +  of the inits, and a finally clause that calls (.close name) on each
  1.2917 +  name in reverse order."
  1.2918 +  {:added "1.0"}
  1.2919 +  [bindings & body]
  1.2920 +  (assert-args with-open
  1.2921 +     (vector? bindings) "a vector for its binding"
  1.2922 +     (even? (count bindings)) "an even number of forms in binding vector")
  1.2923 +  (cond
  1.2924 +    (= (count bindings) 0) `(do ~@body)
  1.2925 +    (symbol? (bindings 0)) `(let ~(subvec bindings 0 2)
  1.2926 +                              (try
  1.2927 +                                (with-open ~(subvec bindings 2) ~@body)
  1.2928 +                                (finally
  1.2929 +                                  (. ~(bindings 0) close))))
  1.2930 +    :else (throw (IllegalArgumentException.
  1.2931 +                   "with-open only allows Symbols in bindings"))))
  1.2932 +
  1.2933 +(defmacro doto
  1.2934 +  "Evaluates x then calls all of the methods and functions with the
  1.2935 +  value of x supplied at the front of the given arguments.  The forms
  1.2936 +  are evaluated in order.  Returns x.
  1.2937 +
  1.2938 +  (doto (new java.util.HashMap) (.put \"a\" 1) (.put \"b\" 2))"
  1.2939 +  {:added "1.0"}
  1.2940 +  [x & forms]
  1.2941 +    (let [gx (gensym)]
  1.2942 +      `(let [~gx ~x]
  1.2943 +         ~@(map (fn [f]
  1.2944 +                  (if (seq? f)
  1.2945 +                    `(~(first f) ~gx ~@(next f))
  1.2946 +                    `(~f ~gx)))
  1.2947 +                forms)
  1.2948 +         ~gx)))
  1.2949 +
  1.2950 +(defmacro memfn
  1.2951 +  "Expands into code that creates a fn that expects to be passed an
  1.2952 +  object and any args and calls the named instance method on the
  1.2953 +  object passing the args. Use when you want to treat a Java method as
  1.2954 +  a first-class fn."
  1.2955 +  {:added "1.0"}
  1.2956 +  [name & args]
  1.2957 +  `(fn [target# ~@args]
  1.2958 +     (. target# (~name ~@args))))
  1.2959 +
  1.2960 +(defmacro time
  1.2961 +  "Evaluates expr and prints the time it took.  Returns the value of
  1.2962 + expr."
  1.2963 +  {:added "1.0"}
  1.2964 +  [expr]
  1.2965 +  `(let [start# (. System (nanoTime))
  1.2966 +         ret# ~expr]
  1.2967 +     (prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs"))
  1.2968 +     ret#))
  1.2969 +
  1.2970 +
  1.2971 +
  1.2972 +(import '(java.lang.reflect Array))
  1.2973 +
  1.2974 +(defn alength
  1.2975 +  "Returns the length of the Java array. Works on arrays of all
  1.2976 +  types."
  1.2977 +  {:inline (fn [a] `(. clojure.lang.RT (alength ~a)))
  1.2978 +   :added "1.0"}
  1.2979 +  [array] (. clojure.lang.RT (alength array)))
  1.2980 +
  1.2981 +(defn aclone
  1.2982 +  "Returns a clone of the Java array. Works on arrays of known
  1.2983 +  types."
  1.2984 +  {:inline (fn [a] `(. clojure.lang.RT (aclone ~a)))
  1.2985 +   :added "1.0"}
  1.2986 +  [array] (. clojure.lang.RT (aclone array)))
  1.2987 +
  1.2988 +(defn aget
  1.2989 +  "Returns the value at the index/indices. Works on Java arrays of all
  1.2990 +  types."
  1.2991 +  {:inline (fn [a i] `(. clojure.lang.RT (aget ~a (int ~i))))
  1.2992 +   :inline-arities #{2}
  1.2993 +   :added "1.0"}
  1.2994 +  ([array idx]
  1.2995 +   (clojure.lang.Reflector/prepRet (. Array (get array idx))))
  1.2996 +  ([array idx & idxs]
  1.2997 +   (apply aget (aget array idx) idxs)))
  1.2998 +
  1.2999 +(defn aset
  1.3000 +  "Sets the value at the index/indices. Works on Java arrays of
  1.3001 +  reference types. Returns val."
  1.3002 +  {:inline (fn [a i v] `(. clojure.lang.RT (aset ~a (int ~i) ~v)))
  1.3003 +   :inline-arities #{3}
  1.3004 +   :added "1.0"}
  1.3005 +  ([array idx val]
  1.3006 +   (. Array (set array idx val))
  1.3007 +   val)
  1.3008 +  ([array idx idx2 & idxv]
  1.3009 +   (apply aset (aget array idx) idx2 idxv)))
  1.3010 +
  1.3011 +(defmacro
  1.3012 +  ^{:private true}
  1.3013 +  def-aset [name method coerce]
  1.3014 +    `(defn ~name
  1.3015 +       {:arglists '([~'array ~'idx ~'val] [~'array ~'idx ~'idx2 & ~'idxv])}
  1.3016 +       ([array# idx# val#]
  1.3017 +        (. Array (~method array# idx# (~coerce val#)))
  1.3018 +        val#)
  1.3019 +       ([array# idx# idx2# & idxv#]
  1.3020 +        (apply ~name (aget array# idx#) idx2# idxv#))))
  1.3021 +
  1.3022 +(def-aset
  1.3023 +  ^{:doc "Sets the value at the index/indices. Works on arrays of int. Returns val."
  1.3024 +    :added "1.0"}
  1.3025 +  aset-int setInt int)
  1.3026 +
  1.3027 +(def-aset
  1.3028 +  ^{:doc "Sets the value at the index/indices. Works on arrays of long. Returns val."
  1.3029 +    :added "1.0"}
  1.3030 +  aset-long setLong long)
  1.3031 +
  1.3032 +(def-aset
  1.3033 +  ^{:doc "Sets the value at the index/indices. Works on arrays of boolean. Returns val."
  1.3034 +    :added "1.0"}
  1.3035 +  aset-boolean setBoolean boolean)
  1.3036 +
  1.3037 +(def-aset
  1.3038 +  ^{:doc "Sets the value at the index/indices. Works on arrays of float. Returns val."
  1.3039 +    :added "1.0"}
  1.3040 +  aset-float setFloat float)
  1.3041 +
  1.3042 +(def-aset
  1.3043 +  ^{:doc "Sets the value at the index/indices. Works on arrays of double. Returns val."
  1.3044 +    :added "1.0"}
  1.3045 +  aset-double setDouble double)
  1.3046 +
  1.3047 +(def-aset
  1.3048 +  ^{:doc "Sets the value at the index/indices. Works on arrays of short. Returns val."
  1.3049 +    :added "1.0"}
  1.3050 +  aset-short setShort short)
  1.3051 +
  1.3052 +(def-aset
  1.3053 +  ^{:doc "Sets the value at the index/indices. Works on arrays of byte. Returns val."
  1.3054 +    :added "1.0"}
  1.3055 +  aset-byte setByte byte)
  1.3056 +
  1.3057 +(def-aset
  1.3058 +  ^{:doc "Sets the value at the index/indices. Works on arrays of char. Returns val."
  1.3059 +    :added "1.0"}
  1.3060 +  aset-char setChar char)
  1.3061 +
  1.3062 +(defn make-array
  1.3063 +  "Creates and returns an array of instances of the specified class of
  1.3064 +  the specified dimension(s).  Note that a class object is required.
  1.3065 +  Class objects can be obtained by using their imported or
  1.3066 +  fully-qualified name.  Class objects for the primitive types can be
  1.3067 +  obtained using, e.g., Integer/TYPE."
  1.3068 +  {:added "1.0"}
  1.3069 +  ([^Class type len]
  1.3070 +   (. Array (newInstance type (int len))))
  1.3071 +  ([^Class type dim & more-dims]
  1.3072 +   (let [dims (cons dim more-dims)
  1.3073 +         ^"[I" dimarray (make-array (. Integer TYPE)  (count dims))]
  1.3074 +     (dotimes [i (alength dimarray)]
  1.3075 +       (aset-int dimarray i (nth dims i)))
  1.3076 +     (. Array (newInstance type dimarray)))))
  1.3077 +
  1.3078 +(defn to-array-2d
  1.3079 +  "Returns a (potentially-ragged) 2-dimensional array of Objects
  1.3080 +  containing the contents of coll, which can be any Collection of any
  1.3081 +  Collection."
  1.3082 +  {:tag "[[Ljava.lang.Object;"
  1.3083 +   :added "1.0"}
  1.3084 +  [^java.util.Collection coll]
  1.3085 +    (let [ret (make-array (. Class (forName "[Ljava.lang.Object;")) (. coll (size)))]
  1.3086 +      (loop [i 0 xs (seq coll)]
  1.3087 +        (when xs
  1.3088 +          (aset ret i (to-array (first xs)))
  1.3089 +          (recur (inc i) (next xs))))
  1.3090 +      ret))
  1.3091 +
  1.3092 +(defn macroexpand-1
  1.3093 +  "If form represents a macro form, returns its expansion,
  1.3094 +  else returns form."
  1.3095 +  {:added "1.0"}
  1.3096 +  [form]
  1.3097 +    (. clojure.lang.Compiler (macroexpand1 form)))
  1.3098 +
  1.3099 +(defn macroexpand
  1.3100 +  "Repeatedly calls macroexpand-1 on form until it no longer
  1.3101 +  represents a macro form, then returns it.  Note neither
  1.3102 +  macroexpand-1 nor macroexpand expand macros in subforms."
  1.3103 +  {:added "1.0"}
  1.3104 +  [form]
  1.3105 +    (let [ex (macroexpand-1 form)]
  1.3106 +      (if (identical? ex form)
  1.3107 +        form
  1.3108 +        (macroexpand ex))))
  1.3109 +
  1.3110 +(defn create-struct
  1.3111 +  "Returns a structure basis object."
  1.3112 +  {:added "1.0"}
  1.3113 +  [& keys]
  1.3114 +    (. clojure.lang.PersistentStructMap (createSlotMap keys)))
  1.3115 +
  1.3116 +(defmacro defstruct
  1.3117 +  "Same as (def name (create-struct keys...))"
  1.3118 +  {:added "1.0"}
  1.3119 +  [name & keys]
  1.3120 +  `(def ~name (create-struct ~@keys)))
  1.3121 +
  1.3122 +(defn struct-map
  1.3123 +  "Returns a new structmap instance with the keys of the
  1.3124 +  structure-basis. keyvals may contain all, some or none of the basis
  1.3125 +  keys - where values are not supplied they will default to nil.
  1.3126 +  keyvals can also contain keys not in the basis."
  1.3127 +  {:added "1.0"}
  1.3128 +  [s & inits]
  1.3129 +    (. clojure.lang.PersistentStructMap (create s inits)))
  1.3130 +
  1.3131 +(defn struct
  1.3132 +  "Returns a new structmap instance with the keys of the
  1.3133 +  structure-basis. vals must be supplied for basis keys in order -
  1.3134 +  where values are not supplied they will default to nil."
  1.3135 +  {:added "1.0"}
  1.3136 +  [s & vals]
  1.3137 +    (. clojure.lang.PersistentStructMap (construct s vals)))
  1.3138 +
  1.3139 +(defn accessor
  1.3140 +  "Returns a fn that, given an instance of a structmap with the basis,
  1.3141 +  returns the value at the key.  The key must be in the basis. The
  1.3142 +  returned function should be (slightly) more efficient than using
  1.3143 +  get, but such use of accessors should be limited to known
  1.3144 +  performance-critical areas."
  1.3145 +  {:added "1.0"}
  1.3146 +  [s key]
  1.3147 +    (. clojure.lang.PersistentStructMap (getAccessor s key)))
  1.3148 +
  1.3149 +(defn load-reader
  1.3150 +  "Sequentially read and evaluate the set of forms contained in the
  1.3151 +  stream/file"
  1.3152 +  {:added "1.0"}
  1.3153 +  [rdr] (. clojure.lang.Compiler (load rdr)))
  1.3154 +
  1.3155 +(defn load-string
  1.3156 +  "Sequentially read and evaluate the set of forms contained in the
  1.3157 +  string"
  1.3158 +  {:added "1.0"}
  1.3159 +  [s]
  1.3160 +  (let [rdr (-> (java.io.StringReader. s)
  1.3161 +                (clojure.lang.LineNumberingPushbackReader.))]
  1.3162 +    (load-reader rdr)))
  1.3163 +
  1.3164 +(defn set
  1.3165 +  "Returns a set of the distinct elements of coll."
  1.3166 +  {:added "1.0"}
  1.3167 +  [coll] (clojure.lang.PersistentHashSet/create ^clojure.lang.ISeq (seq coll)))
  1.3168 +
  1.3169 +(defn ^{:private true}
  1.3170 +  filter-key [keyfn pred amap]
  1.3171 +    (loop [ret {} es (seq amap)]
  1.3172 +      (if es
  1.3173 +        (if (pred (keyfn (first es)))
  1.3174 +          (recur (assoc ret (key (first es)) (val (first es))) (next es))
  1.3175 +          (recur ret (next es)))
  1.3176 +        ret)))
  1.3177 +
  1.3178 +(defn find-ns
  1.3179 +  "Returns the namespace named by the symbol or nil if it doesn't exist."
  1.3180 +  {:added "1.0"}
  1.3181 +  [sym] (clojure.lang.Namespace/find sym))
  1.3182 +
  1.3183 +(defn create-ns
  1.3184 +  "Create a new namespace named by the symbol if one doesn't already
  1.3185 +  exist, returns it or the already-existing namespace of the same
  1.3186 +  name."
  1.3187 +  {:added "1.0"}
  1.3188 +  [sym] (clojure.lang.Namespace/findOrCreate sym))
  1.3189 +
  1.3190 +(defn remove-ns
  1.3191 +  "Removes the namespace named by the symbol. Use with caution.
  1.3192 +  Cannot be used to remove the clojure namespace."
  1.3193 +  {:added "1.0"}
  1.3194 +  [sym] (clojure.lang.Namespace/remove sym))
  1.3195 +
  1.3196 +(defn all-ns
  1.3197 +  "Returns a sequence of all namespaces."
  1.3198 +  {:added "1.0"}
  1.3199 +  [] (clojure.lang.Namespace/all))
  1.3200 +
  1.3201 +(defn ^clojure.lang.Namespace the-ns
  1.3202 +  "If passed a namespace, returns it. Else, when passed a symbol,
  1.3203 +  returns the namespace named by it, throwing an exception if not
  1.3204 +  found."
  1.3205 +  {:added "1.0"}
  1.3206 +  [x]
  1.3207 +  (if (instance? clojure.lang.Namespace x)
  1.3208 +    x
  1.3209 +    (or (find-ns x) (throw (Exception. (str "No namespace: " x " found"))))))
  1.3210 +
  1.3211 +(defn ns-name
  1.3212 +  "Returns the name of the namespace, a symbol."
  1.3213 +  {:added "1.0"}
  1.3214 +  [ns]
  1.3215 +  (.getName (the-ns ns)))
  1.3216 +
  1.3217 +(defn ns-map
  1.3218 +  "Returns a map of all the mappings for the namespace."
  1.3219 +  {:added "1.0"}
  1.3220 +  [ns]
  1.3221 +  (.getMappings (the-ns ns)))
  1.3222 +
  1.3223 +(defn ns-unmap
  1.3224 +  "Removes the mappings for the symbol from the namespace."
  1.3225 +  {:added "1.0"}
  1.3226 +  [ns sym]
  1.3227 +  (.unmap (the-ns ns) sym))
  1.3228 +
  1.3229 +;(defn export [syms]
  1.3230 +;  (doseq [sym syms]
  1.3231 +;   (.. *ns* (intern sym) (setExported true))))
  1.3232 +
  1.3233 +(defn ns-publics
  1.3234 +  "Returns a map of the public intern mappings for the namespace."
  1.3235 +  {:added "1.0"}
  1.3236 +  [ns]
  1.3237 +  (let [ns (the-ns ns)]
  1.3238 +    (filter-key val (fn [^clojure.lang.Var v] (and (instance? clojure.lang.Var v)
  1.3239 +                                 (= ns (.ns v))
  1.3240 +                                 (.isPublic v)))
  1.3241 +                (ns-map ns))))
  1.3242 +
  1.3243 +(defn ns-imports
  1.3244 +  "Returns a map of the import mappings for the namespace."
  1.3245 +  {:added "1.0"}
  1.3246 +  [ns]
  1.3247 +  (filter-key val (partial instance? Class) (ns-map ns)))
  1.3248 +
  1.3249 +(defn ns-interns
  1.3250 +  "Returns a map of the intern mappings for the namespace."
  1.3251 +  {:added "1.0"}
  1.3252 +  [ns]
  1.3253 +  (let [ns (the-ns ns)]
  1.3254 +    (filter-key val (fn [^clojure.lang.Var v] (and (instance? clojure.lang.Var v)
  1.3255 +                                 (= ns (.ns v))))
  1.3256 +                (ns-map ns))))
  1.3257 +
  1.3258 +(defn refer
  1.3259 +  "refers to all public vars of ns, subject to filters.
  1.3260 +  filters can include at most one each of:
  1.3261 +
  1.3262 +  :exclude list-of-symbols
  1.3263 +  :only list-of-symbols
  1.3264 +  :rename map-of-fromsymbol-tosymbol
  1.3265 +
  1.3266 +  For each public interned var in the namespace named by the symbol,
  1.3267 +  adds a mapping from the name of the var to the var to the current
  1.3268 +  namespace.  Throws an exception if name is already mapped to
  1.3269 +  something else in the current namespace. Filters can be used to
  1.3270 +  select a subset, via inclusion or exclusion, or to provide a mapping
  1.3271 +  to a symbol different from the var's name, in order to prevent
  1.3272 +  clashes. Use :use in the ns macro in preference to calling this directly."
  1.3273 +  {:added "1.0"}
  1.3274 +  [ns-sym & filters]
  1.3275 +    (let [ns (or (find-ns ns-sym) (throw (new Exception (str "No namespace: " ns-sym))))
  1.3276 +          fs (apply hash-map filters)
  1.3277 +          nspublics (ns-publics ns)
  1.3278 +          rename (or (:rename fs) {})
  1.3279 +          exclude (set (:exclude fs))
  1.3280 +          to-do (or (:only fs) (keys nspublics))]
  1.3281 +      (doseq [sym to-do]
  1.3282 +        (when-not (exclude sym)
  1.3283 +          (let [v (nspublics sym)]
  1.3284 +            (when-not v
  1.3285 +              (throw (new java.lang.IllegalAccessError
  1.3286 +                          (if (get (ns-interns ns) sym)
  1.3287 +                            (str sym " is not public")
  1.3288 +                            (str sym " does not exist")))))
  1.3289 +            (. *ns* (refer (or (rename sym) sym) v)))))))
  1.3290 +
  1.3291 +(defn ns-refers
  1.3292 +  "Returns a map of the refer mappings for the namespace."
  1.3293 +  {:added "1.0"}
  1.3294 +  [ns]
  1.3295 +  (let [ns (the-ns ns)]
  1.3296 +    (filter-key val (fn [^clojure.lang.Var v] (and (instance? clojure.lang.Var v)
  1.3297 +                                 (not= ns (.ns v))))
  1.3298 +                (ns-map ns))))
  1.3299 +
  1.3300 +(defn alias
  1.3301 +  "Add an alias in the current namespace to another
  1.3302 +  namespace. Arguments are two symbols: the alias to be used, and
  1.3303 +  the symbolic name of the target namespace. Use :as in the ns macro in preference
  1.3304 +  to calling this directly."
  1.3305 +  {:added "1.0"}
  1.3306 +  [alias namespace-sym]
  1.3307 +  (.addAlias *ns* alias (find-ns namespace-sym)))
  1.3308 +
  1.3309 +(defn ns-aliases
  1.3310 +  "Returns a map of the aliases for the namespace."
  1.3311 +  {:added "1.0"}
  1.3312 +  [ns]
  1.3313 +  (.getAliases (the-ns ns)))
  1.3314 +
  1.3315 +(defn ns-unalias
  1.3316 +  "Removes the alias for the symbol from the namespace."
  1.3317 +  {:added "1.0"}
  1.3318 +  [ns sym]
  1.3319 +  (.removeAlias (the-ns ns) sym))
  1.3320 +
  1.3321 +(defn take-nth
  1.3322 +  "Returns a lazy seq of every nth item in coll."
  1.3323 +  {:added "1.0"}
  1.3324 +  [n coll]
  1.3325 +    (lazy-seq
  1.3326 +     (when-let [s (seq coll)]
  1.3327 +       (cons (first s) (take-nth n (drop n s))))))
  1.3328 +
  1.3329 +(defn interleave
  1.3330 +  "Returns a lazy seq of the first item in each coll, then the second etc."
  1.3331 +  {:added "1.0"}
  1.3332 +  ([c1 c2]
  1.3333 +     (lazy-seq
  1.3334 +      (let [s1 (seq c1) s2 (seq c2)]
  1.3335 +        (when (and s1 s2)
  1.3336 +          (cons (first s1) (cons (first s2) 
  1.3337 +                                 (interleave (rest s1) (rest s2))))))))
  1.3338 +  ([c1 c2 & colls] 
  1.3339 +     (lazy-seq 
  1.3340 +      (let [ss (map seq (conj colls c2 c1))]
  1.3341 +        (when (every? identity ss)
  1.3342 +          (concat (map first ss) (apply interleave (map rest ss))))))))
  1.3343 +
  1.3344 +(defn var-get
  1.3345 +  "Gets the value in the var object"
  1.3346 +  {:added "1.0"}
  1.3347 +  [^clojure.lang.Var x] (. x (get)))
  1.3348 +
  1.3349 +(defn var-set
  1.3350 +  "Sets the value in the var object to val. The var must be
  1.3351 + thread-locally bound."
  1.3352 +  {:added "1.0"}
  1.3353 +  [^clojure.lang.Var x val] (. x (set val)))
  1.3354 +
  1.3355 +(defmacro with-local-vars
  1.3356 +  "varbinding=> symbol init-expr
  1.3357 +
  1.3358 +  Executes the exprs in a context in which the symbols are bound to
  1.3359 +  vars with per-thread bindings to the init-exprs.  The symbols refer
  1.3360 +  to the var objects themselves, and must be accessed with var-get and
  1.3361 +  var-set"
  1.3362 +  {:added "1.0"}
  1.3363 +  [name-vals-vec & body]
  1.3364 +  (assert-args with-local-vars
  1.3365 +     (vector? name-vals-vec) "a vector for its binding"
  1.3366 +     (even? (count name-vals-vec)) "an even number of forms in binding vector")
  1.3367 +  `(let [~@(interleave (take-nth 2 name-vals-vec)
  1.3368 +                       (repeat '(. clojure.lang.Var (create))))]
  1.3369 +     (. clojure.lang.Var (pushThreadBindings (hash-map ~@name-vals-vec)))
  1.3370 +     (try
  1.3371 +      ~@body
  1.3372 +      (finally (. clojure.lang.Var (popThreadBindings))))))
  1.3373 +
  1.3374 +(defn ns-resolve
  1.3375 +  "Returns the var or Class to which a symbol will be resolved in the
  1.3376 +  namespace, else nil.  Note that if the symbol is fully qualified,
  1.3377 +  the var/Class to which it resolves need not be present in the
  1.3378 +  namespace."
  1.3379 +  {:added "1.0"}
  1.3380 +  [ns sym]
  1.3381 +  (clojure.lang.Compiler/maybeResolveIn (the-ns ns) sym))
  1.3382 +
  1.3383 +(defn resolve
  1.3384 +  "same as (ns-resolve *ns* symbol)"
  1.3385 +  {:added "1.0"}
  1.3386 +  [sym] (ns-resolve *ns* sym))
  1.3387 +
  1.3388 +(defn array-map
  1.3389 +  "Constructs an array-map."
  1.3390 +  {:added "1.0"}
  1.3391 +  ([] (. clojure.lang.PersistentArrayMap EMPTY))
  1.3392 +  ([& keyvals] (clojure.lang.PersistentArrayMap/createWithCheck (to-array keyvals))))
  1.3393 +
  1.3394 +(defn nthnext
  1.3395 +  "Returns the nth next of coll, (seq coll) when n is 0."
  1.3396 +  {:added "1.0"}
  1.3397 +  [coll n]
  1.3398 +    (loop [n n xs (seq coll)]
  1.3399 +      (if (and xs (pos? n))
  1.3400 +        (recur (dec n) (next xs))
  1.3401 +        xs)))
  1.3402 +
  1.3403 +
  1.3404 +;redefine let and loop  with destructuring
  1.3405 +(defn destructure [bindings]
  1.3406 +  (let [bents (partition 2 bindings)
  1.3407 +        pb (fn pb [bvec b v]
  1.3408 +               (let [pvec
  1.3409 +                     (fn [bvec b val]
  1.3410 +                       (let [gvec (gensym "vec__")]
  1.3411 +                         (loop [ret (-> bvec (conj gvec) (conj val))
  1.3412 +                                n 0
  1.3413 +                                bs b
  1.3414 +                                seen-rest? false]
  1.3415 +                           (if (seq bs)
  1.3416 +                             (let [firstb (first bs)]
  1.3417 +                               (cond
  1.3418 +                                (= firstb '&) (recur (pb ret (second bs) (list `nthnext gvec n))
  1.3419 +                                                     n
  1.3420 +                                                     (nnext bs)
  1.3421 +                                                     true)
  1.3422 +                                (= firstb :as) (pb ret (second bs) gvec)
  1.3423 +                                :else (if seen-rest?
  1.3424 +                                        (throw (new Exception "Unsupported binding form, only :as can follow & parameter"))
  1.3425 +                                        (recur (pb ret firstb  (list `nth gvec n nil))
  1.3426 +                                               (inc n)
  1.3427 +                                               (next bs)
  1.3428 +                                               seen-rest?))))
  1.3429 +                             ret))))
  1.3430 +                     pmap
  1.3431 +                     (fn [bvec b v]
  1.3432 +                       (let [gmap (or (:as b) (gensym "map__"))
  1.3433 +                             defaults (:or b)]
  1.3434 +                         (loop [ret (-> bvec (conj gmap) (conj v)
  1.3435 +                                        (conj gmap) (conj `(if (seq? ~gmap) (apply hash-map ~gmap) ~gmap)))
  1.3436 +                                bes (reduce
  1.3437 +                                     (fn [bes entry]
  1.3438 +                                       (reduce #(assoc %1 %2 ((val entry) %2))
  1.3439 +                                               (dissoc bes (key entry))
  1.3440 +                                               ((key entry) bes)))
  1.3441 +                                     (dissoc b :as :or)
  1.3442 +                                     {:keys #(keyword (str %)), :strs str, :syms #(list `quote %)})]
  1.3443 +                           (if (seq bes)
  1.3444 +                             (let [bb (key (first bes))
  1.3445 +                                   bk (val (first bes))
  1.3446 +                                   has-default (contains? defaults bb)]
  1.3447 +                               (recur (pb ret bb (if has-default
  1.3448 +                                                   (list `get gmap bk (defaults bb))
  1.3449 +                                                   (list `get gmap bk)))
  1.3450 +                                      (next bes)))
  1.3451 +                             ret))))]
  1.3452 +                 (cond
  1.3453 +                  (symbol? b) (-> bvec (conj b) (conj v))
  1.3454 +                  (vector? b) (pvec bvec b v)
  1.3455 +                  (map? b) (pmap bvec b v)
  1.3456 +                  :else (throw (new Exception (str "Unsupported binding form: " b))))))
  1.3457 +        process-entry (fn [bvec b] (pb bvec (first b) (second b)))]
  1.3458 +    (if (every? symbol? (map first bents))
  1.3459 +      bindings
  1.3460 +      (reduce process-entry [] bents))))
  1.3461 +
  1.3462 +(defmacro let
  1.3463 +  "Evaluates the exprs in a lexical context in which the symbols in
  1.3464 +  the binding-forms are bound to their respective init-exprs or parts
  1.3465 +  therein."
  1.3466 +  {:added "1.0"}
  1.3467 +  [bindings & body]
  1.3468 +  (assert-args let
  1.3469 +     (vector? bindings) "a vector for its binding"
  1.3470 +     (even? (count bindings)) "an even number of forms in binding vector")
  1.3471 +  `(let* ~(destructure bindings) ~@body))
  1.3472 +
  1.3473 +(defn ^{:private true}
  1.3474 +  maybe-destructured
  1.3475 +  [params body]
  1.3476 +  (if (every? symbol? params)
  1.3477 +    (cons params body)
  1.3478 +    (loop [params params
  1.3479 +           new-params []
  1.3480 +           lets []]
  1.3481 +      (if params
  1.3482 +        (if (symbol? (first params))
  1.3483 +          (recur (next params) (conj new-params (first params)) lets)
  1.3484 +          (let [gparam (gensym "p__")]
  1.3485 +            (recur (next params) (conj new-params gparam)
  1.3486 +                   (-> lets (conj (first params)) (conj gparam)))))
  1.3487 +        `(~new-params
  1.3488 +          (let ~lets
  1.3489 +            ~@body))))))
  1.3490 +
  1.3491 +;redefine fn with destructuring and pre/post conditions
  1.3492 +(defmacro fn
  1.3493 +  "(fn name? [params* ] exprs*)
  1.3494 +  (fn name? ([params* ] exprs*)+)
  1.3495 +
  1.3496 +  params => positional-params* , or positional-params* & next-param
  1.3497 +  positional-param => binding-form
  1.3498 +  next-param => binding-form
  1.3499 +  name => symbol
  1.3500 +
  1.3501 +  Defines a function"
  1.3502 +  {:added "1.0"}
  1.3503 +  [& sigs]
  1.3504 +    (let [name (if (symbol? (first sigs)) (first sigs) nil)
  1.3505 +          sigs (if name (next sigs) sigs)
  1.3506 +          sigs (if (vector? (first sigs)) (list sigs) sigs)
  1.3507 +          psig (fn* [sig]
  1.3508 +                 (let [[params & body] sig
  1.3509 +                       conds (when (and (next body) (map? (first body))) 
  1.3510 +                                           (first body))
  1.3511 +                       body (if conds (next body) body)
  1.3512 +                       conds (or conds (meta params))
  1.3513 +                       pre (:pre conds)
  1.3514 +                       post (:post conds)                       
  1.3515 +                       body (if post
  1.3516 +                              `((let [~'% ~(if (< 1 (count body)) 
  1.3517 +                                            `(do ~@body) 
  1.3518 +                                            (first body))]
  1.3519 +                                 ~@(map (fn* [c] `(assert ~c)) post)
  1.3520 +                                 ~'%))
  1.3521 +                              body)
  1.3522 +                       body (if pre
  1.3523 +                              (concat (map (fn* [c] `(assert ~c)) pre) 
  1.3524 +                                      body)
  1.3525 +                              body)]
  1.3526 +                   (maybe-destructured params body)))
  1.3527 +          new-sigs (map psig sigs)]
  1.3528 +      (with-meta
  1.3529 +        (if name
  1.3530 +          (list* 'fn* name new-sigs)
  1.3531 +          (cons 'fn* new-sigs))
  1.3532 +        (meta &form))))
  1.3533 +
  1.3534 +(defmacro loop
  1.3535 +  "Evaluates the exprs in a lexical context in which the symbols in
  1.3536 +  the binding-forms are bound to their respective init-exprs or parts
  1.3537 +  therein. Acts as a recur target."
  1.3538 +  {:added "1.0"}
  1.3539 +  [bindings & body]
  1.3540 +    (assert-args loop
  1.3541 +      (vector? bindings) "a vector for its binding"
  1.3542 +      (even? (count bindings)) "an even number of forms in binding vector")
  1.3543 +    (let [db (destructure bindings)]
  1.3544 +      (if (= db bindings)
  1.3545 +        `(loop* ~bindings ~@body)
  1.3546 +        (let [vs (take-nth 2 (drop 1 bindings))
  1.3547 +              bs (take-nth 2 bindings)
  1.3548 +              gs (map (fn [b] (if (symbol? b) b (gensym))) bs)
  1.3549 +              bfs (reduce (fn [ret [b v g]]
  1.3550 +                            (if (symbol? b)
  1.3551 +                              (conj ret g v)
  1.3552 +                              (conj ret g v b g)))
  1.3553 +                          [] (map vector bs vs gs))]
  1.3554 +          `(let ~bfs
  1.3555 +             (loop* ~(vec (interleave gs gs))
  1.3556 +               (let ~(vec (interleave bs gs))
  1.3557 +                 ~@body)))))))
  1.3558 +
  1.3559 +(defmacro when-first
  1.3560 +  "bindings => x xs
  1.3561 +
  1.3562 +  Same as (when (seq xs) (let [x (first xs)] body))"
  1.3563 +  {:added "1.0"}
  1.3564 +  [bindings & body]
  1.3565 +  (assert-args when-first
  1.3566 +     (vector? bindings) "a vector for its binding"
  1.3567 +     (= 2 (count bindings)) "exactly 2 forms in binding vector")
  1.3568 +  (let [[x xs] bindings]
  1.3569 +    `(when (seq ~xs)
  1.3570 +       (let [~x (first ~xs)]
  1.3571 +         ~@body))))
  1.3572 +
  1.3573 +(defmacro lazy-cat
  1.3574 +  "Expands to code which yields a lazy sequence of the concatenation
  1.3575 +  of the supplied colls.  Each coll expr is not evaluated until it is
  1.3576 +  needed. 
  1.3577 +
  1.3578 +  (lazy-cat xs ys zs) === (concat (lazy-seq xs) (lazy-seq ys) (lazy-seq zs))"
  1.3579 +  {:added "1.0"}
  1.3580 +  [& colls]
  1.3581 +  `(concat ~@(map #(list `lazy-seq %) colls)))
  1.3582 +
  1.3583 +(defmacro for
  1.3584 +  "List comprehension. Takes a vector of one or more
  1.3585 +   binding-form/collection-expr pairs, each followed by zero or more
  1.3586 +   modifiers, and yields a lazy sequence of evaluations of expr.
  1.3587 +   Collections are iterated in a nested fashion, rightmost fastest,
  1.3588 +   and nested coll-exprs can refer to bindings created in prior
  1.3589 +   binding-forms.  Supported modifiers are: :let [binding-form expr ...],
  1.3590 +   :while test, :when test.
  1.3591 +
  1.3592 +  (take 100 (for [x (range 100000000) y (range 1000000) :while (< y x)] [x y]))"
  1.3593 +  {:added "1.0"}
  1.3594 +  [seq-exprs body-expr]
  1.3595 +  (assert-args for
  1.3596 +     (vector? seq-exprs) "a vector for its binding"
  1.3597 +     (even? (count seq-exprs)) "an even number of forms in binding vector")
  1.3598 +  (let [to-groups (fn [seq-exprs]
  1.3599 +                    (reduce (fn [groups [k v]]
  1.3600 +                              (if (keyword? k)
  1.3601 +                                (conj (pop groups) (conj (peek groups) [k v]))
  1.3602 +                                (conj groups [k v])))
  1.3603 +                            [] (partition 2 seq-exprs)))
  1.3604 +        err (fn [& msg] (throw (IllegalArgumentException. ^String (apply str msg))))
  1.3605 +        emit-bind (fn emit-bind [[[bind expr & mod-pairs]
  1.3606 +                                  & [[_ next-expr] :as next-groups]]]
  1.3607 +                    (let [giter (gensym "iter__")
  1.3608 +                          gxs (gensym "s__")
  1.3609 +                          do-mod (fn do-mod [[[k v :as pair] & etc]]
  1.3610 +                                   (cond
  1.3611 +                                     (= k :let) `(let ~v ~(do-mod etc))
  1.3612 +                                     (= k :while) `(when ~v ~(do-mod etc))
  1.3613 +                                     (= k :when) `(if ~v
  1.3614 +                                                    ~(do-mod etc)
  1.3615 +                                                    (recur (rest ~gxs)))
  1.3616 +                                     (keyword? k) (err "Invalid 'for' keyword " k)
  1.3617 +                                     next-groups
  1.3618 +                                      `(let [iterys# ~(emit-bind next-groups)
  1.3619 +                                             fs# (seq (iterys# ~next-expr))]
  1.3620 +                                         (if fs#
  1.3621 +                                           (concat fs# (~giter (rest ~gxs)))
  1.3622 +                                           (recur (rest ~gxs))))
  1.3623 +                                     :else `(cons ~body-expr
  1.3624 +                                                  (~giter (rest ~gxs)))))]
  1.3625 +                      (if next-groups
  1.3626 +                        #_"not the inner-most loop"
  1.3627 +                        `(fn ~giter [~gxs]
  1.3628 +                           (lazy-seq
  1.3629 +                             (loop [~gxs ~gxs]
  1.3630 +                               (when-first [~bind ~gxs]
  1.3631 +                                 ~(do-mod mod-pairs)))))
  1.3632 +                        #_"inner-most loop"
  1.3633 +                        (let [gi (gensym "i__")
  1.3634 +                              gb (gensym "b__")
  1.3635 +                              do-cmod (fn do-cmod [[[k v :as pair] & etc]]
  1.3636 +                                        (cond
  1.3637 +                                          (= k :let) `(let ~v ~(do-cmod etc))
  1.3638 +                                          (= k :while) `(when ~v ~(do-cmod etc))
  1.3639 +                                          (= k :when) `(if ~v
  1.3640 +                                                         ~(do-cmod etc)
  1.3641 +                                                         (recur
  1.3642 +                                                           (unchecked-inc ~gi)))
  1.3643 +                                          (keyword? k)
  1.3644 +                                            (err "Invalid 'for' keyword " k)
  1.3645 +                                          :else
  1.3646 +                                            `(do (chunk-append ~gb ~body-expr)
  1.3647 +                                                 (recur (unchecked-inc ~gi)))))]
  1.3648 +                          `(fn ~giter [~gxs]
  1.3649 +                             (lazy-seq
  1.3650 +                               (loop [~gxs ~gxs]
  1.3651 +                                 (when-let [~gxs (seq ~gxs)]
  1.3652 +                                   (if (chunked-seq? ~gxs)
  1.3653 +                                     (let [c# (chunk-first ~gxs)
  1.3654 +                                           size# (int (count c#))
  1.3655 +                                           ~gb (chunk-buffer size#)]
  1.3656 +                                       (if (loop [~gi (int 0)]
  1.3657 +                                             (if (< ~gi size#)
  1.3658 +                                               (let [~bind (.nth c# ~gi)]
  1.3659 +                                                 ~(do-cmod mod-pairs))
  1.3660 +                                               true))
  1.3661 +                                         (chunk-cons
  1.3662 +                                           (chunk ~gb)
  1.3663 +                                           (~giter (chunk-rest ~gxs)))
  1.3664 +                                         (chunk-cons (chunk ~gb) nil)))
  1.3665 +                                     (let [~bind (first ~gxs)]
  1.3666 +                                       ~(do-mod mod-pairs)))))))))))]
  1.3667 +    `(let [iter# ~(emit-bind (to-groups seq-exprs))]
  1.3668 +        (iter# ~(second seq-exprs)))))
  1.3669 +
  1.3670 +(defmacro comment
  1.3671 +  "Ignores body, yields nil"
  1.3672 +  {:added "1.0"}
  1.3673 +  [& body])
  1.3674 +
  1.3675 +(defmacro with-out-str
  1.3676 +  "Evaluates exprs in a context in which *out* is bound to a fresh
  1.3677 +  StringWriter.  Returns the string created by any nested printing
  1.3678 +  calls."
  1.3679 +  {:added "1.0"}
  1.3680 +  [& body]
  1.3681 +  `(let [s# (new java.io.StringWriter)]
  1.3682 +     (binding [*out* s#]
  1.3683 +       ~@body
  1.3684 +       (str s#))))
  1.3685 +
  1.3686 +(defmacro with-in-str
  1.3687 +  "Evaluates body in a context in which *in* is bound to a fresh
  1.3688 +  StringReader initialized with the string s."
  1.3689 +  {:added "1.0"}
  1.3690 +  [s & body]
  1.3691 +  `(with-open [s# (-> (java.io.StringReader. ~s) clojure.lang.LineNumberingPushbackReader.)]
  1.3692 +     (binding [*in* s#]
  1.3693 +       ~@body)))
  1.3694 +
  1.3695 +(defn pr-str
  1.3696 +  "pr to a string, returning it"
  1.3697 +  {:tag String
  1.3698 +   :added "1.0"}
  1.3699 +  [& xs]
  1.3700 +    (with-out-str
  1.3701 +     (apply pr xs)))
  1.3702 +
  1.3703 +(defn prn-str
  1.3704 +  "prn to a string, returning it"
  1.3705 +  {:tag String
  1.3706 +   :added "1.0"}
  1.3707 +  [& xs]
  1.3708 +  (with-out-str
  1.3709 +   (apply prn xs)))
  1.3710 +
  1.3711 +(defn print-str
  1.3712 +  "print to a string, returning it"
  1.3713 +  {:tag String
  1.3714 +   :added "1.0"}
  1.3715 +  [& xs]
  1.3716 +    (with-out-str
  1.3717 +     (apply print xs)))
  1.3718 +
  1.3719 +(defn println-str
  1.3720 +  "println to a string, returning it"
  1.3721 +  {:tag String
  1.3722 +   :added "1.0"}
  1.3723 +  [& xs]
  1.3724 +    (with-out-str
  1.3725 +     (apply println xs)))
  1.3726 +
  1.3727 +(defmacro assert
  1.3728 +  "Evaluates expr and throws an exception if it does not evaluate to
  1.3729 + logical true."
  1.3730 +  {:added "1.0"}
  1.3731 +  [x]
  1.3732 +  (when *assert*
  1.3733 +    `(when-not ~x
  1.3734 +       (throw (new AssertionError (str "Assert failed: " (pr-str '~x)))))))
  1.3735 +
  1.3736 +(defn test
  1.3737 +  "test [v] finds fn at key :test in var metadata and calls it,
  1.3738 +  presuming failure will throw exception"
  1.3739 +  {:added "1.0"}
  1.3740 +  [v]
  1.3741 +    (let [f (:test (meta v))]
  1.3742 +      (if f
  1.3743 +        (do (f) :ok)
  1.3744 +        :no-test)))
  1.3745 +
  1.3746 +(defn re-pattern
  1.3747 +  "Returns an instance of java.util.regex.Pattern, for use, e.g. in
  1.3748 +  re-matcher."
  1.3749 +  {:tag java.util.regex.Pattern
  1.3750 +   :added "1.0"}
  1.3751 +  [s] (if (instance? java.util.regex.Pattern s)
  1.3752 +        s
  1.3753 +        (. java.util.regex.Pattern (compile s))))
  1.3754 +
  1.3755 +(defn re-matcher
  1.3756 +  "Returns an instance of java.util.regex.Matcher, for use, e.g. in
  1.3757 +  re-find."
  1.3758 +  {:tag java.util.regex.Matcher
  1.3759 +   :added "1.0"}
  1.3760 +  [^java.util.regex.Pattern re s]
  1.3761 +    (. re (matcher s)))
  1.3762 +
  1.3763 +(defn re-groups
  1.3764 +  "Returns the groups from the most recent match/find. If there are no
  1.3765 +  nested groups, returns a string of the entire match. If there are
  1.3766 +  nested groups, returns a vector of the groups, the first element
  1.3767 +  being the entire match."
  1.3768 +  {:added "1.0"}
  1.3769 +  [^java.util.regex.Matcher m]
  1.3770 +    (let [gc  (. m (groupCount))]
  1.3771 +      (if (zero? gc)
  1.3772 +        (. m (group))
  1.3773 +        (loop [ret [] c 0]
  1.3774 +          (if (<= c gc)
  1.3775 +            (recur (conj ret (. m (group c))) (inc c))
  1.3776 +            ret)))))
  1.3777 +
  1.3778 +(defn re-seq
  1.3779 +  "Returns a lazy sequence of successive matches of pattern in string,
  1.3780 +  using java.util.regex.Matcher.find(), each such match processed with
  1.3781 +  re-groups."
  1.3782 +  {:added "1.0"}
  1.3783 +  [^java.util.regex.Pattern re s]
  1.3784 +  (let [m (re-matcher re s)]
  1.3785 +    ((fn step []
  1.3786 +       (when (. m (find))
  1.3787 +         (cons (re-groups m) (lazy-seq (step))))))))
  1.3788 +
  1.3789 +(defn re-matches
  1.3790 +  "Returns the match, if any, of string to pattern, using
  1.3791 +  java.util.regex.Matcher.matches().  Uses re-groups to return the
  1.3792 +  groups."
  1.3793 +  {:added "1.0"}
  1.3794 +  [^java.util.regex.Pattern re s]
  1.3795 +    (let [m (re-matcher re s)]
  1.3796 +      (when (. m (matches))
  1.3797 +        (re-groups m))))
  1.3798 +
  1.3799 +
  1.3800 +(defn re-find
  1.3801 +  "Returns the next regex match, if any, of string to pattern, using
  1.3802 +  java.util.regex.Matcher.find().  Uses re-groups to return the
  1.3803 +  groups."
  1.3804 +  {:added "1.0"}
  1.3805 +  ([^java.util.regex.Matcher m]
  1.3806 +   (when (. m (find))
  1.3807 +     (re-groups m)))
  1.3808 +  ([^java.util.regex.Pattern re s]
  1.3809 +   (let [m (re-matcher re s)]
  1.3810 +     (re-find m))))
  1.3811 +
  1.3812 +(defn rand
  1.3813 +  "Returns a random floating point number between 0 (inclusive) and
  1.3814 +  n (default 1) (exclusive)."
  1.3815 +  {:added "1.0"}
  1.3816 +  ([] (. Math (random)))
  1.3817 +  ([n] (* n (rand))))
  1.3818 +
  1.3819 +(defn rand-int
  1.3820 +  "Returns a random integer between 0 (inclusive) and n (exclusive)."
  1.3821 +  {:added "1.0"}
  1.3822 +  [n] (int (rand n)))
  1.3823 +
  1.3824 +(defmacro defn-
  1.3825 +  "same as defn, yielding non-public def"
  1.3826 +  {:added "1.0"}
  1.3827 +  [name & decls]
  1.3828 +    (list* `defn (with-meta name (assoc (meta name) :private true)) decls))
  1.3829 +
  1.3830 +(defn print-doc [v]
  1.3831 +  (println "-------------------------")
  1.3832 +  (println (str (ns-name (:ns (meta v))) "/" (:name (meta v))))
  1.3833 +  (prn (:arglists (meta v)))
  1.3834 +  (when (:macro (meta v))
  1.3835 +    (println "Macro"))
  1.3836 +  (println " " (:doc (meta v))))
  1.3837 +
  1.3838 +(defn find-doc
  1.3839 +  "Prints documentation for any var whose documentation or name
  1.3840 + contains a match for re-string-or-pattern"
  1.3841 +  {:added "1.0"}
  1.3842 +  [re-string-or-pattern]
  1.3843 +    (let [re  (re-pattern re-string-or-pattern)]
  1.3844 +      (doseq [ns (all-ns)
  1.3845 +              v (sort-by (comp :name meta) (vals (ns-interns ns)))
  1.3846 +              :when (and (:doc (meta v))
  1.3847 +                         (or (re-find (re-matcher re (:doc (meta v))))
  1.3848 +                             (re-find (re-matcher re (str (:name (meta v)))))))]
  1.3849 +               (print-doc v))))
  1.3850 +
  1.3851 +(defn special-form-anchor
  1.3852 +  "Returns the anchor tag on http://clojure.org/special_forms for the
  1.3853 +  special form x, or nil"
  1.3854 +  {:added "1.0"}
  1.3855 +  [x]
  1.3856 +  (#{'. 'def 'do 'fn 'if 'let 'loop 'monitor-enter 'monitor-exit 'new
  1.3857 +  'quote 'recur 'set! 'throw 'try 'var} x))
  1.3858 +
  1.3859 +(defn syntax-symbol-anchor
  1.3860 +  "Returns the anchor tag on http://clojure.org/special_forms for the
  1.3861 +  special form that uses syntax symbol x, or nil"
  1.3862 +  {:added "1.0"}
  1.3863 +  [x]
  1.3864 +  ({'& 'fn 'catch 'try 'finally 'try} x))
  1.3865 +
  1.3866 +(defn print-special-doc
  1.3867 +  [name type anchor]
  1.3868 +  (println "-------------------------")
  1.3869 +  (println name)
  1.3870 +  (println type)
  1.3871 +  (println (str "  Please see http://clojure.org/special_forms#" anchor)))
  1.3872 +
  1.3873 +(defn print-namespace-doc
  1.3874 +  "Print the documentation string of a Namespace."
  1.3875 +  {:added "1.0"}
  1.3876 +  [nspace]
  1.3877 +  (println "-------------------------")
  1.3878 +  (println (str (ns-name nspace)))
  1.3879 +  (println " " (:doc (meta nspace))))
  1.3880 +
  1.3881 +(defmacro doc
  1.3882 +  "Prints documentation for a var or special form given its name"
  1.3883 +  {:added "1.0"}
  1.3884 +  [name]
  1.3885 +  (cond
  1.3886 +   (special-form-anchor `~name)
  1.3887 +   `(print-special-doc '~name "Special Form" (special-form-anchor '~name))
  1.3888 +   (syntax-symbol-anchor `~name)
  1.3889 +   `(print-special-doc '~name "Syntax Symbol" (syntax-symbol-anchor '~name))
  1.3890 +   :else
  1.3891 +    (let [nspace (find-ns name)]
  1.3892 +      (if nspace
  1.3893 +        `(print-namespace-doc ~nspace)
  1.3894 +        `(print-doc (var ~name))))))
  1.3895 +
  1.3896 + (defn tree-seq
  1.3897 +  "Returns a lazy sequence of the nodes in a tree, via a depth-first walk.
  1.3898 +   branch? must be a fn of one arg that returns true if passed a node
  1.3899 +   that can have children (but may not).  children must be a fn of one
  1.3900 +   arg that returns a sequence of the children. Will only be called on
  1.3901 +   nodes for which branch? returns true. Root is the root node of the
  1.3902 +  tree."
  1.3903 +  {:added "1.0"}
  1.3904 +   [branch? children root]
  1.3905 +   (let [walk (fn walk [node]
  1.3906 +                (lazy-seq
  1.3907 +                 (cons node
  1.3908 +                  (when (branch? node)
  1.3909 +                    (mapcat walk (children node))))))]
  1.3910 +     (walk root)))
  1.3911 +
  1.3912 +(defn file-seq
  1.3913 +  "A tree seq on java.io.Files"
  1.3914 +  {:added "1.0"}
  1.3915 +  [dir]
  1.3916 +    (tree-seq
  1.3917 +     (fn [^java.io.File f] (. f (isDirectory)))
  1.3918 +     (fn [^java.io.File d] (seq (. d (listFiles))))
  1.3919 +     dir))
  1.3920 +
  1.3921 +(defn xml-seq
  1.3922 +  "A tree seq on the xml elements as per xml/parse"
  1.3923 +  {:added "1.0"}
  1.3924 +  [root]
  1.3925 +    (tree-seq
  1.3926 +     (complement string?)
  1.3927 +     (comp seq :content)
  1.3928 +     root))
  1.3929 +
  1.3930 +(defn special-symbol?
  1.3931 +  "Returns true if s names a special form"
  1.3932 +  {:added "1.0"}
  1.3933 +  [s]
  1.3934 +    (contains? (. clojure.lang.Compiler specials) s))
  1.3935 +
  1.3936 +(defn var?
  1.3937 +  "Returns true if v is of type clojure.lang.Var"
  1.3938 +  {:added "1.0"}
  1.3939 +  [v] (instance? clojure.lang.Var v))
  1.3940 +
  1.3941 +(defn ^String subs
  1.3942 +  "Returns the substring of s beginning at start inclusive, and ending
  1.3943 +  at end (defaults to length of string), exclusive."
  1.3944 +  {:added "1.0"}
  1.3945 +  ([^String s start] (. s (substring start)))
  1.3946 +  ([^String s start end] (. s (substring start end))))
  1.3947 +
  1.3948 +(defn max-key
  1.3949 +  "Returns the x for which (k x), a number, is greatest."
  1.3950 +  {:added "1.0"}
  1.3951 +  ([k x] x)
  1.3952 +  ([k x y] (if (> (k x) (k y)) x y))
  1.3953 +  ([k x y & more]
  1.3954 +   (reduce #(max-key k %1 %2) (max-key k x y) more)))
  1.3955 +
  1.3956 +(defn min-key
  1.3957 +  "Returns the x for which (k x), a number, is least."
  1.3958 +  {:added "1.0"}
  1.3959 +  ([k x] x)
  1.3960 +  ([k x y] (if (< (k x) (k y)) x y))
  1.3961 +  ([k x y & more]
  1.3962 +   (reduce #(min-key k %1 %2) (min-key k x y) more)))
  1.3963 +
  1.3964 +(defn distinct
  1.3965 +  "Returns a lazy sequence of the elements of coll with duplicates removed"
  1.3966 +  {:added "1.0"}
  1.3967 +  [coll]
  1.3968 +    (let [step (fn step [xs seen]
  1.3969 +                   (lazy-seq
  1.3970 +                    ((fn [[f :as xs] seen]
  1.3971 +                      (when-let [s (seq xs)]
  1.3972 +                        (if (contains? seen f) 
  1.3973 +                          (recur (rest s) seen)
  1.3974 +                          (cons f (step (rest s) (conj seen f))))))
  1.3975 +                     xs seen)))]
  1.3976 +      (step coll #{})))
  1.3977 +
  1.3978 +
  1.3979 +
  1.3980 +(defn replace
  1.3981 +  "Given a map of replacement pairs and a vector/collection, returns a
  1.3982 +  vector/seq with any elements = a key in smap replaced with the
  1.3983 +  corresponding val in smap"
  1.3984 +  {:added "1.0"}
  1.3985 +  [smap coll]
  1.3986 +    (if (vector? coll)
  1.3987 +      (reduce (fn [v i]
  1.3988 +                (if-let [e (find smap (nth v i))]
  1.3989 +                        (assoc v i (val e))
  1.3990 +                        v))
  1.3991 +              coll (range (count coll)))
  1.3992 +      (map #(if-let [e (find smap %)] (val e) %) coll)))
  1.3993 +
  1.3994 +(defmacro dosync
  1.3995 +  "Runs the exprs (in an implicit do) in a transaction that encompasses
  1.3996 +  exprs and any nested calls.  Starts a transaction if none is already
  1.3997 +  running on this thread. Any uncaught exception will abort the
  1.3998 +  transaction and flow out of dosync. The exprs may be run more than
  1.3999 +  once, but any effects on Refs will be atomic."
  1.4000 +  {:added "1.0"}
  1.4001 +  [& exprs]
  1.4002 +  `(sync nil ~@exprs))
  1.4003 +
  1.4004 +(defmacro with-precision
  1.4005 +  "Sets the precision and rounding mode to be used for BigDecimal operations.
  1.4006 +
  1.4007 +  Usage: (with-precision 10 (/ 1M 3))
  1.4008 +  or:    (with-precision 10 :rounding HALF_DOWN (/ 1M 3))
  1.4009 +
  1.4010 +  The rounding mode is one of CEILING, FLOOR, HALF_UP, HALF_DOWN,
  1.4011 +  HALF_EVEN, UP, DOWN and UNNECESSARY; it defaults to HALF_UP."
  1.4012 +  {:added "1.0"}
  1.4013 +  [precision & exprs]
  1.4014 +    (let [[body rm] (if (= (first exprs) :rounding)
  1.4015 +                      [(next (next exprs))
  1.4016 +                       `((. java.math.RoundingMode ~(second exprs)))]
  1.4017 +                      [exprs nil])]
  1.4018 +      `(binding [*math-context* (java.math.MathContext. ~precision ~@rm)]
  1.4019 +         ~@body)))
  1.4020 +
  1.4021 +(defn mk-bound-fn
  1.4022 +  {:private true}
  1.4023 +  [^clojure.lang.Sorted sc test key]
  1.4024 +  (fn [e]
  1.4025 +    (test (.. sc comparator (compare (. sc entryKey e) key)) 0)))
  1.4026 +
  1.4027 +(defn subseq
  1.4028 +  "sc must be a sorted collection, test(s) one of <, <=, > or
  1.4029 +  >=. Returns a seq of those entries with keys ek for
  1.4030 +  which (test (.. sc comparator (compare ek key)) 0) is true"
  1.4031 +  {:added "1.0"}
  1.4032 +  ([^clojure.lang.Sorted sc test key]
  1.4033 +   (let [include (mk-bound-fn sc test key)]
  1.4034 +     (if (#{> >=} test)
  1.4035 +       (when-let [[e :as s] (. sc seqFrom key true)]
  1.4036 +         (if (include e) s (next s)))
  1.4037 +       (take-while include (. sc seq true)))))
  1.4038 +  ([^clojure.lang.Sorted sc start-test start-key end-test end-key]
  1.4039 +   (when-let [[e :as s] (. sc seqFrom start-key true)]
  1.4040 +     (take-while (mk-bound-fn sc end-test end-key)
  1.4041 +                 (if ((mk-bound-fn sc start-test start-key) e) s (next s))))))
  1.4042 +
  1.4043 +(defn rsubseq
  1.4044 +  "sc must be a sorted collection, test(s) one of <, <=, > or
  1.4045 +  >=. Returns a reverse seq of those entries with keys ek for
  1.4046 +  which (test (.. sc comparator (compare ek key)) 0) is true"
  1.4047 +  {:added "1.0"}
  1.4048 +  ([^clojure.lang.Sorted sc test key]
  1.4049 +   (let [include (mk-bound-fn sc test key)]
  1.4050 +     (if (#{< <=} test)
  1.4051 +       (when-let [[e :as s] (. sc seqFrom key false)]
  1.4052 +         (if (include e) s (next s)))
  1.4053 +       (take-while include (. sc seq false)))))
  1.4054 +  ([^clojure.lang.Sorted sc start-test start-key end-test end-key]
  1.4055 +   (when-let [[e :as s] (. sc seqFrom end-key false)]
  1.4056 +     (take-while (mk-bound-fn sc start-test start-key)
  1.4057 +                 (if ((mk-bound-fn sc end-test end-key) e) s (next s))))))
  1.4058 +
  1.4059 +(defn repeatedly
  1.4060 +  "Takes a function of no args, presumably with side effects, and
  1.4061 +  returns an infinite (or length n if supplied) lazy sequence of calls
  1.4062 +  to it"
  1.4063 +  {:added "1.0"}
  1.4064 +  ([f] (lazy-seq (cons (f) (repeatedly f))))
  1.4065 +  ([n f] (take n (repeatedly f))))
  1.4066 +
  1.4067 +(defn add-classpath
  1.4068 +  "DEPRECATED 
  1.4069 +
  1.4070 +  Adds the url (String or URL object) to the classpath per
  1.4071 +  URLClassLoader.addURL"
  1.4072 +  {:added "1.0"
  1.4073 +   :deprecated "1.1"}
  1.4074 +  [url]
  1.4075 +  (println "WARNING: add-classpath is deprecated")
  1.4076 +  (clojure.lang.RT/addURL url))
  1.4077 +
  1.4078 +
  1.4079 +
  1.4080 +(defn hash
  1.4081 +  "Returns the hash code of its argument"
  1.4082 +  {:added "1.0"}
  1.4083 +  [x] (. clojure.lang.Util (hash x)))
  1.4084 +
  1.4085 +(defn interpose
  1.4086 +  "Returns a lazy seq of the elements of coll separated by sep"
  1.4087 +  {:added "1.0"}
  1.4088 +  [sep coll] (drop 1 (interleave (repeat sep) coll)))
  1.4089 +
  1.4090 +(defmacro definline
  1.4091 +  "Experimental - like defmacro, except defines a named function whose
  1.4092 +  body is the expansion, calls to which may be expanded inline as if
  1.4093 +  it were a macro. Cannot be used with variadic (&) args."
  1.4094 +  {:added "1.0"}
  1.4095 +  [name & decl]
  1.4096 +  (let [[pre-args [args expr]] (split-with (comp not vector?) decl)]
  1.4097 +    `(do
  1.4098 +       (defn ~name ~@pre-args ~args ~(apply (eval (list `fn args expr)) args))
  1.4099 +       (alter-meta! (var ~name) assoc :inline (fn ~name ~args ~expr))
  1.4100 +       (var ~name))))
  1.4101 +
  1.4102 +(defn empty
  1.4103 +  "Returns an empty collection of the same category as coll, or nil"
  1.4104 +  {:added "1.0"}
  1.4105 +  [coll]
  1.4106 +  (when (instance? clojure.lang.IPersistentCollection coll)
  1.4107 +    (.empty ^clojure.lang.IPersistentCollection coll)))
  1.4108 +
  1.4109 +(defmacro amap
  1.4110 +  "Maps an expression across an array a, using an index named idx, and
  1.4111 +  return value named ret, initialized to a clone of a, then setting 
  1.4112 +  each element of ret to the evaluation of expr, returning the new 
  1.4113 +  array ret."
  1.4114 +  {:added "1.0"}
  1.4115 +  [a idx ret expr]
  1.4116 +  `(let [a# ~a
  1.4117 +         ~ret (aclone a#)]
  1.4118 +     (loop  [~idx (int 0)]
  1.4119 +       (if (< ~idx  (alength a#))
  1.4120 +         (do
  1.4121 +           (aset ~ret ~idx ~expr)
  1.4122 +           (recur (unchecked-inc ~idx)))
  1.4123 +         ~ret))))
  1.4124 +
  1.4125 +(defmacro areduce
  1.4126 +  "Reduces an expression across an array a, using an index named idx,
  1.4127 +  and return value named ret, initialized to init, setting ret to the 
  1.4128 +  evaluation of expr at each step, returning ret."
  1.4129 +  {:added "1.0"}
  1.4130 +  [a idx ret init expr]
  1.4131 +  `(let [a# ~a]
  1.4132 +     (loop  [~idx (int 0) ~ret ~init]
  1.4133 +       (if (< ~idx  (alength a#))
  1.4134 +         (recur (unchecked-inc ~idx) ~expr)
  1.4135 +         ~ret))))
  1.4136 +
  1.4137 +(defn float-array
  1.4138 +  "Creates an array of floats"
  1.4139 +  {:inline (fn [& args] `(. clojure.lang.Numbers float_array ~@args))
  1.4140 +   :inline-arities #{1 2}
  1.4141 +   :added "1.0"}
  1.4142 +  ([size-or-seq] (. clojure.lang.Numbers float_array size-or-seq))
  1.4143 +  ([size init-val-or-seq] (. clojure.lang.Numbers float_array size init-val-or-seq)))
  1.4144 +
  1.4145 +(defn boolean-array
  1.4146 +  "Creates an array of booleans"
  1.4147 +  {:inline (fn [& args] `(. clojure.lang.Numbers boolean_array ~@args))
  1.4148 +   :inline-arities #{1 2}
  1.4149 +   :added "1.1"}
  1.4150 +  ([size-or-seq] (. clojure.lang.Numbers boolean_array size-or-seq))
  1.4151 +  ([size init-val-or-seq] (. clojure.lang.Numbers boolean_array size init-val-or-seq)))
  1.4152 +
  1.4153 +(defn byte-array
  1.4154 +  "Creates an array of bytes"
  1.4155 +  {:inline (fn [& args] `(. clojure.lang.Numbers byte_array ~@args))
  1.4156 +   :inline-arities #{1 2}
  1.4157 +   :added "1.1"}
  1.4158 +  ([size-or-seq] (. clojure.lang.Numbers byte_array size-or-seq))
  1.4159 +  ([size init-val-or-seq] (. clojure.lang.Numbers byte_array size init-val-or-seq)))
  1.4160 +
  1.4161 +(defn char-array
  1.4162 +  "Creates an array of chars"
  1.4163 +  {:inline (fn [& args] `(. clojure.lang.Numbers char_array ~@args))
  1.4164 +   :inline-arities #{1 2}
  1.4165 +   :added "1.1"}
  1.4166 +  ([size-or-seq] (. clojure.lang.Numbers char_array size-or-seq))
  1.4167 +  ([size init-val-or-seq] (. clojure.lang.Numbers char_array size init-val-or-seq)))
  1.4168 +
  1.4169 +(defn short-array
  1.4170 +  "Creates an array of shorts"
  1.4171 +  {:inline (fn [& args] `(. clojure.lang.Numbers short_array ~@args))
  1.4172 +   :inline-arities #{1 2}
  1.4173 +   :added "1.1"}
  1.4174 +  ([size-or-seq] (. clojure.lang.Numbers short_array size-or-seq))
  1.4175 +  ([size init-val-or-seq] (. clojure.lang.Numbers short_array size init-val-or-seq)))
  1.4176 +
  1.4177 +(defn double-array
  1.4178 +  "Creates an array of doubles"
  1.4179 +  {:inline (fn [& args] `(. clojure.lang.Numbers double_array ~@args))
  1.4180 +   :inline-arities #{1 2}
  1.4181 +   :added "1.0"}
  1.4182 +  ([size-or-seq] (. clojure.lang.Numbers double_array size-or-seq))
  1.4183 +  ([size init-val-or-seq] (. clojure.lang.Numbers double_array size init-val-or-seq)))
  1.4184 +
  1.4185 +(defn object-array
  1.4186 +  "Creates an array of objects"
  1.4187 +  {:inline (fn [arg] `(. clojure.lang.RT object_array ~arg))
  1.4188 +   :inline-arities #{1}
  1.4189 +   :added "1.2"}
  1.4190 +  ([size-or-seq] (. clojure.lang.RT object_array size-or-seq)))
  1.4191 +
  1.4192 +(defn int-array
  1.4193 +  "Creates an array of ints"
  1.4194 +  {:inline (fn [& args] `(. clojure.lang.Numbers int_array ~@args))
  1.4195 +   :inline-arities #{1 2}
  1.4196 +   :added "1.0"}
  1.4197 +  ([size-or-seq] (. clojure.lang.Numbers int_array size-or-seq))
  1.4198 +  ([size init-val-or-seq] (. clojure.lang.Numbers int_array size init-val-or-seq)))
  1.4199 +
  1.4200 +(defn long-array
  1.4201 +  "Creates an array of longs"
  1.4202 +  {:inline (fn [& args] `(. clojure.lang.Numbers long_array ~@args))
  1.4203 +   :inline-arities #{1 2}
  1.4204 +   :added "1.0"}
  1.4205 +  ([size-or-seq] (. clojure.lang.Numbers long_array size-or-seq))
  1.4206 +  ([size init-val-or-seq] (. clojure.lang.Numbers long_array size init-val-or-seq)))
  1.4207 +
  1.4208 +(definline booleans
  1.4209 +  "Casts to boolean[]"
  1.4210 +  {:added "1.1"}
  1.4211 +  [xs] `(. clojure.lang.Numbers booleans ~xs))
  1.4212 +
  1.4213 +(definline bytes
  1.4214 +  "Casts to bytes[]"
  1.4215 +  {:added "1.1"}
  1.4216 +  [xs] `(. clojure.lang.Numbers bytes ~xs))
  1.4217 +
  1.4218 +(definline chars
  1.4219 +  "Casts to chars[]"
  1.4220 +  {:added "1.1"}
  1.4221 +  [xs] `(. clojure.lang.Numbers chars ~xs))
  1.4222 +
  1.4223 +(definline shorts
  1.4224 +  "Casts to shorts[]"
  1.4225 +  {:added "1.1"}
  1.4226 +  [xs] `(. clojure.lang.Numbers shorts ~xs))
  1.4227 +
  1.4228 +(definline floats
  1.4229 +  "Casts to float[]"
  1.4230 +  {:added "1.0"}
  1.4231 +  [xs] `(. clojure.lang.Numbers floats ~xs))
  1.4232 +
  1.4233 +(definline ints
  1.4234 +  "Casts to int[]"
  1.4235 +  {:added "1.0"}
  1.4236 +  [xs] `(. clojure.lang.Numbers ints ~xs))
  1.4237 +
  1.4238 +(definline doubles
  1.4239 +  "Casts to double[]"
  1.4240 +  {:added "1.0"}
  1.4241 +  [xs] `(. clojure.lang.Numbers doubles ~xs))
  1.4242 +
  1.4243 +(definline longs
  1.4244 +  "Casts to long[]"
  1.4245 +  {:added "1.0"}
  1.4246 +  [xs] `(. clojure.lang.Numbers longs ~xs))
  1.4247 +
  1.4248 +(import '(java.util.concurrent BlockingQueue LinkedBlockingQueue))
  1.4249 +
  1.4250 +(defn seque
  1.4251 +  "Creates a queued seq on another (presumably lazy) seq s. The queued
  1.4252 +  seq will produce a concrete seq in the background, and can get up to
  1.4253 +  n items ahead of the consumer. n-or-q can be an integer n buffer
  1.4254 +  size, or an instance of java.util.concurrent BlockingQueue. Note
  1.4255 +  that reading from a seque can block if the reader gets ahead of the
  1.4256 +  producer."
  1.4257 +  {:added "1.0"}
  1.4258 +  ([s] (seque 100 s))
  1.4259 +  ([n-or-q s]
  1.4260 +   (let [^BlockingQueue q (if (instance? BlockingQueue n-or-q)
  1.4261 +                             n-or-q
  1.4262 +                             (LinkedBlockingQueue. (int n-or-q)))
  1.4263 +         NIL (Object.) ;nil sentinel since LBQ doesn't support nils
  1.4264 +         agt (agent (seq s))
  1.4265 +         fill (fn [s]
  1.4266 +                (try
  1.4267 +                  (loop [[x & xs :as s] s]
  1.4268 +                    (if s
  1.4269 +                      (if (.offer q (if (nil? x) NIL x))
  1.4270 +                        (recur xs)
  1.4271 +                        s)
  1.4272 +                      (.put q q))) ; q itself is eos sentinel
  1.4273 +                  (catch Exception e
  1.4274 +                    (.put q q)
  1.4275 +                    (throw e))))
  1.4276 +         drain (fn drain []
  1.4277 +                 (lazy-seq
  1.4278 +                  (let [x (.take q)]
  1.4279 +                    (if (identical? x q) ;q itself is eos sentinel
  1.4280 +                      (do @agt nil)  ;touch agent just to propagate errors
  1.4281 +                      (do
  1.4282 +                        (send-off agt fill)
  1.4283 +                        (cons (if (identical? x NIL) nil x) (drain)))))))]
  1.4284 +     (send-off agt fill)
  1.4285 +     (drain))))
  1.4286 +
  1.4287 +(defn class?
  1.4288 +  "Returns true if x is an instance of Class"
  1.4289 +  {:added "1.0"}
  1.4290 +  [x] (instance? Class x))
  1.4291 +
  1.4292 +(defn- is-annotation? [c]
  1.4293 +  (and (class? c)
  1.4294 +       (.isAssignableFrom java.lang.annotation.Annotation c)))
  1.4295 +
  1.4296 +(defn- is-runtime-annotation? [^Class c]
  1.4297 +  (boolean 
  1.4298 +   (and (is-annotation? c)
  1.4299 +        (when-let [^java.lang.annotation.Retention r 
  1.4300 +                   (.getAnnotation c java.lang.annotation.Retention)] 
  1.4301 +          (= (.value r) java.lang.annotation.RetentionPolicy/RUNTIME)))))
  1.4302 +
  1.4303 +(defn- descriptor [^Class c] (clojure.asm.Type/getDescriptor c))
  1.4304 +
  1.4305 +(declare process-annotation)
  1.4306 +(defn- add-annotation [^clojure.asm.AnnotationVisitor av name v]
  1.4307 +  (cond
  1.4308 +   (vector? v) (let [avec (.visitArray av name)]
  1.4309 +                 (doseq [vval v]
  1.4310 +                   (add-annotation avec "value" vval))
  1.4311 +                 (.visitEnd avec))
  1.4312 +   (symbol? v) (let [ev (eval v)]
  1.4313 +                 (cond 
  1.4314 +                  (instance? java.lang.Enum ev)
  1.4315 +                  (.visitEnum av name (descriptor (class ev)) (str ev))
  1.4316 +                  (class? ev) (.visit av name (clojure.asm.Type/getType ev))
  1.4317 +                  :else (throw (IllegalArgumentException. 
  1.4318 +                                (str "Unsupported annotation value: " v " of class " (class ev))))))
  1.4319 +   (seq? v) (let [[nested nv] v
  1.4320 +                  c (resolve nested)
  1.4321 +                  nav (.visitAnnotation av name (descriptor c))]
  1.4322 +              (process-annotation nav nv)
  1.4323 +              (.visitEnd nav))
  1.4324 +   :else (.visit av name v)))
  1.4325 +
  1.4326 +(defn- process-annotation [av v]
  1.4327 +  (if (map? v) 
  1.4328 +    (doseq [[k v] v]
  1.4329 +      (add-annotation av (name k) v))
  1.4330 +    (add-annotation av "value" v)))
  1.4331 +
  1.4332 +(defn- add-annotations
  1.4333 +  ([visitor m] (add-annotations visitor m nil))
  1.4334 +  ([visitor m i]
  1.4335 +     (doseq [[k v] m]
  1.4336 +       (when (symbol? k)
  1.4337 +         (when-let [c (resolve k)]
  1.4338 +           (when (is-annotation? c)
  1.4339 +                                        ;this is known duck/reflective as no common base of ASM Visitors
  1.4340 +             (let [av (if i
  1.4341 +                        (.visitParameterAnnotation visitor i (descriptor c) 
  1.4342 +                                                   (is-runtime-annotation? c))
  1.4343 +                        (.visitAnnotation visitor (descriptor c) 
  1.4344 +                                          (is-runtime-annotation? c)))]
  1.4345 +               (process-annotation av v)
  1.4346 +               (.visitEnd av))))))))
  1.4347 +
  1.4348 +(defn alter-var-root
  1.4349 +  "Atomically alters the root binding of var v by applying f to its
  1.4350 +  current value plus any args"
  1.4351 +  {:added "1.0"}
  1.4352 +  [^clojure.lang.Var v f & args] (.alterRoot v f args))
  1.4353 +
  1.4354 +(defn bound?
  1.4355 +  "Returns true if all of the vars provided as arguments have any bound value, root or thread-local.
  1.4356 +   Implies that deref'ing the provided vars will succeed. Returns true if no vars are provided."
  1.4357 +  {:added "1.2"}
  1.4358 +  [& vars]
  1.4359 +  (every? #(.isBound ^clojure.lang.Var %) vars))
  1.4360 +
  1.4361 +(defn thread-bound?
  1.4362 +  "Returns true if all of the vars provided as arguments have thread-local bindings.
  1.4363 +   Implies that set!'ing the provided vars will succeed.  Returns true if no vars are provided."
  1.4364 +  {:added "1.2"}
  1.4365 +  [& vars]
  1.4366 +  (every? #(.getThreadBinding ^clojure.lang.Var %) vars))
  1.4367 +
  1.4368 +(defn make-hierarchy
  1.4369 +  "Creates a hierarchy object for use with derive, isa? etc."
  1.4370 +  {:added "1.0"}
  1.4371 +  [] {:parents {} :descendants {} :ancestors {}})
  1.4372 +
  1.4373 +(def ^{:private true}
  1.4374 +     global-hierarchy (make-hierarchy))
  1.4375 +
  1.4376 +(defn not-empty
  1.4377 +  "If coll is empty, returns nil, else coll"
  1.4378 +  {:added "1.0"}
  1.4379 +  [coll] (when (seq coll) coll))
  1.4380 +
  1.4381 +(defn bases
  1.4382 +  "Returns the immediate superclass and direct interfaces of c, if any"
  1.4383 +  {:added "1.0"}
  1.4384 +  [^Class c]
  1.4385 +  (when c
  1.4386 +    (let [i (.getInterfaces c)
  1.4387 +          s (.getSuperclass c)]
  1.4388 +      (not-empty
  1.4389 +       (if s (cons s i) i)))))
  1.4390 +
  1.4391 +(defn supers
  1.4392 +  "Returns the immediate and indirect superclasses and interfaces of c, if any"
  1.4393 +  {:added "1.0"}
  1.4394 +  [^Class class]
  1.4395 +  (loop [ret (set (bases class)) cs ret]
  1.4396 +    (if (seq cs)
  1.4397 +      (let [c (first cs) bs (bases c)]
  1.4398 +        (recur (into ret bs) (into (disj cs c) bs)))
  1.4399 +      (not-empty ret))))
  1.4400 +
  1.4401 +(defn isa?
  1.4402 +  "Returns true if (= child parent), or child is directly or indirectly derived from
  1.4403 +  parent, either via a Java type inheritance relationship or a
  1.4404 +  relationship established via derive. h must be a hierarchy obtained
  1.4405 +  from make-hierarchy, if not supplied defaults to the global
  1.4406 +  hierarchy"
  1.4407 +  {:added "1.0"}
  1.4408 +  ([child parent] (isa? global-hierarchy child parent))
  1.4409 +  ([h child parent]
  1.4410 +   (or (= child parent)
  1.4411 +       (and (class? parent) (class? child)
  1.4412 +            (. ^Class parent isAssignableFrom child))
  1.4413 +       (contains? ((:ancestors h) child) parent)
  1.4414 +       (and (class? child) (some #(contains? ((:ancestors h) %) parent) (supers child)))
  1.4415 +       (and (vector? parent) (vector? child)
  1.4416 +            (= (count parent) (count child))
  1.4417 +            (loop [ret true i 0]
  1.4418 +              (if (or (not ret) (= i (count parent)))
  1.4419 +                ret
  1.4420 +                (recur (isa? h (child i) (parent i)) (inc i))))))))
  1.4421 +
  1.4422 +(defn parents
  1.4423 +  "Returns the immediate parents of tag, either via a Java type
  1.4424 +  inheritance relationship or a relationship established via derive. h
  1.4425 +  must be a hierarchy obtained from make-hierarchy, if not supplied
  1.4426 +  defaults to the global hierarchy"
  1.4427 +  {:added "1.0"}
  1.4428 +  ([tag] (parents global-hierarchy tag))
  1.4429 +  ([h tag] (not-empty
  1.4430 +            (let [tp (get (:parents h) tag)]
  1.4431 +              (if (class? tag)
  1.4432 +                (into (set (bases tag)) tp)
  1.4433 +                tp)))))
  1.4434 +
  1.4435 +(defn ancestors
  1.4436 +  "Returns the immediate and indirect parents of tag, either via a Java type
  1.4437 +  inheritance relationship or a relationship established via derive. h
  1.4438 +  must be a hierarchy obtained from make-hierarchy, if not supplied
  1.4439 +  defaults to the global hierarchy"
  1.4440 +  {:added "1.0"}
  1.4441 +  ([tag] (ancestors global-hierarchy tag))
  1.4442 +  ([h tag] (not-empty
  1.4443 +            (let [ta (get (:ancestors h) tag)]
  1.4444 +              (if (class? tag)
  1.4445 +                (let [superclasses (set (supers tag))]
  1.4446 +                  (reduce into superclasses
  1.4447 +                    (cons ta
  1.4448 +                          (map #(get (:ancestors h) %) superclasses))))
  1.4449 +                ta)))))
  1.4450 +
  1.4451 +(defn descendants
  1.4452 +  "Returns the immediate and indirect children of tag, through a
  1.4453 +  relationship established via derive. h must be a hierarchy obtained
  1.4454 +  from make-hierarchy, if not supplied defaults to the global
  1.4455 +  hierarchy. Note: does not work on Java type inheritance
  1.4456 +  relationships."
  1.4457 +  {:added "1.0"}
  1.4458 +  ([tag] (descendants global-hierarchy tag))
  1.4459 +  ([h tag] (if (class? tag)
  1.4460 +             (throw (java.lang.UnsupportedOperationException. "Can't get descendants of classes"))
  1.4461 +             (not-empty (get (:descendants h) tag)))))
  1.4462 +
  1.4463 +(defn derive
  1.4464 +  "Establishes a parent/child relationship between parent and
  1.4465 +  tag. Parent must be a namespace-qualified symbol or keyword and
  1.4466 +  child can be either a namespace-qualified symbol or keyword or a
  1.4467 +  class. h must be a hierarchy obtained from make-hierarchy, if not
  1.4468 +  supplied defaults to, and modifies, the global hierarchy."
  1.4469 +  {:added "1.0"}
  1.4470 +  ([tag parent]
  1.4471 +   (assert (namespace parent))
  1.4472 +   (assert (or (class? tag) (and (instance? clojure.lang.Named tag) (namespace tag))))
  1.4473 +
  1.4474 +   (alter-var-root #'global-hierarchy derive tag parent) nil)
  1.4475 +  ([h tag parent]
  1.4476 +   (assert (not= tag parent))
  1.4477 +   (assert (or (class? tag) (instance? clojure.lang.Named tag)))
  1.4478 +   (assert (instance? clojure.lang.Named parent))
  1.4479 +
  1.4480 +   (let [tp (:parents h)
  1.4481 +         td (:descendants h)
  1.4482 +         ta (:ancestors h)
  1.4483 +         tf (fn [m source sources target targets]
  1.4484 +              (reduce (fn [ret k]
  1.4485 +                        (assoc ret k
  1.4486 +                               (reduce conj (get targets k #{}) (cons target (targets target)))))
  1.4487 +                      m (cons source (sources source))))]
  1.4488 +     (or
  1.4489 +      (when-not (contains? (tp tag) parent)
  1.4490 +        (when (contains? (ta tag) parent)
  1.4491 +          (throw (Exception. (print-str tag "already has" parent "as ancestor"))))
  1.4492 +        (when (contains? (ta parent) tag)
  1.4493 +          (throw (Exception. (print-str "Cyclic derivation:" parent "has" tag "as ancestor"))))
  1.4494 +        {:parents (assoc (:parents h) tag (conj (get tp tag #{}) parent))
  1.4495 +         :ancestors (tf (:ancestors h) tag td parent ta)
  1.4496 +         :descendants (tf (:descendants h) parent ta tag td)})
  1.4497 +      h))))
  1.4498 +
  1.4499 +(declare flatten)
  1.4500 +
  1.4501 +(defn underive
  1.4502 +  "Removes a parent/child relationship between parent and
  1.4503 +  tag. h must be a hierarchy obtained from make-hierarchy, if not
  1.4504 +  supplied defaults to, and modifies, the global hierarchy."
  1.4505 +  {:added "1.0"}
  1.4506 +  ([tag parent] (alter-var-root #'global-hierarchy underive tag parent) nil)
  1.4507 +  ([h tag parent]
  1.4508 +    (let [parentMap (:parents h)
  1.4509 +	  childsParents (if (parentMap tag)
  1.4510 +			  (disj (parentMap tag) parent) #{})
  1.4511 +	  newParents (if (not-empty childsParents)
  1.4512 +		       (assoc parentMap tag childsParents)
  1.4513 +		       (dissoc parentMap tag))
  1.4514 +	  deriv-seq (flatten (map #(cons (key %) (interpose (key %) (val %)))
  1.4515 +				       (seq newParents)))]
  1.4516 +      (if (contains? (parentMap tag) parent)
  1.4517 +	(reduce #(apply derive %1 %2) (make-hierarchy)
  1.4518 +		(partition 2 deriv-seq))
  1.4519 +	h))))
  1.4520 +
  1.4521 +
  1.4522 +(defn distinct?
  1.4523 +  "Returns true if no two of the arguments are ="
  1.4524 +  {:tag Boolean
  1.4525 +   :added "1.0"}
  1.4526 +  ([x] true)
  1.4527 +  ([x y] (not (= x y)))
  1.4528 +  ([x y & more]
  1.4529 +   (if (not= x y)
  1.4530 +     (loop [s #{x y} [x & etc :as xs] more]
  1.4531 +       (if xs
  1.4532 +         (if (contains? s x)
  1.4533 +           false
  1.4534 +           (recur (conj s x) etc))
  1.4535 +         true))
  1.4536 +     false)))
  1.4537 +
  1.4538 +(defn resultset-seq
  1.4539 +  "Creates and returns a lazy sequence of structmaps corresponding to
  1.4540 +  the rows in the java.sql.ResultSet rs"
  1.4541 +  {:added "1.0"}
  1.4542 +  [^java.sql.ResultSet rs]
  1.4543 +    (let [rsmeta (. rs (getMetaData))
  1.4544 +          idxs (range 1 (inc (. rsmeta (getColumnCount))))
  1.4545 +          keys (map (comp keyword #(.toLowerCase ^String %))
  1.4546 +                    (map (fn [i] (. rsmeta (getColumnLabel i))) idxs))
  1.4547 +          check-keys
  1.4548 +                (or (apply distinct? keys)
  1.4549 +                    (throw (Exception. "ResultSet must have unique column labels")))
  1.4550 +          row-struct (apply create-struct keys)
  1.4551 +          row-values (fn [] (map (fn [^Integer i] (. rs (getObject i))) idxs))
  1.4552 +          rows (fn thisfn []
  1.4553 +                 (when (. rs (next))
  1.4554 +                   (cons (apply struct row-struct (row-values)) (lazy-seq (thisfn)))))]
  1.4555 +      (rows)))
  1.4556 +
  1.4557 +(defn iterator-seq
  1.4558 +  "Returns a seq on a java.util.Iterator. Note that most collections
  1.4559 +  providing iterators implement Iterable and thus support seq directly."
  1.4560 +  {:added "1.0"}
  1.4561 +  [iter]
  1.4562 +  (clojure.lang.IteratorSeq/create iter))
  1.4563 +
  1.4564 +(defn enumeration-seq
  1.4565 +  "Returns a seq on a java.util.Enumeration"
  1.4566 +  {:added "1.0"}
  1.4567 +  [e]
  1.4568 +  (clojure.lang.EnumerationSeq/create e))
  1.4569 +
  1.4570 +(defn format
  1.4571 +  "Formats a string using java.lang.String.format, see java.util.Formatter for format
  1.4572 +  string syntax"
  1.4573 +  {:tag String
  1.4574 +   :added "1.0"}
  1.4575 +  [fmt & args]
  1.4576 +  (String/format fmt (to-array args)))
  1.4577 +
  1.4578 +(defn printf
  1.4579 +  "Prints formatted output, as per format"
  1.4580 +  {:added "1.0"}
  1.4581 +  [fmt & args]
  1.4582 +  (print (apply format fmt args)))
  1.4583 +
  1.4584 +(declare gen-class)
  1.4585 +
  1.4586 +(defmacro with-loading-context [& body]
  1.4587 +  `((fn loading# [] 
  1.4588 +        (. clojure.lang.Var (pushThreadBindings {clojure.lang.Compiler/LOADER  
  1.4589 +                                                 (.getClassLoader (.getClass ^Object loading#))}))
  1.4590 +        (try
  1.4591 +         ~@body
  1.4592 +         (finally
  1.4593 +          (. clojure.lang.Var (popThreadBindings)))))))
  1.4594 +
  1.4595 +(defmacro ns
  1.4596 +  "Sets *ns* to the namespace named by name (unevaluated), creating it
  1.4597 +  if needed.  references can be zero or more of: (:refer-clojure ...)
  1.4598 +  (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class)
  1.4599 +  with the syntax of refer-clojure/require/use/import/load/gen-class
  1.4600 +  respectively, except the arguments are unevaluated and need not be
  1.4601 +  quoted. (:gen-class ...), when supplied, defaults to :name
  1.4602 +  corresponding to the ns name, :main true, :impl-ns same as ns, and
  1.4603 +  :init-impl-ns true. All options of gen-class are
  1.4604 +  supported. The :gen-class directive is ignored when not
  1.4605 +  compiling. If :gen-class is not supplied, when compiled only an
  1.4606 +  nsname__init.class will be generated. If :refer-clojure is not used, a
  1.4607 +  default (refer 'clojure) is used.  Use of ns is preferred to
  1.4608 +  individual calls to in-ns/require/use/import:
  1.4609 +
  1.4610 +  (ns foo.bar
  1.4611 +    (:refer-clojure :exclude [ancestors printf])
  1.4612 +    (:require (clojure.contrib sql sql.tests))
  1.4613 +    (:use (my.lib this that))
  1.4614 +    (:import (java.util Date Timer Random)
  1.4615 +             (java.sql Connection Statement)))"
  1.4616 +  {:arglists '([name docstring? attr-map? references*])
  1.4617 +   :added "1.0"}
  1.4618 +  [name & references]
  1.4619 +  (let [process-reference
  1.4620 +        (fn [[kname & args]]
  1.4621 +          `(~(symbol "clojure.core" (clojure.core/name kname))
  1.4622 +             ~@(map #(list 'quote %) args)))
  1.4623 +        docstring  (when (string? (first references)) (first references))
  1.4624 +        references (if docstring (next references) references)
  1.4625 +        name (if docstring
  1.4626 +               (vary-meta name assoc :doc docstring)
  1.4627 +               name)
  1.4628 +        metadata   (when (map? (first references)) (first references))
  1.4629 +        references (if metadata (next references) references)
  1.4630 +        name (if metadata
  1.4631 +               (vary-meta name merge metadata)
  1.4632 +               name)
  1.4633 +        gen-class-clause (first (filter #(= :gen-class (first %)) references))
  1.4634 +        gen-class-call
  1.4635 +          (when gen-class-clause
  1.4636 +            (list* `gen-class :name (.replace (str name) \- \_) :impl-ns name :main true (next gen-class-clause)))
  1.4637 +        references (remove #(= :gen-class (first %)) references)
  1.4638 +        ;ns-effect (clojure.core/in-ns name)
  1.4639 +        ]
  1.4640 +    `(do
  1.4641 +       (clojure.core/in-ns '~name)
  1.4642 +       (with-loading-context
  1.4643 +        ~@(when gen-class-call (list gen-class-call))
  1.4644 +        ~@(when (and (not= name 'clojure.core) (not-any? #(= :refer-clojure (first %)) references))
  1.4645 +            `((clojure.core/refer '~'clojure.core)))
  1.4646 +        ~@(map process-reference references)))))
  1.4647 +
  1.4648 +(defmacro refer-clojure
  1.4649 +  "Same as (refer 'clojure.core <filters>)"
  1.4650 +  {:added "1.0"}
  1.4651 +  [& filters]
  1.4652 +  `(clojure.core/refer '~'clojure.core ~@filters))
  1.4653 +
  1.4654 +(defmacro defonce
  1.4655 +  "defs name to have the root value of the expr iff the named var has no root value,
  1.4656 +  else expr is unevaluated"
  1.4657 +  {:added "1.0"}
  1.4658 +  [name expr]
  1.4659 +  `(let [v# (def ~name)]
  1.4660 +     (when-not (.hasRoot v#)
  1.4661 +       (def ~name ~expr))))
  1.4662 +
  1.4663 +;;;;;;;;;;; require/use/load, contributed by Stephen C. Gilardi ;;;;;;;;;;;;;;;;;;
  1.4664 +
  1.4665 +(defonce
  1.4666 +  ^{:private true
  1.4667 +     :doc "A ref to a sorted set of symbols representing loaded libs"}
  1.4668 +  *loaded-libs* (ref (sorted-set)))
  1.4669 +
  1.4670 +(defonce
  1.4671 +  ^{:private true
  1.4672 +     :doc "the set of paths currently being loaded by this thread"}
  1.4673 +  *pending-paths* #{})
  1.4674 +
  1.4675 +(defonce
  1.4676 +  ^{:private true :doc
  1.4677 +     "True while a verbose load is pending"}
  1.4678 +  *loading-verbosely* false)
  1.4679 +
  1.4680 +(defn- throw-if
  1.4681 +  "Throws an exception with a message if pred is true"
  1.4682 +  [pred fmt & args]
  1.4683 +  (when pred
  1.4684 +    (let [^String message (apply format fmt args)
  1.4685 +          exception (Exception. message)
  1.4686 +          raw-trace (.getStackTrace exception)
  1.4687 +          boring? #(not= (.getMethodName ^StackTraceElement %) "doInvoke")
  1.4688 +          trace (into-array (drop 2 (drop-while boring? raw-trace)))]
  1.4689 +      (.setStackTrace exception trace)
  1.4690 +      (throw exception))))
  1.4691 +
  1.4692 +(defn- libspec?
  1.4693 +  "Returns true if x is a libspec"
  1.4694 +  [x]
  1.4695 +  (or (symbol? x)
  1.4696 +      (and (vector? x)
  1.4697 +           (or
  1.4698 +            (nil? (second x))
  1.4699 +            (keyword? (second x))))))
  1.4700 +
  1.4701 +(defn- prependss
  1.4702 +  "Prepends a symbol or a seq to coll"
  1.4703 +  [x coll]
  1.4704 +  (if (symbol? x)
  1.4705 +    (cons x coll)
  1.4706 +    (concat x coll)))
  1.4707 +
  1.4708 +(defn- root-resource
  1.4709 +  "Returns the root directory path for a lib"
  1.4710 +  {:tag String}
  1.4711 +  [lib]
  1.4712 +  (str \/
  1.4713 +       (.. (name lib)
  1.4714 +           (replace \- \_)
  1.4715 +           (replace \. \/))))
  1.4716 +
  1.4717 +(defn- root-directory
  1.4718 +  "Returns the root resource path for a lib"
  1.4719 +  [lib]
  1.4720 +  (let [d (root-resource lib)]
  1.4721 +    (subs d 0 (.lastIndexOf d "/"))))
  1.4722 +
  1.4723 +(declare load)
  1.4724 +
  1.4725 +(defn- load-one
  1.4726 +  "Loads a lib given its name. If need-ns, ensures that the associated
  1.4727 +  namespace exists after loading. If require, records the load so any
  1.4728 +  duplicate loads can be skipped."
  1.4729 +  [lib need-ns require]
  1.4730 +  (load (root-resource lib))
  1.4731 +  (throw-if (and need-ns (not (find-ns lib)))
  1.4732 +            "namespace '%s' not found after loading '%s'"
  1.4733 +            lib (root-resource lib))
  1.4734 +  (when require
  1.4735 +    (dosync
  1.4736 +     (commute *loaded-libs* conj lib))))
  1.4737 +
  1.4738 +(defn- load-all
  1.4739 +  "Loads a lib given its name and forces a load of any libs it directly or
  1.4740 +  indirectly loads. If need-ns, ensures that the associated namespace
  1.4741 +  exists after loading. If require, records the load so any duplicate loads
  1.4742 +  can be skipped."
  1.4743 +  [lib need-ns require]
  1.4744 +  (dosync
  1.4745 +   (commute *loaded-libs* #(reduce conj %1 %2)
  1.4746 +            (binding [*loaded-libs* (ref (sorted-set))]
  1.4747 +              (load-one lib need-ns require)
  1.4748 +              @*loaded-libs*))))
  1.4749 +
  1.4750 +(defn- load-lib
  1.4751 +  "Loads a lib with options"
  1.4752 +  [prefix lib & options]
  1.4753 +  (throw-if (and prefix (pos? (.indexOf (name lib) (int \.))))
  1.4754 +            "lib names inside prefix lists must not contain periods")
  1.4755 +  (let [lib (if prefix (symbol (str prefix \. lib)) lib)
  1.4756 +        opts (apply hash-map options)
  1.4757 +        {:keys [as reload reload-all require use verbose]} opts
  1.4758 +        loaded (contains? @*loaded-libs* lib)
  1.4759 +        load (cond reload-all
  1.4760 +                   load-all
  1.4761 +                   (or reload (not require) (not loaded))
  1.4762 +                   load-one)
  1.4763 +        need-ns (or as use)
  1.4764 +        filter-opts (select-keys opts '(:exclude :only :rename))]
  1.4765 +    (binding [*loading-verbosely* (or *loading-verbosely* verbose)]
  1.4766 +      (if load
  1.4767 +        (load lib need-ns require)
  1.4768 +        (throw-if (and need-ns (not (find-ns lib)))
  1.4769 +                  "namespace '%s' not found" lib))
  1.4770 +      (when (and need-ns *loading-verbosely*)
  1.4771 +        (printf "(clojure.core/in-ns '%s)\n" (ns-name *ns*)))
  1.4772 +      (when as
  1.4773 +        (when *loading-verbosely*
  1.4774 +          (printf "(clojure.core/alias '%s '%s)\n" as lib))
  1.4775 +        (alias as lib))
  1.4776 +      (when use
  1.4777 +        (when *loading-verbosely*
  1.4778 +          (printf "(clojure.core/refer '%s" lib)
  1.4779 +          (doseq [opt filter-opts]
  1.4780 +            (printf " %s '%s" (key opt) (print-str (val opt))))
  1.4781 +          (printf ")\n"))
  1.4782 +        (apply refer lib (mapcat seq filter-opts))))))
  1.4783 +
  1.4784 +(defn- load-libs
  1.4785 +  "Loads libs, interpreting libspecs, prefix lists, and flags for
  1.4786 +  forwarding to load-lib"
  1.4787 +  [& args]
  1.4788 +  (let [flags (filter keyword? args)
  1.4789 +        opts (interleave flags (repeat true))
  1.4790 +        args (filter (complement keyword?) args)]
  1.4791 +    ; check for unsupported options
  1.4792 +    (let [supported #{:as :reload :reload-all :require :use :verbose} 
  1.4793 +          unsupported (seq (remove supported flags))]
  1.4794 +      (throw-if unsupported
  1.4795 +                (apply str "Unsupported option(s) supplied: "
  1.4796 +                     (interpose \, unsupported))))
  1.4797 +    ; check a load target was specified
  1.4798 +    (throw-if (not (seq args)) "Nothing specified to load")
  1.4799 +    (doseq [arg args]
  1.4800 +      (if (libspec? arg)
  1.4801 +        (apply load-lib nil (prependss arg opts))
  1.4802 +        (let [[prefix & args] arg]
  1.4803 +          (throw-if (nil? prefix) "prefix cannot be nil")
  1.4804 +          (doseq [arg args]
  1.4805 +            (apply load-lib prefix (prependss arg opts))))))))
  1.4806 +
  1.4807 +;; Public
  1.4808 +
  1.4809 +
  1.4810 +(defn require
  1.4811 +  "Loads libs, skipping any that are already loaded. Each argument is
  1.4812 +  either a libspec that identifies a lib, a prefix list that identifies
  1.4813 +  multiple libs whose names share a common prefix, or a flag that modifies
  1.4814 +  how all the identified libs are loaded. Use :require in the ns macro
  1.4815 +  in preference to calling this directly.
  1.4816 +
  1.4817 +  Libs
  1.4818 +
  1.4819 +  A 'lib' is a named set of resources in classpath whose contents define a
  1.4820 +  library of Clojure code. Lib names are symbols and each lib is associated
  1.4821 +  with a Clojure namespace and a Java package that share its name. A lib's
  1.4822 +  name also locates its root directory within classpath using Java's
  1.4823 +  package name to classpath-relative path mapping. All resources in a lib
  1.4824 +  should be contained in the directory structure under its root directory.
  1.4825 +  All definitions a lib makes should be in its associated namespace.
  1.4826 +
  1.4827 +  'require loads a lib by loading its root resource. The root resource path
  1.4828 +  is derived from the lib name in the following manner:
  1.4829 +  Consider a lib named by the symbol 'x.y.z; it has the root directory
  1.4830 +  <classpath>/x/y/, and its root resource is <classpath>/x/y/z.clj. The root
  1.4831 +  resource should contain code to create the lib's namespace (usually by using
  1.4832 +  the ns macro) and load any additional lib resources.
  1.4833 +
  1.4834 +  Libspecs
  1.4835 +
  1.4836 +  A libspec is a lib name or a vector containing a lib name followed by
  1.4837 +  options expressed as sequential keywords and arguments.
  1.4838 +
  1.4839 +  Recognized options: :as
  1.4840 +  :as takes a symbol as its argument and makes that symbol an alias to the
  1.4841 +    lib's namespace in the current namespace.
  1.4842 +
  1.4843 +  Prefix Lists
  1.4844 +
  1.4845 +  It's common for Clojure code to depend on several libs whose names have
  1.4846 +  the same prefix. When specifying libs, prefix lists can be used to reduce
  1.4847 +  repetition. A prefix list contains the shared prefix followed by libspecs
  1.4848 +  with the shared prefix removed from the lib names. After removing the
  1.4849 +  prefix, the names that remain must not contain any periods.
  1.4850 +
  1.4851 +  Flags
  1.4852 +
  1.4853 +  A flag is a keyword.
  1.4854 +  Recognized flags: :reload, :reload-all, :verbose
  1.4855 +  :reload forces loading of all the identified libs even if they are
  1.4856 +    already loaded
  1.4857 +  :reload-all implies :reload and also forces loading of all libs that the
  1.4858 +    identified libs directly or indirectly load via require or use
  1.4859 +  :verbose triggers printing information about each load, alias, and refer
  1.4860 +
  1.4861 +  Example:
  1.4862 +
  1.4863 +  The following would load the libraries clojure.zip and clojure.set
  1.4864 +  abbreviated as 's'.
  1.4865 +
  1.4866 +  (require '(clojure zip [set :as s]))"
  1.4867 +  {:added "1.0"}
  1.4868 +
  1.4869 +  [& args]
  1.4870 +  (apply load-libs :require args))
  1.4871 +
  1.4872 +(defn use
  1.4873 +  "Like 'require, but also refers to each lib's namespace using
  1.4874 +  clojure.core/refer. Use :use in the ns macro in preference to calling
  1.4875 +  this directly.
  1.4876 +
  1.4877 +  'use accepts additional options in libspecs: :exclude, :only, :rename.
  1.4878 +  The arguments and semantics for :exclude, :only, and :rename are the same
  1.4879 +  as those documented for clojure.core/refer."
  1.4880 +  {:added "1.0"}
  1.4881 +  [& args] (apply load-libs :require :use args))
  1.4882 +
  1.4883 +(defn loaded-libs
  1.4884 +  "Returns a sorted set of symbols naming the currently loaded libs"
  1.4885 +  {:added "1.0"}
  1.4886 +  [] @*loaded-libs*)
  1.4887 +
  1.4888 +(defn load
  1.4889 +  "Loads Clojure code from resources in classpath. A path is interpreted as
  1.4890 +  classpath-relative if it begins with a slash or relative to the root
  1.4891 +  directory for the current namespace otherwise."
  1.4892 +  {:added "1.0"}
  1.4893 +  [& paths]
  1.4894 +  (doseq [^String path paths]
  1.4895 +    (let [^String path (if (.startsWith path "/")
  1.4896 +                          path
  1.4897 +                          (str (root-directory (ns-name *ns*)) \/ path))]
  1.4898 +      (when *loading-verbosely*
  1.4899 +        (printf "(clojure.core/load \"%s\")\n" path)
  1.4900 +        (flush))
  1.4901 +;      (throw-if (*pending-paths* path)
  1.4902 +;                "cannot load '%s' again while it is loading"
  1.4903 +;                path)
  1.4904 +      (when-not (*pending-paths* path)
  1.4905 +        (binding [*pending-paths* (conj *pending-paths* path)]
  1.4906 +          (clojure.lang.RT/load  (.substring path 1)))))))
  1.4907 +
  1.4908 +(defn compile
  1.4909 +  "Compiles the namespace named by the symbol lib into a set of
  1.4910 +  classfiles. The source for the lib must be in a proper
  1.4911 +  classpath-relative directory. The output files will go into the
  1.4912 +  directory specified by *compile-path*, and that directory too must
  1.4913 +  be in the classpath."
  1.4914 +  {:added "1.0"}
  1.4915 +  [lib]
  1.4916 +  (binding [*compile-files* true]
  1.4917 +    (load-one lib true true))
  1.4918 +  lib)
  1.4919 +
  1.4920 +;;;;;;;;;;;;; nested associative ops ;;;;;;;;;;;
  1.4921 +
  1.4922 +(defn get-in
  1.4923 +  "Returns the value in a nested associative structure,
  1.4924 +  where ks is a sequence of ke(ys. Returns nil if the key is not present,
  1.4925 +  or the not-found value if supplied."
  1.4926 +  {:added "1.2"}
  1.4927 +  ([m ks]
  1.4928 +     (reduce get m ks))
  1.4929 +  ([m ks not-found]
  1.4930 +     (loop [sentinel (Object.)
  1.4931 +            m m
  1.4932 +            ks (seq ks)]
  1.4933 +       (if ks
  1.4934 +         (let [m (get m (first ks) sentinel)]
  1.4935 +           (if (identical? sentinel m)
  1.4936 +             not-found
  1.4937 +             (recur sentinel m (next ks))))
  1.4938 +         m))))
  1.4939 +
  1.4940 +(defn assoc-in
  1.4941 +  "Associates a value in a nested associative structure, where ks is a
  1.4942 +  sequence of keys and v is the new value and returns a new nested structure.
  1.4943 +  If any levels do not exist, hash-maps will be created."
  1.4944 +  {:added "1.0"}
  1.4945 +  [m [k & ks] v]
  1.4946 +  (if ks
  1.4947 +    (assoc m k (assoc-in (get m k) ks v))
  1.4948 +    (assoc m k v)))
  1.4949 +
  1.4950 +(defn update-in
  1.4951 +  "'Updates' a value in a nested associative structure, where ks is a
  1.4952 +  sequence of keys and f is a function that will take the old value
  1.4953 +  and any supplied args and return the new value, and returns a new
  1.4954 +  nested structure.  If any levels do not exist, hash-maps will be
  1.4955 +  created."
  1.4956 +  {:added "1.0"}
  1.4957 +  ([m [k & ks] f & args]
  1.4958 +   (if ks
  1.4959 +     (assoc m k (apply update-in (get m k) ks f args))
  1.4960 +     (assoc m k (apply f (get m k) args)))))
  1.4961 +
  1.4962 +
  1.4963 +(defn empty?
  1.4964 +  "Returns true if coll has no items - same as (not (seq coll)).
  1.4965 +  Please use the idiom (seq x) rather than (not (empty? x))"
  1.4966 +  {:added "1.0"}
  1.4967 +  [coll] (not (seq coll)))
  1.4968 +
  1.4969 +(defn coll?
  1.4970 +  "Returns true if x implements IPersistentCollection"
  1.4971 +  {:added "1.0"}
  1.4972 +  [x] (instance? clojure.lang.IPersistentCollection x))
  1.4973 +
  1.4974 +(defn list?
  1.4975 +  "Returns true if x implements IPersistentList"
  1.4976 +  {:added "1.0"}
  1.4977 +  [x] (instance? clojure.lang.IPersistentList x))
  1.4978 +
  1.4979 +(defn set?
  1.4980 +  "Returns true if x implements IPersistentSet"
  1.4981 +  {:added "1.0"}
  1.4982 +  [x] (instance? clojure.lang.IPersistentSet x))
  1.4983 +
  1.4984 +(defn ifn?
  1.4985 +  "Returns true if x implements IFn. Note that many data structures
  1.4986 +  (e.g. sets and maps) implement IFn"
  1.4987 +  {:added "1.0"}
  1.4988 +  [x] (instance? clojure.lang.IFn x))
  1.4989 +
  1.4990 +(defn fn?
  1.4991 +  "Returns true if x implements Fn, i.e. is an object created via fn."
  1.4992 +  {:added "1.0"}
  1.4993 +  [x] (instance? clojure.lang.Fn x))
  1.4994 +
  1.4995 +
  1.4996 +(defn associative?
  1.4997 + "Returns true if coll implements Associative"
  1.4998 + {:added "1.0"}
  1.4999 +  [coll] (instance? clojure.lang.Associative coll))
  1.5000 +
  1.5001 +(defn sequential?
  1.5002 + "Returns true if coll implements Sequential"
  1.5003 + {:added "1.0"}
  1.5004 +  [coll] (instance? clojure.lang.Sequential coll))
  1.5005 +
  1.5006 +(defn sorted?
  1.5007 + "Returns true if coll implements Sorted"
  1.5008 + {:added "1.0"}
  1.5009 +  [coll] (instance? clojure.lang.Sorted coll))
  1.5010 +
  1.5011 +(defn counted?
  1.5012 + "Returns true if coll implements count in constant time"
  1.5013 + {:added "1.0"}
  1.5014 +  [coll] (instance? clojure.lang.Counted coll))
  1.5015 +
  1.5016 +(defn reversible?
  1.5017 + "Returns true if coll implements Reversible"
  1.5018 + {:added "1.0"}
  1.5019 +  [coll] (instance? clojure.lang.Reversible coll))
  1.5020 +
  1.5021 +(def
  1.5022 + ^{:doc "bound in a repl thread to the most recent value printed"
  1.5023 +   :added "1.0"}
  1.5024 + *1)
  1.5025 +
  1.5026 +(def
  1.5027 + ^{:doc "bound in a repl thread to the second most recent value printed"
  1.5028 +   :added "1.0"}
  1.5029 + *2)
  1.5030 +
  1.5031 +(def
  1.5032 + ^{:doc "bound in a repl thread to the third most recent value printed"
  1.5033 +   :added "1.0"}
  1.5034 + *3)
  1.5035 +
  1.5036 +(def
  1.5037 + ^{:doc "bound in a repl thread to the most recent exception caught by the repl"
  1.5038 +   :added "1.0"}
  1.5039 + *e)
  1.5040 +
  1.5041 +(defn trampoline
  1.5042 +  "trampoline can be used to convert algorithms requiring mutual
  1.5043 +  recursion without stack consumption. Calls f with supplied args, if
  1.5044 +  any. If f returns a fn, calls that fn with no arguments, and
  1.5045 +  continues to repeat, until the return value is not a fn, then
  1.5046 +  returns that non-fn value. Note that if you want to return a fn as a
  1.5047 +  final value, you must wrap it in some data structure and unpack it
  1.5048 +  after trampoline returns."
  1.5049 +  {:added "1.0"}
  1.5050 +  ([f]
  1.5051 +     (let [ret (f)]
  1.5052 +       (if (fn? ret)
  1.5053 +         (recur ret)
  1.5054 +         ret)))
  1.5055 +  ([f & args]
  1.5056 +     (trampoline #(apply f args))))
  1.5057 +
  1.5058 +(defn intern
  1.5059 +  "Finds or creates a var named by the symbol name in the namespace
  1.5060 +  ns (which can be a symbol or a namespace), setting its root binding
  1.5061 +  to val if supplied. The namespace must exist. The var will adopt any
  1.5062 +  metadata from the name symbol.  Returns the var."
  1.5063 +  {:added "1.0"}
  1.5064 +  ([ns ^clojure.lang.Symbol name]
  1.5065 +     (let [v (clojure.lang.Var/intern (the-ns ns) name)]
  1.5066 +       (when (meta name) (.setMeta v (meta name)))
  1.5067 +       v))
  1.5068 +  ([ns name val]
  1.5069 +     (let [v (clojure.lang.Var/intern (the-ns ns) name val)]
  1.5070 +       (when (meta name) (.setMeta v (meta name)))
  1.5071 +       v)))
  1.5072 +
  1.5073 +(defmacro while
  1.5074 +  "Repeatedly executes body while test expression is true. Presumes
  1.5075 +  some side-effect will cause test to become false/nil. Returns nil"
  1.5076 +  {:added "1.0"}
  1.5077 +  [test & body]
  1.5078 +  `(loop []
  1.5079 +     (when ~test
  1.5080 +       ~@body
  1.5081 +       (recur))))
  1.5082 +
  1.5083 +(defn memoize
  1.5084 +  "Returns a memoized version of a referentially transparent function. The
  1.5085 +  memoized version of the function keeps a cache of the mapping from arguments
  1.5086 +  to results and, when calls with the same arguments are repeated often, has
  1.5087 +  higher performance at the expense of higher memory use."
  1.5088 +  {:added "1.0"}
  1.5089 +  [f]
  1.5090 +  (let [mem (atom {})]
  1.5091 +    (fn [& args]
  1.5092 +      (if-let [e (find @mem args)]
  1.5093 +        (val e)
  1.5094 +        (let [ret (apply f args)]
  1.5095 +          (swap! mem assoc args ret)
  1.5096 +          ret)))))
  1.5097 +
  1.5098 +(defmacro condp
  1.5099 +  "Takes a binary predicate, an expression, and a set of clauses.
  1.5100 +  Each clause can take the form of either:
  1.5101 +
  1.5102 +  test-expr result-expr
  1.5103 +
  1.5104 +  test-expr :>> result-fn
  1.5105 +
  1.5106 +  Note :>> is an ordinary keyword.
  1.5107 +
  1.5108 +  For each clause, (pred test-expr expr) is evaluated. If it returns
  1.5109 +  logical true, the clause is a match. If a binary clause matches, the
  1.5110 +  result-expr is returned, if a ternary clause matches, its result-fn,
  1.5111 +  which must be a unary function, is called with the result of the
  1.5112 +  predicate as its argument, the result of that call being the return
  1.5113 +  value of condp. A single default expression can follow the clauses,
  1.5114 +  and its value will be returned if no clause matches. If no default
  1.5115 +  expression is provided and no clause matches, an
  1.5116 +  IllegalArgumentException is thrown."
  1.5117 +  {:added "1.0"}
  1.5118 +
  1.5119 +  [pred expr & clauses]
  1.5120 +  (let [gpred (gensym "pred__")
  1.5121 +        gexpr (gensym "expr__")
  1.5122 +        emit (fn emit [pred expr args]
  1.5123 +               (let [[[a b c :as clause] more]
  1.5124 +                       (split-at (if (= :>> (second args)) 3 2) args)
  1.5125 +                       n (count clause)]
  1.5126 +                 (cond
  1.5127 +                  (= 0 n) `(throw (IllegalArgumentException. (str "No matching clause: " ~expr)))
  1.5128 +                  (= 1 n) a
  1.5129 +                  (= 2 n) `(if (~pred ~a ~expr)
  1.5130 +                             ~b
  1.5131 +                             ~(emit pred expr more))
  1.5132 +                  :else `(if-let [p# (~pred ~a ~expr)]
  1.5133 +                           (~c p#)
  1.5134 +                           ~(emit pred expr more)))))
  1.5135 +        gres (gensym "res__")]
  1.5136 +    `(let [~gpred ~pred
  1.5137 +           ~gexpr ~expr]
  1.5138 +       ~(emit gpred gexpr clauses))))
  1.5139 +
  1.5140 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; var documentation ;;;;;;;;;;;;;;;;;;;;;;;;;;
  1.5141 +
  1.5142 +(alter-meta! #'*agent* assoc :added "1.0")
  1.5143 +(alter-meta! #'in-ns assoc :added "1.0")
  1.5144 +(alter-meta! #'load-file assoc :added "1.0")
  1.5145 +
  1.5146 +(defmacro add-doc-and-meta {:private true} [name docstring meta]
  1.5147 +  `(alter-meta! (var ~name) merge (assoc ~meta :doc ~docstring)))
  1.5148 +
  1.5149 +(add-doc-and-meta *file*
  1.5150 +  "The path of the file being evaluated, as a String.
  1.5151 +
  1.5152 +  Evaluates to nil when there is no file, eg. in the REPL."
  1.5153 +  {:added "1.0"})
  1.5154 +
  1.5155 +(add-doc-and-meta *command-line-args*
  1.5156 +  "A sequence of the supplied command line arguments, or nil if
  1.5157 +  none were supplied"
  1.5158 +  {:added "1.0"})
  1.5159 +
  1.5160 +(add-doc-and-meta *warn-on-reflection*
  1.5161 +  "When set to true, the compiler will emit warnings when reflection is
  1.5162 +  needed to resolve Java method calls or field accesses.
  1.5163 +
  1.5164 +  Defaults to false."
  1.5165 +  {:added "1.0"})
  1.5166 +
  1.5167 +(add-doc-and-meta *compile-path*
  1.5168 +  "Specifies the directory where 'compile' will write out .class
  1.5169 +  files. This directory must be in the classpath for 'compile' to
  1.5170 +  work.
  1.5171 +
  1.5172 +  Defaults to \"classes\""
  1.5173 +  {:added "1.0"})
  1.5174 +
  1.5175 +(add-doc-and-meta *compile-files*
  1.5176 +  "Set to true when compiling files, false otherwise."
  1.5177 +  {:added "1.0"})
  1.5178 +
  1.5179 +(add-doc-and-meta *ns*
  1.5180 +  "A clojure.lang.Namespace object representing the current namespace."
  1.5181 +  {:added "1.0"})
  1.5182 +
  1.5183 +(add-doc-and-meta *in*
  1.5184 +  "A java.io.Reader object representing standard input for read operations.
  1.5185 +
  1.5186 +  Defaults to System/in, wrapped in a LineNumberingPushbackReader"
  1.5187 +  {:added "1.0"})
  1.5188 +
  1.5189 +(add-doc-and-meta *out*
  1.5190 +  "A java.io.Writer object representing standard output for print operations.
  1.5191 +
  1.5192 +  Defaults to System/out"
  1.5193 +  {:added "1.0"})
  1.5194 +
  1.5195 +(add-doc-and-meta *err*
  1.5196 +  "A java.io.Writer object representing standard error for print operations.
  1.5197 +
  1.5198 +  Defaults to System/err, wrapped in a PrintWriter"
  1.5199 +  {:added "1.0"})
  1.5200 +
  1.5201 +(add-doc-and-meta *flush-on-newline*
  1.5202 +  "When set to true, output will be flushed whenever a newline is printed.
  1.5203 +
  1.5204 +  Defaults to true."
  1.5205 +  {:added "1.0"})
  1.5206 +
  1.5207 +(add-doc-and-meta *print-meta*
  1.5208 +  "If set to logical true, when printing an object, its metadata will also
  1.5209 +  be printed in a form that can be read back by the reader.
  1.5210 +
  1.5211 +  Defaults to false."
  1.5212 +  {:added "1.0"})
  1.5213 +
  1.5214 +(add-doc-and-meta *print-dup*
  1.5215 +  "When set to logical true, objects will be printed in a way that preserves
  1.5216 +  their type when read in later.
  1.5217 +
  1.5218 +  Defaults to false."
  1.5219 +  {:added "1.0"})
  1.5220 +
  1.5221 +(add-doc-and-meta *print-readably*
  1.5222 +  "When set to logical false, strings and characters will be printed with
  1.5223 +  non-alphanumeric characters converted to the appropriate escape sequences.
  1.5224 +
  1.5225 +  Defaults to true"
  1.5226 +  {:added "1.0"})
  1.5227 +
  1.5228 +(add-doc-and-meta *read-eval*
  1.5229 +  "When set to logical false, the EvalReader (#=(...)) is disabled in the 
  1.5230 +  read/load in the thread-local binding.
  1.5231 +  Example: (binding [*read-eval* false] (read-string \"#=(eval (def x 3))\"))
  1.5232 +
  1.5233 +  Defaults to true"
  1.5234 +  {:added "1.0"})
  1.5235 +
  1.5236 +(defn future?
  1.5237 +  "Returns true if x is a future"
  1.5238 +  {:added "1.1"}
  1.5239 +  [x] (instance? java.util.concurrent.Future x))
  1.5240 +
  1.5241 +(defn future-done?
  1.5242 +  "Returns true if future f is done"
  1.5243 +  {:added "1.1"}
  1.5244 +  [^java.util.concurrent.Future f] (.isDone f))
  1.5245 +
  1.5246 +
  1.5247 +(defmacro letfn 
  1.5248 +  "Takes a vector of function specs and a body, and generates a set of
  1.5249 +  bindings of functions to their names. All of the names are available
  1.5250 +  in all of the definitions of the functions, as well as the body.
  1.5251 +
  1.5252 +  fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+)"
  1.5253 +  {:added "1.0"}
  1.5254 +  [fnspecs & body] 
  1.5255 +  `(letfn* ~(vec (interleave (map first fnspecs) 
  1.5256 +                             (map #(cons `fn %) fnspecs)))
  1.5257 +           ~@body))
  1.5258 +
  1.5259 +
  1.5260 +;;;;;;; case ;;;;;;;;;;;;;
  1.5261 +(defn- shift-mask [shift mask x]
  1.5262 +  (-> x (bit-shift-right shift) (bit-and mask)))
  1.5263 +
  1.5264 +(defn- min-hash 
  1.5265 +  "takes a collection of keys and returns [shift mask]"
  1.5266 +  [keys]
  1.5267 +  (let [hashes (map hash keys)
  1.5268 +        cnt (count keys)]
  1.5269 +    (when-not (apply distinct? hashes)
  1.5270 +      (throw (IllegalArgumentException. "Hashes must be distinct")))
  1.5271 +    (or (first 
  1.5272 +         (filter (fn [[s m]]
  1.5273 +                   (apply distinct? (map #(shift-mask s m %) hashes)))
  1.5274 +                 (for [mask (map #(dec (bit-shift-left 1 %)) (range 1 14))
  1.5275 +                       shift (range 0 31)]
  1.5276 +                   [shift mask])))
  1.5277 +        (throw (IllegalArgumentException. "No distinct mapping found")))))
  1.5278 +
  1.5279 +(defmacro case 
  1.5280 +  "Takes an expression, and a set of clauses.
  1.5281 +
  1.5282 +  Each clause can take the form of either:
  1.5283 +
  1.5284 +  test-constant result-expr
  1.5285 +
  1.5286 +  (test-constant1 ... test-constantN)  result-expr
  1.5287 +
  1.5288 +  The test-constants are not evaluated. They must be compile-time
  1.5289 +  literals, and need not be quoted.  If the expression is equal to a
  1.5290 +  test-constant, the corresponding result-expr is returned. A single
  1.5291 +  default expression can follow the clauses, and its value will be
  1.5292 +  returned if no clause matches. If no default expression is provided
  1.5293 +  and no clause matches, an IllegalArgumentException is thrown.
  1.5294 +
  1.5295 +  Unlike cond and condp, case does a constant-time dispatch, the
  1.5296 +  clauses are not considered sequentially.  All manner of constant
  1.5297 +  expressions are acceptable in case, including numbers, strings,
  1.5298 +  symbols, keywords, and (Clojure) composites thereof. Note that since
  1.5299 +  lists are used to group multiple constants that map to the same
  1.5300 +  expression, a vector can be used to match a list if needed. The
  1.5301 +  test-constants need not be all of the same type."
  1.5302 +  {:added "1.2"}
  1.5303 +
  1.5304 +  [e & clauses]
  1.5305 +  (let [ge (with-meta (gensym) {:tag Object})
  1.5306 +        default (if (odd? (count clauses)) 
  1.5307 +                  (last clauses)
  1.5308 +                  `(throw (IllegalArgumentException. (str "No matching clause: " ~ge))))
  1.5309 +        cases (partition 2 clauses)
  1.5310 +        case-map (reduce (fn [m [test expr]]
  1.5311 +                           (if (seq? test)
  1.5312 +                             (into m (zipmap test (repeat expr)))
  1.5313 +                             (assoc m test expr))) 
  1.5314 +                           {} cases)
  1.5315 +        [shift mask] (if (seq case-map) (min-hash (keys case-map)) [0 0])
  1.5316 +        
  1.5317 +        hmap (reduce (fn [m [test expr :as te]]
  1.5318 +                       (assoc m (shift-mask shift mask (hash test)) te))
  1.5319 +                     (sorted-map) case-map)]
  1.5320 +    `(let [~ge ~e]
  1.5321 +       ~(condp = (count clauses)
  1.5322 +          0 default
  1.5323 +          1 default
  1.5324 +          `(case* ~ge ~shift ~mask ~(key (first hmap)) ~(key (last hmap)) ~default ~hmap 
  1.5325 +                        ~(every? keyword? (keys case-map)))))))
  1.5326 +
  1.5327 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; helper files ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1.5328 +(alter-meta! (find-ns 'clojure.core) assoc :doc "Fundamental library of the Clojure language")
  1.5329 +(load "core_proxy")
  1.5330 +(load "core_print")
  1.5331 +(load "genclass")
  1.5332 +(load "core_deftype")
  1.5333 +(load "core/protocols")
  1.5334 +(load "gvec")
  1.5335 +
  1.5336 +;; redefine reduce with internal-reduce
  1.5337 +#_(defn reduce
  1.5338 +  "f should be a function of 2 arguments. If val is not supplied,
  1.5339 +  returns the result of applying f to the first 2 items in coll, then
  1.5340 +  applying f to that result and the 3rd item, etc. If coll contains no
  1.5341 +  items, f must accept no arguments as well, and reduce returns the
  1.5342 +  result of calling f with no arguments.  If coll has only 1 item, it
  1.5343 +  is returned and f is not called.  If val is supplied, returns the
  1.5344 +  result of applying f to val and the first item in coll, then
  1.5345 +  applying f to that result and the 2nd item, etc. If coll contains no
  1.5346 +  items, returns val and f is not called."
  1.5347 +  {:added "1.0"}
  1.5348 +  ([f coll]
  1.5349 +     (if-let [s (seq coll)]
  1.5350 +       (reduce f (first s) (next s))
  1.5351 +       (f)))
  1.5352 +  ([f val coll]
  1.5353 +     (let [s (seq coll)]
  1.5354 +       (clojure.core.protocols/internal-reduce s f val))))
  1.5355 +
  1.5356 +(require '[clojure.java.io :as jio])
  1.5357 +
  1.5358 +(defn- normalize-slurp-opts
  1.5359 +  [opts]
  1.5360 +  (if (string? (first opts))
  1.5361 +    (do
  1.5362 +      (println "WARNING: (slurp f enc) is deprecated, use (slurp f :encoding enc).")
  1.5363 +      [:encoding (first opts)])
  1.5364 +    opts))
  1.5365 +
  1.5366 +(defn slurp
  1.5367 +  "Reads the file named by f using the encoding enc into a string
  1.5368 +  and returns it."
  1.5369 +  {:added "1.0"}
  1.5370 +  ([f & opts]
  1.5371 +     (let [opts (normalize-slurp-opts opts)
  1.5372 +           sb (StringBuilder.)]
  1.5373 +       (with-open [#^java.io.Reader r (apply jio/reader f opts)]
  1.5374 +         (loop [c (.read r)]
  1.5375 +           (if (neg? c)
  1.5376 +             (str sb)
  1.5377 +             (do
  1.5378 +               (.append sb (char c))
  1.5379 +               (recur (.read r)))))))))
  1.5380 +
  1.5381 +(defn spit
  1.5382 +  "Opposite of slurp.  Opens f with writer, writes content, then
  1.5383 +  closes f. Options passed to clojure.java.io/writer."
  1.5384 +  {:added "1.2"}
  1.5385 +  [f content & options]
  1.5386 +  (with-open [#^java.io.Writer w (apply jio/writer f options)]
  1.5387 +    (.write w (str content))))
  1.5388 +
  1.5389 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; futures (needs proxy);;;;;;;;;;;;;;;;;;
  1.5390 +(defn future-call 
  1.5391 +  "Takes a function of no args and yields a future object that will
  1.5392 +  invoke the function in another thread, and will cache the result and
  1.5393 +  return it on all subsequent calls to deref/@. If the computation has
  1.5394 +  not yet finished, calls to deref/@ will block."
  1.5395 +  {:added "1.1"}
  1.5396 +  [^Callable f]
  1.5397 +  (let [fut (.submit clojure.lang.Agent/soloExecutor f)]
  1.5398 +    (reify 
  1.5399 +     clojure.lang.IDeref 
  1.5400 +      (deref [_] (.get fut))
  1.5401 +     java.util.concurrent.Future
  1.5402 +      (get [_] (.get fut))
  1.5403 +      (get [_ timeout unit] (.get fut timeout unit))
  1.5404 +      (isCancelled [_] (.isCancelled fut))
  1.5405 +      (isDone [_] (.isDone fut))
  1.5406 +      (cancel [_ interrupt?] (.cancel fut interrupt?)))))
  1.5407 +  
  1.5408 +(defmacro future
  1.5409 +  "Takes a body of expressions and yields a future object that will
  1.5410 +  invoke the body in another thread, and will cache the result and
  1.5411 +  return it on all subsequent calls to deref/@. If the computation has
  1.5412 +  not yet finished, calls to deref/@ will block."
  1.5413 +  {:added "1.1"}
  1.5414 +  [& body] `(future-call (^{:once true} fn* [] ~@body)))
  1.5415 +
  1.5416 +
  1.5417 +(defn future-cancel
  1.5418 +  "Cancels the future, if possible."
  1.5419 +  {:added "1.1"}
  1.5420 +  [^java.util.concurrent.Future f] (.cancel f true))
  1.5421 +
  1.5422 +(defn future-cancelled?
  1.5423 +  "Returns true if future f is cancelled"
  1.5424 +  {:added "1.1"}
  1.5425 +  [^java.util.concurrent.Future f] (.isCancelled f))
  1.5426 +
  1.5427 +(defn pmap
  1.5428 +  "Like map, except f is applied in parallel. Semi-lazy in that the
  1.5429 +  parallel computation stays ahead of the consumption, but doesn't
  1.5430 +  realize the entire result unless required. Only useful for
  1.5431 +  computationally intensive functions where the time of f dominates
  1.5432 +  the coordination overhead."
  1.5433 +  {:added "1.0"}
  1.5434 +  ([f coll]
  1.5435 +   (let [n (+ 2 (.. Runtime getRuntime availableProcessors))
  1.5436 +         rets (map #(future (f %)) coll)
  1.5437 +         step (fn step [[x & xs :as vs] fs]
  1.5438 +                (lazy-seq
  1.5439 +                 (if-let [s (seq fs)]
  1.5440 +                   (cons (deref x) (step xs (rest s)))
  1.5441 +                   (map deref vs))))]
  1.5442 +     (step rets (drop n rets))))
  1.5443 +  ([f coll & colls]
  1.5444 +   (let [step (fn step [cs]
  1.5445 +                (lazy-seq
  1.5446 +                 (let [ss (map seq cs)]
  1.5447 +                   (when (every? identity ss)
  1.5448 +                     (cons (map first ss) (step (map rest ss)))))))]
  1.5449 +     (pmap #(apply f %) (step (cons coll colls))))))
  1.5450 +
  1.5451 +(defn pcalls
  1.5452 +  "Executes the no-arg fns in parallel, returning a lazy sequence of
  1.5453 +  their values"
  1.5454 +  {:added "1.0"}
  1.5455 +  [& fns] (pmap #(%) fns))
  1.5456 +
  1.5457 +(defmacro pvalues
  1.5458 +  "Returns a lazy sequence of the values of the exprs, which are
  1.5459 +  evaluated in parallel"
  1.5460 +  {:added "1.0"}
  1.5461 +  [& exprs]
  1.5462 +  `(pcalls ~@(map #(list `fn [] %) exprs)))
  1.5463 +
  1.5464 +
  1.5465 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; clojure version number ;;;;;;;;;;;;;;;;;;;;;;
  1.5466 +
  1.5467 +(let [version-stream (.getResourceAsStream (clojure.lang.RT/baseLoader) 
  1.5468 +                                           "clojure/version.properties")
  1.5469 +      properties     (doto (new java.util.Properties) (.load version-stream))
  1.5470 +      prop (fn [k] (.getProperty properties (str "clojure.version." k)))
  1.5471 +      clojure-version {:major       (Integer/valueOf ^String (prop "major"))
  1.5472 +                       :minor       (Integer/valueOf ^String (prop "minor"))
  1.5473 +                       :incremental (Integer/valueOf ^String (prop "incremental"))
  1.5474 +                       :qualifier   (prop "qualifier")}]
  1.5475 +  (def *clojure-version* 
  1.5476 +    (if (not (= (prop "interim") "false"))
  1.5477 +      (clojure.lang.RT/assoc clojure-version :interim true)
  1.5478 +      clojure-version)))
  1.5479 +      
  1.5480 +(add-doc-and-meta *clojure-version*
  1.5481 +  "The version info for Clojure core, as a map containing :major :minor 
  1.5482 +  :incremental and :qualifier keys. Feature releases may increment 
  1.5483 +  :minor and/or :major, bugfix releases will increment :incremental. 
  1.5484 +  Possible values of :qualifier include \"GA\", \"SNAPSHOT\", \"RC-x\" \"BETA-x\""
  1.5485 +  {:added "1.0"})
  1.5486 +      
  1.5487 +(defn
  1.5488 +  clojure-version 
  1.5489 +  "Returns clojure version as a printable string."
  1.5490 +  {:added "1.0"}
  1.5491 +  []
  1.5492 +  (str (:major *clojure-version*)
  1.5493 +       "."
  1.5494 +       (:minor *clojure-version*)
  1.5495 +       (when-let [i (:incremental *clojure-version*)]
  1.5496 +         (str "." i))
  1.5497 +       (when-let [q (:qualifier *clojure-version*)]
  1.5498 +         (when (pos? (count q)) (str "-" q)))
  1.5499 +       (when (:interim *clojure-version*)
  1.5500 +         "-SNAPSHOT")))
  1.5501 +
  1.5502 +(defn promise
  1.5503 +  "Alpha - subject to change.
  1.5504 +  Returns a promise object that can be read with deref/@, and set,
  1.5505 +  once only, with deliver. Calls to deref/@ prior to delivery will
  1.5506 +  block. All subsequent derefs will return the same delivered value
  1.5507 +  without blocking."
  1.5508 +  {:added "1.1"}
  1.5509 +  []
  1.5510 +  (let [d (java.util.concurrent.CountDownLatch. 1)
  1.5511 +        v (atom nil)]
  1.5512 +    (reify 
  1.5513 +     clojure.lang.IDeref
  1.5514 +      (deref [_] (.await d) @v)
  1.5515 +     clojure.lang.IFn
  1.5516 +      (invoke [this x]
  1.5517 +        (locking d
  1.5518 +          (if (pos? (.getCount d))
  1.5519 +            (do (reset! v x)
  1.5520 +                (.countDown d)
  1.5521 +                this)
  1.5522 +            (throw (IllegalStateException. "Multiple deliver calls to a promise"))))))))
  1.5523 +
  1.5524 +(defn deliver
  1.5525 +  "Alpha - subject to change.
  1.5526 +  Delivers the supplied value to the promise, releasing any pending
  1.5527 +  derefs. A subsequent call to deliver on a promise will throw an exception."
  1.5528 +  {:added "1.1"}
  1.5529 +  [promise val] (promise val))
  1.5530 +
  1.5531 +
  1.5532 +
  1.5533 +(defn flatten
  1.5534 +  "Takes any nested combination of sequential things (lists, vectors,
  1.5535 +  etc.) and returns their contents as a single, flat sequence.
  1.5536 +  (flatten nil) returns nil."
  1.5537 +  {:added "1.2"}
  1.5538 +  [x]
  1.5539 +  (filter (complement sequential?)
  1.5540 +          (rest (tree-seq sequential? seq x))))
  1.5541 +
  1.5542 +(defn group-by 
  1.5543 +  "Returns a map of the elements of coll keyed by the result of
  1.5544 +  f on each element. The value at each key will be a vector of the
  1.5545 +  corresponding elements, in the order they appeared in coll."
  1.5546 +  {:added "1.2"}
  1.5547 +  [f coll]  
  1.5548 +  (persistent!
  1.5549 +   (reduce
  1.5550 +    (fn [ret x]
  1.5551 +      (let [k (f x)]
  1.5552 +        (assoc! ret k (conj (get ret k []) x))))
  1.5553 +    (transient {}) coll)))
  1.5554 +
  1.5555 +(defn partition-by 
  1.5556 +  "Applies f to each value in coll, splitting it each time f returns
  1.5557 +   a new value.  Returns a lazy seq of partitions."
  1.5558 +  {:added "1.2"}
  1.5559 +  [f coll]
  1.5560 +  (lazy-seq
  1.5561 +   (when-let [s (seq coll)]
  1.5562 +     (let [fst (first s)
  1.5563 +           fv (f fst)
  1.5564 +           run (cons fst (take-while #(= fv (f %)) (rest s)))]
  1.5565 +       (cons run (partition-by f (drop (count run) s)))))))
  1.5566 +
  1.5567 +(defn frequencies
  1.5568 +  "Returns a map from distinct items in coll to the number of times
  1.5569 +  they appear."
  1.5570 +  {:added "1.2"}
  1.5571 +  [coll]
  1.5572 +  (persistent!
  1.5573 +   (reduce (fn [counts x]
  1.5574 +             (assoc! counts x (inc (get counts x 0))))
  1.5575 +           (transient {}) coll)))
  1.5576 +
  1.5577 +(defn reductions
  1.5578 +  "Returns a lazy seq of the intermediate values of the reduction (as
  1.5579 +  per reduce) of coll by f, starting with init."
  1.5580 +  {:added "1.2"}
  1.5581 +  ([f coll]
  1.5582 +     (lazy-seq
  1.5583 +      (if-let [s (seq coll)]
  1.5584 +        (reductions f (first s) (rest s))
  1.5585 +        (list (f)))))
  1.5586 +  ([f init coll]
  1.5587 +     (cons init
  1.5588 +           (lazy-seq
  1.5589 +            (when-let [s (seq coll)]
  1.5590 +              (reductions f (f init (first s)) (rest s)))))))
  1.5591 +
  1.5592 +(defn rand-nth
  1.5593 +  "Return a random element of the (sequential) collection. Will have
  1.5594 +  the same performance characteristics as nth for the given
  1.5595 +  collection."
  1.5596 +  {:added "1.2"}
  1.5597 +  [coll]
  1.5598 +  (nth coll (rand-int (count coll))))
  1.5599 +
  1.5600 +(defn partition-all
  1.5601 +  "Returns a lazy sequence of lists like partition, but may include
  1.5602 +  partitions with fewer than n items at the end."
  1.5603 +  {:added "1.2"}
  1.5604 +  ([n coll]
  1.5605 +     (partition-all n n coll))
  1.5606 +  ([n step coll]
  1.5607 +     (lazy-seq
  1.5608 +      (when-let [s (seq coll)]
  1.5609 +        (cons (take n s) (partition-all n step (drop step s)))))))
  1.5610 +
  1.5611 +(defn shuffle
  1.5612 +  "Return a random permutation of coll"
  1.5613 +  {:added "1.2"}
  1.5614 +  [coll]
  1.5615 +  (let [al (java.util.ArrayList. coll)]
  1.5616 +    (java.util.Collections/shuffle al)
  1.5617 +    (clojure.lang.RT/vector (.toArray al))))
  1.5618 +
  1.5619 +(defn map-indexed
  1.5620 +  "Returns a lazy sequence consisting of the result of applying f to 0
  1.5621 +  and the first item of coll, followed by applying f to 1 and the second
  1.5622 +  item in coll, etc, until coll is exhausted. Thus function f should
  1.5623 +  accept 2 arguments, index and item."
  1.5624 +  {:added "1.2"}
  1.5625 +  [f coll]
  1.5626 +  (letfn [(mapi [idx coll]
  1.5627 +            (lazy-seq
  1.5628 +             (when-let [s (seq coll)]
  1.5629 +               (if (chunked-seq? s)
  1.5630 +                 (let [c (chunk-first s)
  1.5631 +                       size (int (count c))
  1.5632 +                       b (chunk-buffer size)]
  1.5633 +                   (dotimes [i size]
  1.5634 +                     (chunk-append b (f (+ idx i) (.nth c i))))
  1.5635 +                   (chunk-cons (chunk b) (mapi (+ idx size) (chunk-rest s))))
  1.5636 +                 (cons (f idx (first s)) (mapi (inc idx) (rest s)))))))]
  1.5637 +    (mapi 0 coll)))
  1.5638 +
  1.5639 +(defn keep
  1.5640 +  "Returns a lazy sequence of the non-nil results of (f item). Note,
  1.5641 +  this means false return values will be included.  f must be free of
  1.5642 +  side-effects."
  1.5643 +  {:added "1.2"}
  1.5644 +  ([f coll]
  1.5645 +   (lazy-seq
  1.5646 +    (when-let [s (seq coll)]
  1.5647 +      (if (chunked-seq? s)
  1.5648 +        (let [c (chunk-first s)
  1.5649 +              size (count c)
  1.5650 +              b (chunk-buffer size)]
  1.5651 +          (dotimes [i size]
  1.5652 +            (let [x (f (.nth c i))]
  1.5653 +              (when-not (nil? x)
  1.5654 +                (chunk-append b x))))
  1.5655 +          (chunk-cons (chunk b) (keep f (chunk-rest s))))
  1.5656 +        (let [x (f (first s))]
  1.5657 +          (if (nil? x)
  1.5658 +            (keep f (rest s))
  1.5659 +            (cons x (keep f (rest s))))))))))
  1.5660 +
  1.5661 +(defn keep-indexed
  1.5662 +  "Returns a lazy sequence of the non-nil results of (f index item). Note,
  1.5663 +  this means false return values will be included.  f must be free of
  1.5664 +  side-effects."
  1.5665 +  {:added "1.2"}
  1.5666 +  ([f coll]
  1.5667 +     (letfn [(keepi [idx coll]
  1.5668 +               (lazy-seq
  1.5669 +                (when-let [s (seq coll)]
  1.5670 +                  (if (chunked-seq? s)
  1.5671 +                    (let [c (chunk-first s)
  1.5672 +                          size (count c)
  1.5673 +                          b (chunk-buffer size)]
  1.5674 +                      (dotimes [i size]
  1.5675 +                        (let [x (f (+ idx i) (.nth c i))]
  1.5676 +                          (when-not (nil? x)
  1.5677 +                            (chunk-append b x))))
  1.5678 +                      (chunk-cons (chunk b) (keepi (+ idx size) (chunk-rest s))))
  1.5679 +                    (let [x (f idx (first s))]
  1.5680 +                      (if (nil? x)
  1.5681 +                        (keepi (inc idx) (rest s))
  1.5682 +                        (cons x (keepi (inc idx) (rest s)))))))))]
  1.5683 +       (keepi 0 coll))))
  1.5684 +
  1.5685 +(defn fnil
  1.5686 +  "Takes a function f, and returns a function that calls f, replacing
  1.5687 +  a nil first argument to f with the supplied value x. Higher arity
  1.5688 +  versions can replace arguments in the second and third
  1.5689 +  positions (y, z). Note that the function f can take any number of
  1.5690 +  arguments, not just the one(s) being nil-patched."
  1.5691 +  {:added "1.2"}
  1.5692 +  ([f x]
  1.5693 +   (fn
  1.5694 +     ([a] (f (if (nil? a) x a)))
  1.5695 +     ([a b] (f (if (nil? a) x a) b))
  1.5696 +     ([a b c] (f (if (nil? a) x a) b c))
  1.5697 +     ([a b c & ds] (apply f (if (nil? a) x a) b c ds))))
  1.5698 +  ([f x y]
  1.5699 +   (fn
  1.5700 +     ([a b] (f (if (nil? a) x a) (if (nil? b) y b)))
  1.5701 +     ([a b c] (f (if (nil? a) x a) (if (nil? b) y b) c))
  1.5702 +     ([a b c & ds] (apply f (if (nil? a) x a) (if (nil? b) y b) c ds))))
  1.5703 +  ([f x y z]
  1.5704 +   (fn
  1.5705 +     ([a b] (f (if (nil? a) x a) (if (nil? b) y b)))
  1.5706 +     ([a b c] (f (if (nil? a) x a) (if (nil? b) y b) (if (nil? c) z c)))
  1.5707 +     ([a b c & ds] (apply f (if (nil? a) x a) (if (nil? b) y b) (if (nil? c) z c) ds)))))
  1.5708 +
  1.5709 +(defn- ^{:dynamic true} assert-valid-fdecl
  1.5710 +  "A good fdecl looks like (([a] ...) ([a b] ...)) near the end of defn."
  1.5711 +  [fdecl]
  1.5712 +  (if-let [bad-args (seq (remove #(vector? %) (map first fdecl)))]
  1.5713 +    (throw (IllegalArgumentException. (str "Parameter declaration " (first bad-args) " should be a vector")))))