summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2008-07-21 21:17:06 +0000
committerRich Hickey <richhickey@gmail.com>2008-07-21 21:17:06 +0000
commit2d7bb725966b98ff32f410fb1162286ae87961c6 (patch)
tree8935e5c9961b855c721012c87ea38c71700c3ce3
parent4c38b36cfb0fef594f06484cfaf99fb6a0b676de (diff)
removed root-level .cljs
-rw-r--r--src/boot.clj2670
-rw-r--r--src/genclass.clj517
-rw-r--r--src/inspector.clj110
-rw-r--r--src/parallel.clj248
-rw-r--r--src/proxy.clj307
-rw-r--r--src/set.clj116
-rw-r--r--src/xml.clj117
-rw-r--r--src/zip.clj248
8 files changed, 0 insertions, 4333 deletions
diff --git a/src/boot.clj b/src/boot.clj
deleted file mode 100644
index 89cda99d..00000000
--- a/src/boot.clj
+++ /dev/null
@@ -1,2670 +0,0 @@
-; Copyright (c) Rich Hickey. All rights reserved.
-; The use and distribution terms for this software are covered by the
-; Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
-; which can be found in the file CPL.TXT at the root of this distribution.
-; By using this software in any fashion, you are agreeing to be bound by
-; the terms of this license.
-; You must not remove this notice, or any other, from this software.
-
-(in-ns 'clojure)
-
-(def
- #^{:arglists '([& items])
- :doc "Creates a new list containing the items."}
- list (. clojure.lang.PersistentList creator))
-
-(def
- #^{:arglists '([x seq])
- :doc "Returns a new seq where x is the first element and seq is
- the rest."}
-
- cons (fn* cons [x seq] (. clojure.lang.RT (cons x seq))))
-
-;during bootstrap we don't have destructuring let, loop or fn, will redefine later
-(def
- #^{:macro true}
- let (fn* let [& decl] (cons 'let* decl)))
-
-(def
- #^{:macro true}
- loop (fn* loop [& decl] (cons 'loop* decl)))
-
-(def
- #^{:macro true}
- fn (fn* fn [& decl] (cons 'fn* decl)))
-
-(def
- #^{:arglists '([coll])
- :doc "Returns the first item in the collection. Calls seq on its
- argument. If coll is nil, returns nil."}
- first (fn first [coll] (. clojure.lang.RT (first coll))))
-
-(def
- #^{:arglists '([coll])
- :doc "Returns a seq of the items after the first. Calls seq on its
- argument. If there are no more items, returns nil."}
- rest (fn rest [x] (. clojure.lang.RT (rest x))))
-
-(def
- #^{:arglists '([coll x] [coll x & xs])
- :doc "conj[oin]. Returns a new collection with the xs
- 'added'. (conj nil item) returns (item). The 'addition' may
- happen at different 'places' depending on the concrete type."}
- conj (fn conj
- ([coll x] (. clojure.lang.RT (conj coll x)))
- ([coll x & xs]
- (if xs
- (recur (conj coll x) (first xs) (rest xs))
- (conj coll x)))))
-
-(def
- #^{:doc "Same as (first (rest x))"
- :arglists '([x])}
- second (fn second [x] (first (rest x))))
-
-(def
- #^{:doc "Same as (first (first x))"
- :arglists '([x])}
- ffirst (fn ffirst [x] (first (first x))))
-
-(def
- #^{:doc "Same as (rest (first x))"
- :arglists '([x])}
- rfirst (fn rfirst [x] (rest (first x))))
-
-(def
- #^{:doc "Same as (first (rest x))"
- :arglists '([x])}
- frest (fn frest [x] (first (rest x))))
-
-(def
- #^{:doc "Same as (rest (rest x))"
- :arglists '([x])}
- rrest (fn rrest [x] (rest (rest x))))
-
-(def
- #^{:arglists '([coll])
- :doc "Sequence. Returns a new ISeq on the collection. If the
- collection is empty, returns nil. (seq nil) returns nil. seq also
- works on Strings, native Java arrays (of reference types) and any
- objects that implement Iterable."
- :tag clojure.lang.ISeq}
- seq (fn seq [coll] (. clojure.lang.RT (seq coll))))
-
-(def
- #^{:arglists '([#^Class c x])
- :doc "Evaluates x and tests if it is an instance of the class
- c. Returns true or false"}
- instance? (fn instance? [#^Class c x] (. c (isInstance x))))
-
-(def
- #^{:arglists '([x])
- :doc "Return true if x implements ISeq"}
- seq? (fn seq? [x] (instance? clojure.lang.ISeq x)))
-
-(def
- #^{:arglists '([x])
- :doc "Return true if x is a String"}
- string? (fn string? [x] (instance? String x)))
-
-(def
- #^{:arglists '([x])
- :doc "Return true if x implements IPersistentMap"}
- map? (fn map? [x] (instance? clojure.lang.IPersistentMap x)))
-
-(def
- #^{:arglists '([x])
- :doc "Return true if x implements IPersistentVector "}
- vector? (fn vector? [x] (instance? clojure.lang.IPersistentVector x)))
-
-(def
- #^{:private true}
- sigs
- (fn [fdecl]
- (if (seq? (first fdecl))
- (loop [ret [] fdecl fdecl]
- (if fdecl
- (recur (conj ret (first (first fdecl))) (rest fdecl))
- (seq ret)))
- (list (first fdecl)))))
-
-(def
- #^{:arglists '([map key val] [map key val & kvs])
- :doc "assoc[iate]. When applied to a map, returns a new map of the
- same (hashed/sorted) type, that contains the mapping of key(s) to
- val(s). When applied to a vector, returns a new vector that
- contains val at index. Note - index must be <= (count vector)."}
- assoc
- (fn assoc
- ([map key val] (. clojure.lang.RT (assoc map key val)))
- ([map key val & kvs]
- (let [ret (assoc map key val)]
- (if kvs
- (recur ret (first kvs) (second kvs) (rrest kvs))
- ret)))))
-
-;;;;;;;;;;;;;;;;; metadata ;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(def
- #^{:arglists '([obj])
- :doc "Returns the metadata of obj, returns nil if there is no metadata."}
- meta (fn meta [x]
- (if (instance? clojure.lang.IObj x)
- (. #^clojure.lang.IObj x (meta)))))
-
-(def
- #^{:arglists '([#^clojure.lang.IObj obj m])
- :doc "Returns an object of the same type and value as obj, with
- map m as its metadata."}
- with-meta (fn with-meta [#^clojure.lang.IObj x m]
- (. x (withMeta m))))
-
-(def
- #^{:arglists '([coll])
- :doc "Return the last item in coll, in linear time"}
- last (fn last [s]
- (if (rest s)
- (recur (rest s))
- (first s))))
-
-(def
- #^{:arglists '([coll])
- :doc "Return a sequence of all but the last item in coll, in linear time"}
- butlast (fn butlast [s]
- (loop [ret [] s s]
- (if (rest s)
- (recur (conj ret (first s)) (rest s))
- (seq ret)))))
-
-(def
-
- #^{:doc "Same as (def name (fn [params* ] exprs*)) or (def
- name (fn ([params* ] exprs*)+)) with any doc-string or attrs added
- to the var metadata"
- :arglists '([name doc-string? attr-map? [params*] body]
- [name doc-string? attr-map? ([params*] body)+ attr-map?])}
- defn (fn defn [name & fdecl]
- (let [m (if (string? (first fdecl))
- {:doc (first fdecl)}
- {})
- fdecl (if (string? (first fdecl))
- (rest fdecl)
- fdecl)
- m (if (map? (first fdecl))
- (conj m (first fdecl))
- m)
- fdecl (if (map? (first fdecl))
- (rest fdecl)
- fdecl)
- fdecl (if (vector? (first fdecl))
- (list fdecl)
- fdecl)
- m (if (map? (last fdecl))
- (conj m (last fdecl))
- m)
- fdecl (if (map? (last fdecl))
- (butlast fdecl)
- fdecl)
- m (conj {:arglists (list 'quote (sigs fdecl))} m)]
- (list 'def (with-meta name (conj (if (meta name) (meta name) {}) m))
- (cons `fn fdecl)))))
-
-(. (var defn) (setMacro))
-
-(defn cast
- "Throws a ClassCastException if x is not a c, else returns x."
- [#^Class c x]
- (. c (cast x)))
-
-(defn to-array
- "Returns an array of Objects containing the contents of coll, which
- can be any Collection. Maps to java.util.Collection.toArray()."
- [coll] (. clojure.lang.RT (toArray coll)))
-
-(defn vector
- "Creates a new vector containing the args."
- ([] [])
- ([& args]
- (. clojure.lang.LazilyPersistentVector (create args))))
-
-(defn vec
- "Creates a new vector containing the contents of coll."
- ([coll]
- (. clojure.lang.LazilyPersistentVector (createOwning (to-array coll)))))
-
-(defn hash-map
- "keyval => key val
- Returns a new hash map with supplied mappings."
- ([] {})
- ([& keyvals]
- (. clojure.lang.PersistentHashMap (create keyvals))))
-
-(defn hash-set
- "Returns a new hash set with supplied keys."
- ([] #{})
- ([& keys]
- (. clojure.lang.PersistentHashSet (create keys))))
-
-(defn sorted-map
- "keyval => key val
- Returns a new sorted map with supplied mappings."
- ([& keyvals]
- (. clojure.lang.PersistentTreeMap (create keyvals))))
-
-(defn sorted-set
- "Returns a new sorted set with supplied keys."
- ([& keys]
- (. clojure.lang.PersistentTreeSet (create keys))))
-
-(defn sorted-map-by
- "keyval => key val
- Returns a new sorted map with supplied mappings, using the supplied comparator."
- ([comparator & keyvals]
- (. clojure.lang.PersistentTreeMap (create comparator keyvals))))
-
-;;;;;;;;;;;;;;;;;;;;
-(def
-
- #^{:doc "Like defn, but the resulting function name is declared as a
- macro and will be used as a macro by the compiler when it is
- called."
- :arglists '([name doc-string? attr-map? [params*] body]
- [name doc-string? attr-map? ([params*] body)+ attr-map?])}
- defmacro (fn [name & args]
- (list 'do
- (cons `defn (cons name args))
- (list '. (list 'var name) '(setMacro)))))
-
-(. (var defmacro) (setMacro))
-
-(defmacro when
- "Evaluates test. If logical true, evaluates body in an implicit do."
- [test & body]
- (list 'if test (cons 'do body)))
-
-(defmacro when-not
- "Evaluates test. If logical false, evaluates body in an implicit do."
- [test & body]
- (list 'if test nil (cons 'do body)))
-
-(defn nil?
- "Returns true if x is nil, false otherwise."
- {:tag Boolean}
- [x] (identical? x nil))
-
-(defn false?
- "Returns true if x is the value false, false otherwise."
- {:tag Boolean}
- [x] (identical? x false))
-
-(defn true?
- "Returns true if x is the value true, false otherwise."
- {:tag Boolean}
- [x] (identical? x true))
-
-(defn not
- "Returns true if x is logical false, false otherwise."
- {:tag Boolean}
- [x] (if x false true))
-
-(defn str
- "With no args, returns the empty string. With one arg x, returns
- x.toString(). (str nil) returns the empty string. With more than
- one arg, returns the concatenation of the str values of the args."
- {:tag String}
- ([] "")
- ([#^Object x]
- (if (nil? x) "" (. x (toString))))
- ([x & ys]
- (loop [sb (new StringBuilder #^String (str x)) more ys]
- (if more
- (recur (. sb (append (str (first more)))) (rest more))
- (str sb)))))
-
-(defn symbol
- "Returns a Symbol with the given namespace and name."
- ([name] (. clojure.lang.Symbol (intern name)))
- ([ns name] (. clojure.lang.Symbol (intern ns name))))
-
-(defn keyword
- "Returns a Keyword with the given namespace and name. Do not use :
- in the keyword strings, it will be added automatically."
- ([name] (. clojure.lang.Keyword (intern nil name)))
- ([ns name] (. clojure.lang.Keyword (intern ns name))))
-
-(defn gensym
- "Returns a new symbol with a unique name. If a prefix string is
- supplied, the name is prefix# where # is some unique number. If
- prefix is not supplied, the prefix is 'G'."
- ([] (gensym "G__"))
- ([prefix-string] (. clojure.lang.Symbol (intern (str prefix-string (str (. clojure.lang.RT (nextID))))))))
-
-(defmacro cond
- "Takes a set of test/expr pairs. It evaluates each test one at a
- time. If a test returns logical true, cond evaluates and returns
- the value of the corresponding expr and doesn't evaluate any of the
- other tests or exprs. (cond) returns nil."
- [& clauses]
- (when clauses
- (list 'if (first clauses)
- (second clauses)
- (cons 'cond (rest (rest clauses))))))
-
-(defn spread
- {:private true}
- [arglist]
- (cond
- (nil? arglist) nil
- (nil? (rest arglist)) (seq (first arglist))
- :else (cons (first arglist) (spread (rest arglist)))))
-
-(defn apply
- "Applies fn f to the argument list formed by prepending args to argseq."
- {:arglists '([f args* argseq])}
- [#^clojure.lang.IFn f & args]
- (. f (applyTo (spread args))))
-
-(defn list*
- "Creates a new list containing the item prepended to more."
- [item & more]
- (spread (cons item more)))
-
-(defmacro delay
- "Takes a body of expressions and yields a function than will invoke
- the body only the first time it is called, and will cache the result
- and return it on all calls"
- [& body]
- (list 'new 'clojure.lang.Delay (list* `fn [] body)))
-
-(defn fnseq
- "Returns a seq object whose first is first and whose rest is the
- value produced by calling restfn with no arguments. restfn will be
- called at most once per step in the sequence, e.g. calling rest
- repeatedly on the head of the seq calls restfn once - the value it
- yields is cached."
- [first restfn]
- (new clojure.lang.FnSeq first restfn))
-
-(defmacro lazy-cons
- "Expands to code which produces a seq object whose first is
- first-expr and whose rest is rest-expr, neither of which is
- evaluated until first/rest is called. Each expr will be evaluated at most
- once per step in the sequence, e.g. calling first/rest repeatedly on the
- same node of the seq evaluates first/rest-expr once - the values they yield are
- cached."
- [first-expr & rest-expr]
- (list 'new 'clojure.lang.LazySeq (list `fn [] first-expr) (list* `fn [] rest-expr)))
-
-(defn concat
- "Returns a lazy seq representing the concatenation of the elements in x + xs."
- ([] nil)
- ([x & xs]
- (cond
- (nil? xs) (seq x)
- (nil? (seq x)) (recur (first xs) (rest xs))
- :else (lazy-cons (first x) (apply concat (rest x) xs)))))
-
-;;;;;;;;;;;;;;;;at this point all the support for syntax-quote exists;;;;;;;;;;;;;;;;;;;;;;
-(defn =
- "Equality. Returns true if obj1 equals obj2, false if not. Same as
- Java obj1.equals(obj2) except it also works for nil, and compares
- numbers in a type-independent manner. Clojure's immutable data
- structures define equals() (and thus =) as a value, not an identity,
- comparison."
- {:tag Boolean
- :inline (fn [x y] `(. clojure.lang.Util equal ~x ~y))}
- [x y] (. clojure.lang.Util (equal x y)))
-
-(defn not=
- "Same as (not (= obj1 obj2))"
- {:tag Boolean}
- [x y] (not (= x y)))
-
-(defn compare
- "Comparator. Returns 0 if x equals y, -1 if x is logically 'less
- than' y, else 1. Same as Java x.compareTo(y) except it also works
- for nil, and compares numbers in a type-independent manner. x must
- implement Comparable"
- {:tag Integer
- :inline (fn [x y] `(. clojure.lang.Util compare ~x ~y))}
- [x y] (. clojure.lang.Util (compare x y)))
-
-(defmacro and
- "Evaluates exprs one at a time, from left to right. If a form
- returns logical false (nil or false), and returns that value and
- doesn't evaluate any of the other expressions, otherwise it returns
- the value of the last expr. (and) returns true."
- ([] true)
- ([x] x)
- ([x & rest]
- `(let [and# ~x]
- (if and# (and ~@rest) and#))))
-
-(defmacro or
- "Evaluates exprs one at a time, from left to right. If a form
- returns a logical true value, or returns that value and doesn't
- evaluate any of the other expressions, otherwise it returns the
- value of the last expression. (or) returns nil."
- ([] nil)
- ([x] x)
- ([x & rest]
- `(let [or# ~x]
- (if or# or# (or ~@rest)))))
-
-;;;;;;;;;;;;;;;;;;; sequence fns ;;;;;;;;;;;;;;;;;;;;;;;
-(defn reduce
- "f should be a function of 2 arguments. If val is not supplied,
- returns the result of applying f to the first 2 items in coll, then
- applying f to that result and the 3rd item, etc. If coll contains no
- items, f must accept no arguments as well, and reduce returns the
- result of calling f with no arguments. If coll has only 1 item, it
- is returned and f is not called. If val is supplied, returns the
- result of applying f to val and the first item in coll, then
- applying f to that result and the 2nd item, etc. If coll contains no
- items, returns val and f is not called."
- ([f coll]
- (let [s (seq coll)]
- (if s
- (if (instance? clojure.lang.IReduce s)
- (. #^clojure.lang.IReduce s (reduce f))
- (reduce f (first s) (rest s)))
- (f))))
- ([f val coll]
- (let [s (seq coll)]
- (if (instance? clojure.lang.IReduce s)
- (. #^clojure.lang.IReduce s (reduce f val))
- ((fn [f val s]
- (if s
- (recur f (f val (first s)) (rest s))
- val)) f val s)))))
-
-(defn reverse
- "Returns a seq of the items in coll in reverse order. Not lazy."
- [coll]
- (reduce conj nil coll))
-
-;;math stuff
-(defn +
- "Returns the sum of nums. (+) returns 0."
- {:inline (fn [x y] `(. clojure.lang.Numbers (add ~x ~y)))
- :inline-arities #{2}}
- ([] 0)
- ([x] (cast Number x))
- ([x y] (. clojure.lang.Numbers (add x y)))
- ([x y & more]
- (reduce + (+ x y) more)))
-
-(defn *
- "Returns the product of nums. (*) returns 1."
- {:inline (fn [x y] `(. clojure.lang.Numbers (multiply ~x ~y)))
- :inline-arities #{2}}
- ([] 1)
- ([x] (cast Number x))
- ([x y] (. clojure.lang.Numbers (multiply x y)))
- ([x y & more]
- (reduce * (* x y) more)))
-
-(defn /
- "If no denominators are supplied, returns 1/numerator,
- else returns numerator divided by all of the denominators."
- {:inline (fn [x y] `(. clojure.lang.Numbers (divide ~x ~y)))
- :inline-arities #{2}}
- ([x] (/ 1 x))
- ([x y] (. clojure.lang.Numbers (divide x y)))
- ([x y & more]
- (reduce / (/ x y) more)))
-
-(defn -
- "If no ys are supplied, returns the negation of x, else subtracts
- the ys from x and returns the result."
- {:inline (fn [& args] `(. clojure.lang.Numbers (minus ~@args)))
- :inline-arities #{1 2}}
- ([x] (. clojure.lang.Numbers (minus x)))
- ([x y] (. clojure.lang.Numbers (minus x y)))
- ([x y & more]
- (reduce - (- x y) more)))
-
-(defn <
- "Returns non-nil if nums are in monotonically increasing order,
- otherwise false."
- {:inline (fn [x y] `(. clojure.lang.Numbers (lt ~x ~y)))
- :inline-arities #{2}}
- ([x] true)
- ([x y] (. clojure.lang.Numbers (lt x y)))
- ([x y & more]
- (if (< x y)
- (if (rest more)
- (recur y (first more) (rest more))
- (< y (first more)))
- false)))
-
-(defn <=
- "Returns non-nil if nums are in monotonically non-decreasing order,
- otherwise false."
- {:inline (fn [x y] `(. clojure.lang.Numbers (lte ~x ~y)))
- :inline-arities #{2}}
- ([x] true)
- ([x y] (. clojure.lang.Numbers (lte x y)))
- ([x y & more]
- (if (<= x y)
- (if (rest more)
- (recur y (first more) (rest more))
- (<= y (first more)))
- false)))
-
-(defn >
- "Returns non-nil if nums are in monotonically decreasing order,
- otherwise false."
- {:inline (fn [x y] `(. clojure.lang.Numbers (gt ~x ~y)))
- :inline-arities #{2}}
- ([x] true)
- ([x y] (. clojure.lang.Numbers (gt x y)))
- ([x y & more]
- (if (> x y)
- (if (rest more)
- (recur y (first more) (rest more))
- (> y (first more)))
- false)))
-
-(defn >=
- "Returns non-nil if nums are in monotonically non-increasing order,
- otherwise false."
- {:inline (fn [x y] `(. clojure.lang.Numbers (gte ~x ~y)))
- :inline-arities #{2}}
- ([x] true)
- ([x y] (. clojure.lang.Numbers (gte x y)))
- ([x y & more]
- (if (>= x y)
- (if (rest more)
- (recur y (first more) (rest more))
- (>= y (first more)))
- false)))
-
-(defn ==
- "Returns non-nil if nums all have the same value, otherwise false"
- {:inline (fn [x y] `(. clojure.lang.Numbers (equiv ~x ~y)))
- :inline-arities #{2}}
- ([x] true)
- ([x y] (. clojure.lang.Numbers (equiv x y)))
- ([x y & more]
- (if (== x y)
- (if (rest more)
- (recur y (first more) (rest more))
- (== y (first more)))
- false)))
-
-(defn max
- "Returns the greatest of the nums."
- ([x] x)
- ([x y] (if (> x y) x y))
- ([x y & more]
- (reduce max (max x y) more)))
-
-(defn min
- "Returns the least of the nums."
- ([x] x)
- ([x y] (if (< x y) x y))
- ([x y & more]
- (reduce min (min x y) more)))
-
-(defn inc
- "Returns a number one greater than num."
- {:inline (fn [x] `(. clojure.lang.Numbers (inc ~x)))}
- [x] (. clojure.lang.Numbers (inc x)))
-
-(defn dec
- "Returns a number one less than num."
- {:inline (fn [x] `(. clojure.lang.Numbers (dec ~x)))}
- [x] (. clojure.lang.Numbers (dec x)))
-
-(defn unchecked-inc
- "Returns a number one greater than x, an int or long.
- Note - uses a primitive operator subject to overflow."
- {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_inc ~x)))}
- [x] (. clojure.lang.Numbers (unchecked_inc x)))
-
-(defn unchecked-dec
- "Returns a number one less than x, an int or long.
- Note - uses a primitive operator subject to overflow."
- {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_dec ~x)))}
- [x] (. clojure.lang.Numbers (unchecked_dec x)))
-
-(defn unchecked-negate
- "Returns the negation of x, an int or long.
- Note - uses a primitive operator subject to overflow."
- {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_negate ~x)))}
- [x] (. clojure.lang.Numbers (unchecked_negate x)))
-
-(defn unchecked-add
- "Returns the sum of x and y, both int or long.
- Note - uses a primitive operator subject to overflow."
- {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_add ~x ~y)))}
- [x y] (. clojure.lang.Numbers (unchecked_add x y)))
-
-(defn unchecked-subtract
- "Returns the difference of x and y, both int or long.
- Note - uses a primitive operator subject to overflow."
- {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_subtract ~x ~y)))}
- [x y] (. clojure.lang.Numbers (unchecked_subtract x y)))
-
-(defn unchecked-multiply
- "Returns the product of x and y, both int or long.
- Note - uses a primitive operator subject to overflow."
- {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_multiply ~x ~y)))}
- [x y] (. clojure.lang.Numbers (unchecked_multiply x y)))
-
-(defn unchecked-divide
- "Returns the division of x by y, both int or long.
- Note - uses a primitive operator subject to truncation."
- {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_divide ~x ~y)))}
- [x y] (. clojure.lang.Numbers (unchecked_divide x y)))
-
-(defn pos?
- "Returns true if num is greater than zero, else false"
- {:tag Boolean
- :inline (fn [x] `(. clojure.lang.Numbers (isPos ~x)))}
- [x] (. clojure.lang.Numbers (isPos x)))
-
-(defn neg?
- "Returns true if num is less than zero, else false"
- {:tag Boolean
- :inline (fn [x] `(. clojure.lang.Numbers (isNeg ~x)))}
- [x] (. clojure.lang.Numbers (isNeg x)))
-
-(defn zero?
- "Returns true if num is zero, else false"
- {:tag Boolean
- :inline (fn [x] `(. clojure.lang.Numbers (isZero ~x)))}
- [x] (. clojure.lang.Numbers (isZero x)))
-
-(defn quot
- "quot[ient] of dividing numerator by denominator."
- [num div]
- (. clojure.lang.Numbers (quotient num div)))
-
-(defn rem
- "rem[ainder] of dividing numerator by denominator."
- [num div]
- (. clojure.lang.Numbers (remainder num div)))
-
-(defn rationalize
- "returns the rational value of num"
- [num]
- (. clojure.lang.Numbers (rationalize num)))
-
-;;Bit ops
-
-(defn bit-not
- "Bitwise complement"
- [x] (. clojure.lang.Numbers not x))
-
-
-(defn bit-and
- "Bitwise and"
- [x y] (. clojure.lang.Numbers and x y))
-
-(defn bit-or
- "Bitwise or"
- [x y] (. clojure.lang.Numbers or x y))
-
-(defn bit-xor
- "Bitwise exclusive or"
- [x y] (. clojure.lang.Numbers xor x y))
-
-(defn bit-and-not
- "Bitwise and with complement"
- [x y] (. clojure.lang.Numbers andNot x y))
-
-
-(defn bit-clear
- "Clear bit at index n"
- [x n] (. clojure.lang.Numbers clearBit x n))
-
-(defn bit-set
- "Set bit at index n"
- [x n] (. clojure.lang.Numbers setBit x n))
-
-(defn bit-flip
- "Flip bit at index n"
- [x n] (. clojure.lang.Numbers flipBit x n))
-
-(defn bit-test
- "Test bit at index n"
- [x n] (. clojure.lang.Numbers testBit x n))
-
-
-(defn bit-shift-left
- "Bitwise shift left"
- [x n] (. clojure.lang.Numbers shiftLeft x n))
-
-(defn bit-shift-right
- "Bitwise shift right"
- [x n] (. clojure.lang.Numbers shiftRight x n))
-
-;;
-
-(defn complement
- "Takes a fn f and returns a fn that takes the same arguments as f,
- has the same effects, if any, and returns the opposite truth value."
- [f] (fn [& args]
- (not (apply f args))))
-
-(defn constantly
- "Returns a function that takes any number of arguments and returns x."
- [x] (fn [& args] x))
-
-(defn identity
- "Returns its argument."
- [x] x)
-
-;;Collection stuff
-
-
-
-(defn count
- "Returns the number of items in the collection. (count nil) returns
- 0. Also works on strings, arrays, and Java Collections and Maps"
- [coll] (. clojure.lang.RT (count coll)))
-
-;;list stuff
-(defn peek
- "For a list or queue, same as first, for a vector, same as, but much
- more efficient than, last. If the collection is empty, returns nil."
- [coll] (. clojure.lang.RT (peek coll)))
-
-(defn pop
- "For a list or queue, returns a new list/queue without the first
- item, for a vector, returns a new vector without the last item. If
- the collection is empty, throws an exception. Note - not the same
- as rest/butlast."
- [coll] (. clojure.lang.RT (pop coll)))
-
-(defn nth
- "Returns the value at the index. get returns nil if index out of
- bounds, nth throws an exception unless not-found is supplied. nth
- also works for strings, Java arrays, regex Matchers and Lists, and,
- in O(n) time, for sequences."
- ([coll index] (. clojure.lang.RT (nth coll index)))
- ([coll index not-found] (. clojure.lang.RT (nth coll index not-found))))
-
-;;map stuff
-
-(defn contains?
- "Returns true if key is present, else false."
- [map key] (. clojure.lang.RT (contains map key)))
-
-(defn get
- "Returns the value mapped to key, not-found or nil if key not present."
- ([map key]
- (. clojure.lang.RT (get map key)))
- ([map key not-found]
- (. clojure.lang.RT (get map key not-found))))
-
-(defn dissoc
- "dissoc[iate]. Returns a new map of the same (hashed/sorted) type,
- that does not contain a mapping for key(s)."
- ([map] map)
- ([map key]
- (. clojure.lang.RT (dissoc map key)))
- ([map key & ks]
- (let [ret (dissoc map key)]
- (if ks
- (recur ret (first ks) (rest ks))
- ret))))
-
-(defn disj
- "disj[oin]. Returns a new set of the same (hashed/sorted) type, that
- does not contain key(s)."
- ([set] set)
- ([#^clojure.lang.IPersistentSet set key]
- (. set (disjoin key)))
- ([set key & ks]
- (let [ret (disj set key)]
- (if ks
- (recur ret (first ks) (rest ks))
- ret))))
-
-(defn find
- "Returns the map entry for key, or nil if key not present."
- [map key] (. clojure.lang.RT (find map key)))
-
-(defn select-keys
- "Returns a map containing only those entries in map whose key is in keys"
- [map keyseq]
- (loop [ret {} keys (seq keyseq)]
- (if keys
- (let [entry (. clojure.lang.RT (find map (first keys)))]
- (recur
- (if entry
- (conj ret entry)
- ret)
- (rest keys)))
- ret)))
-
-(defn keys
- "Returns a sequence of the map's keys."
- [map] (. clojure.lang.RT (keys map)))
-
-(defn vals
- "Returns a sequence of the map's values."
- [map] (. clojure.lang.RT (vals map)))
-
-(defn key
- "Returns the key of the map entry."
- [#^java.util.Map$Entry e]
- (. e (getKey)))
-
-(defn val
- "Returns the value in the map entry."
- [#^java.util.Map$Entry e]
- (. e (getValue)))
-
-(defn rseq
- "Returns, in constant time, a sequence of the items in rev (which
- can be a vector or sorted-map), in reverse order."
- [#^clojure.lang.Reversible rev]
- (. rev (rseq)))
-
-(defn name
- "Returns the name String of a symbol or keyword."
- [#^clojure.lang.Named x]
- (. x (getName)))
-
-(defn namespace
- "Returns the namespace String of a symbol or keyword, or nil if not present."
- [#^clojure.lang.Named x]
- (. x (getNamespace)))
-
-(defmacro locking
- "Executes exprs in an implicit do, while holding the monitor of x.
- Will release the monitor of x in all circumstances."
- [x & body]
- `(let [lockee# ~x]
- (try
- (monitor-enter lockee#)
- ~@body
- (finally
- (monitor-exit lockee#)))))
-
-(defmacro ..
- "form => fieldName-symbol or (instanceMethodName-symbol args*)
-
- Expands into a member access (.) of the first member on the first
- argument, followed by the next member on the result, etc. For
- instance:
-
- (.. System (getProperties) (get \"os.name\"))
-
- expands to:
-
- (. (. System (getProperties)) (get \"os.name\"))
-
- but is easier to write, read, and understand."
- ([x form] `(. ~x ~form))
- ([x form & more] `(.. (. ~x ~form) ~@more)))
-
-(defmacro ->
- "Macro. Threads the expr through the forms. Inserts x as the
- second item in the first form, making a list of it if it is not a
- list already. If there are more forms, inserts the first form as the
- second item in second form, etc."
- ([x form] (if (seq? form)
- `(~(first form) ~x ~@(rest form))
- (list form x)))
- ([x form & more] `(-> (-> ~x ~form) ~@more)))
-
-;;multimethods
-(defmacro defmulti
- "Creates a new multimethod with the associated dispatch function. If
- default-dispatch-val is supplied it becomes the default dispatch
- value of the multimethod, otherwise the default dispatch value
- is :default."
- ([name dispatch-fn] `(defmulti ~name ~dispatch-fn :default))
- ([name dispatch-fn default-val]
- `(def ~name (new clojure.lang.MultiFn ~dispatch-fn ~default-val))))
-
-(defmacro defmethod
- "Creates and installs a new method of multimethod associated with dispatch-value. "
- [multifn dispatch-val & fn-tail]
- `(let [pvar# (var ~multifn)]
- (. pvar# (commuteRoot (fn [#^clojure.lang.MultiFn mf#]
- (. mf# (assoc ~dispatch-val (fn ~@fn-tail))))))))
-
-(defmacro remove-method
- "Removes the method of multimethod associated with dispatch-value."
- [multifn dispatch-val]
- `(let [pvar# (var ~multifn)]
- (. pvar# (commuteRoot (fn [#^clojure.lang.MultiFn mf#]
- (. mf# (dissoc ~dispatch-val)))))))
-
-;;;;;;;;; var stuff
-
-(defmacro binding
- "binding => var-symbol init-expr
-
- Creates new bindings for the (already-existing) vars, with the
- supplied initial values, executes the exprs in an implicit do, then
- re-establishes the bindings that existed before."
- [bindings & body]
- (let [var-ize (fn [var-vals]
- (loop [ret [] vvs (seq var-vals)]
- (if vvs
- (recur (conj (conj ret `(var ~(first vvs))) (second vvs))
- (rest (rest vvs)))
- (seq ret))))]
- `(do
- (. clojure.lang.Var (pushThreadBindings (hash-map ~@(var-ize bindings))))
- (try
- ~@body
- (finally
- (. clojure.lang.Var (popThreadBindings)))))))
-
-(defn find-var
- "Returns the global var named by the namespace-qualified symbol, or
- nil if no var with that name."
- [sym] (. clojure.lang.Var (find sym)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Refs ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defn agent
- "Creates and returns an agent with an initial value of state."
- [state] (new clojure.lang.Agent state))
-
-(defn ! [& args] (throw (new Exception "! is now send. See also send-off")))
-
-(defn send
- "Dispatch an action to an agent. Returns the agent immediately.
- Subsequently, in a thread from a thread pool, the state of the agent
- will be set to the value of:
-
- (apply action-fn state-of-agent args)"
- [#^clojure.lang.Agent a f & args]
- (. a (dispatch f args false)))
-
-(defn send-off
- "Dispatch a potentially blocking action to an agent. Returns the
- agent immediately. Subsequently, in a separate thread, the state of
- the agent will be set to the value of:
-
- (apply action-fn state-of-agent args)"
- [#^clojure.lang.Agent a f & args]
- (. a (dispatch f args true)))
-
-(defn agent-errors
- "Returns a sequence of the exceptions thrown during asynchronous
- actions of the agent."
- [#^clojure.lang.Agent a] (. a (getErrors)))
-
-(defn clear-agent-errors
- "Clears any exceptions thrown during asynchronous actions of the
- agent, allowing subsequent actions to occur."
- [#^clojure.lang.Agent a] (. a (clearErrors)))
-
-(defn ref
- "Creates and returns a Ref with an initial value of x."
- [x] (new clojure.lang.Ref x))
-
-(defn deref
- "Also reader macro: @ref/@agent Within a transaction, returns the
- in-transaction-value of ref, else returns the
- most-recently-committed value of ref. When applied to an agent,
- returns its current state."
- [#^clojure.lang.IRef ref] (. ref (get)))
-
-
-(defn commute
- "Must be called in a transaction. Sets the in-transaction-value of
- ref to:
-
- (apply fun in-transaction-value-of-ref args)
-
- and returns the in-transaction-value of ref.
-
- At the commit point of the transaction, sets the value of ref to be:
-
- (apply fun most-recently-committed-value-of-ref args)
-
- Thus fun should be commutative, or, failing that, you must accept
- last-one-in-wins behavior. commute allows for more concurrency than
- ref-set."
-
- [#^clojure.lang.Ref ref fun & args]
- (. ref (commute fun args)))
-
-(defn alter
- "Must be called in a transaction. Sets the in-transaction-value of
- ref to:
-
- (apply fun in-transaction-value-of-ref args)
-
- and returns the in-transaction-value of ref."
- [#^clojure.lang.Ref ref fun & args]
- (. ref (alter fun args)))
-
-(defn ref-set
- "Must be called in a transaction. Sets the value of ref.
- Returns val."
- [#^clojure.lang.Ref ref val]
- (. ref (set val)))
-
-(defn ensure
- "Must be called in a transaction. Protects the ref from modification
- by other transactions. Returns the in-transaction-value of
- ref. Allows for more concurrency than (ref-set ref @ref)"
- [#^clojure.lang.Ref ref]
- (. ref (touch))
- (. ref (get)))
-
-(defmacro sync
- "transaction-flags => TBD, pass nil for now
-
- Runs the exprs (in an implicit do) in a transaction that encompasses
- exprs and any nested calls. Starts a transaction if none is already
- running on this thread. Any uncaught exception will abort the
- transaction and flow out of sync. The exprs may be run more than
- once, but any effects on Refs will be atomic."
- [flags-ignored-for-now & body]
- `(. clojure.lang.LockingTransaction
- (runInTransaction (fn [] ~@body))))
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; fn stuff ;;;;;;;;;;;;;;;;
-
-
-(defn comp
- "Takes a set of functions and returns a fn that is the composition
- of those fns. The returned fn takes a variable number of args,
- applies the rightmost of fns to the args, the next
- fn (right-to-left) to the result, etc."
- [& fs]
- (let [fs (reverse fs)]
- (fn [& args]
- (loop [ret (apply (first fs) args) fs (rest fs)]
- (if fs
- (recur ((first fs) ret) (rest fs))
- ret)))))
-
-(defn partial
- "Takes a function f and fewer than the normal arguments to f, and
- returns a fn that takes a variable number of additional args. When
- called, the returned function calls f with args + additional args."
- ([f arg1]
- (fn [& args] (apply f arg1 args)))
- ([f arg1 arg2]
- (fn [& args] (apply f arg1 arg2 args)))
- ([f arg1 arg2 arg3]
- (fn [& args] (apply f arg1 arg2 arg3 args)))
- ([f arg1 arg2 arg3 & more]
- (fn [& args] (apply f arg1 arg2 arg3 (concat more args)))))
-
-;;;;;;;;;;;;;;;;;;; sequence fns ;;;;;;;;;;;;;;;;;;;;;;;
-
-(defn every?
- "Returns true if (pred x) is logical true for every x in coll, else
- false."
- {:tag Boolean}
- [pred coll]
- (if (seq coll)
- (and (pred (first coll))
- (recur pred (rest coll)))
- true))
-
-(def
- #^{:tag Boolean
- :doc "Returns false if (pred x) is logical true for every x in
- coll, else true."
- :arglists '([pred coll])}
-not-every? (comp not every?))
-
-(defn some
- "Returns the first logical true value of (pred x) for any x in coll,
- else nil."
- [pred coll]
- (when (seq coll)
- (or (pred (first coll)) (recur pred (rest coll)))))
-
-(def
- #^{:tag Boolean
- :doc "Returns false if (pred x) is logical true for any x in coll,
- else true."
- :arglists '([pred coll])}
- not-any? (comp not some))
-
-(defn map
- "Returns a lazy seq consisting of the result of applying f to the
- set of first items of each coll, followed by applying f to the set
- of second items in each coll, until any one of the colls is
- exhausted. Any remaining items in other colls are ignored. Function
- f should accept number-of-colls arguments."
- ([f coll]
- (when (seq coll)
- (lazy-cons (f (first coll)) (map f (rest coll)))))
- ([f coll & colls]
- (when (and (seq coll) (every? seq colls))
- (lazy-cons (apply f (first coll) (map first colls))
- (apply map f (rest coll) (map rest colls))))))
-
-(defn mapcat
- "Returns the result of applying concat to the result of applying map
- to f and colls. Thus function f should return a collection."
- [f & colls]
- (apply concat (apply map f colls)))
-
-(defn filter
- "Returns a lazy seq of the items in coll for which
- (pred item) returns true."
- [pred coll]
- (when (seq coll)
- (if (pred (first coll))
- (lazy-cons (first coll) (filter pred (rest coll)))
- (recur pred (rest coll)))))
-
-(defn take
- "Returns a lazy seq of the first n items in coll, or all items if
- there are fewer than n."
- [n coll]
- (when (and (pos? n) (seq coll))
- (lazy-cons (first coll) (take (dec n) (rest coll)))))
-
-(defn take-while
- "Returns a lazy seq of successive items from coll while
- (pred item) returns true."
- [pred coll]
- (when (and (seq coll) (pred (first coll)))
- (lazy-cons (first coll) (take-while pred (rest coll)))))
-
-(defn drop
- "Returns a lazy seq of all but the first n items in coll."
- [n coll]
- (if (and (pos? n) (seq coll))
- (recur (dec n) (rest coll))
- (seq coll)))
-
-(defn drop-last
- "Return a lazy seq of all but the last n (default 1) items in coll"
- ([s] (drop-last 1 s))
- ([n s] (map (fn [x _] x) (seq s) (drop n s))))
-
-(defn drop-while
- "Returns a lazy seq of the items in coll starting from the first
- item for which (pred item) returns nil."
- [pred coll]
- (if (and (seq coll) (pred (first coll)))
- (recur pred (rest coll))
- (seq coll)))
-
-(defn cycle
- "Returns a lazy (infinite!) seq of repetitions of the items in
- coll."
- [coll]
- (when (seq coll)
- (let [rep (fn thisfn [xs]
- (if xs
- (lazy-cons (first xs) (thisfn (rest xs)))
- (recur (seq coll))))]
- (rep (seq coll)))))
-
-(defn split-at
- "Returns a vector of [(take n coll) (drop n coll)]"
- [n coll]
- [(take n coll) (drop n coll)])
-
-(defn split-with
- "Returns a vector of [(take-while pred coll) (drop-while pred coll)]"
- [pred coll]
- [(take-while pred coll) (drop-while pred coll)])
-
-(defn repeat
- "Returns a lazy (infinite!) seq of xs."
- [x] (lazy-cons x (repeat x)))
-
-(defn replicate
- "Returns a lazy seq of n xs."
- [n x] (take n (repeat x)))
-
-(defn iterate
- "Returns a lazy seq of x, (f x), (f (f x)) etc."
- [f x] (lazy-cons x (iterate f (f x))))
-
-(defn range
- "Returns a lazy seq of nums from start (inclusive) to end
- (exclusive), by step, where start defaults to 0 and step to 1."
- ([end] (if (and (> end 0) (< end (. Integer MAX_VALUE)))
- (new clojure.lang.Range 0 end)
- (take end (iterate inc 0))))
- ([start end] (if (and (< start end) (< end (. Integer MAX_VALUE)))
- (new clojure.lang.Range start end)
- (take (- end start) (iterate inc start))))
- ([start end step]
- (take-while (partial (if (pos? step) > <) end) (iterate (partial + step) start))))
-
-(defn merge
- "Returns a map that consists of the rest of the maps conj-ed onto
- the first. If a key occurs in more than one map, the mapping from
- the latter (left-to-right) will be the mapping in the result."
- [& maps] (reduce conj maps))
-
-(defn merge-with
- "Returns a map that consists of the rest of the maps conj-ed onto
- the first. If a key occurs in more than one map, the mapping(s)
- from the latter (left-to-right) will be combined with the mapping in
- the result by calling (f val-in-result val-in-latter)."
- [f & maps]
- (let [merge-entry (fn [m e]
- (let [k (key e) v (val e)]
- (if (contains? m k)
- (assoc m k (f (m k) v))
- (assoc m k v))))
- merge2 (fn [m1 m2]
- (reduce merge-entry m1 (seq m2)))]
- (reduce merge2 maps)))
-
-
-
-(defn zipmap
- "Returns a map with the keys mapped to the corresponding vals."
- [keys vals]
- (loop [map {}
- ks (seq keys)
- vs (seq vals)]
- (if (and ks vs)
- (recur (assoc map (first ks) (first vs))
- (rest ks)
- (rest vs))
- map)))
-
-(defn line-seq
- "Returns the lines of text from rdr as a lazy sequence of strings.
- rdr must implement java.io.BufferedReader."
- [#^java.io.BufferedReader rdr]
- (let [line (. rdr (readLine))]
- (when line
- (lazy-cons line (line-seq rdr)))))
-
-(defn comparator
- "Returns an implementation of java.util.Comparator based upon pred."
- [pred]
- (fn [x y]
- (cond (pred x y) -1 (pred y x) 1 :else 0)))
-
-(defn sort
- "Returns a sorted sequence of the items in coll. If no comparator is
- supplied, uses compare. comparator must
- implement java.util.Comparator."
- ([#^java.util.Collection coll]
- (sort compare coll))
- ([#^java.util.Comparator comp #^java.util.Collection coll]
- (when (and coll (not (. coll (isEmpty))))
- (let [a (. coll (toArray))]
- (. java.util.Arrays (sort a comp))
- (seq a)))))
-
-(defn sort-by
- "Returns a sorted sequence of the items in coll, where the sort
- order is determined by comparing (keyfn item). If no comparator is
- supplied, uses compare. comparator must
- implement java.util.Comparator."
- ([keyfn coll]
- (sort-by keyfn compare coll))
- ([keyfn #^java.util.Comparator comp coll]
- (sort (fn [x y] (. comp (compare (keyfn x) (keyfn y)))) coll)))
-
-;; evaluation
-
-(defn eval
- "Evaluates the form data structure (not text!) and returns the result."
- [form] (. clojure.lang.Compiler (eval form)))
-
-;(defn defimports [& imports-maps]
-; (def *imports* (apply merge imports-maps)))
-
-(defmacro doseq
- "Repeatedly executes body (presumably for side-effects) with
- binding-form bound to successive items from coll. Does not retain
- the head of the sequence. Returns nil."
- [item list & body]
- `(loop [list# (seq ~list)]
- (when list#
- (let [~item (first list#)]
- ~@body)
- (recur (rest list#)))))
-
-(defn scan [& args] (throw (new Exception "scan is now called dorun")))
-(defn touch [& args] (throw (new Exception "touch is now called doall")))
-
-(defn dorun
- "When lazy sequences are produced via functions that have side
- effects, any effects other than those needed to produce the first
- element in the seq do not occur until the seq is consumed. dorun can
- be used to force any effects. Walks through the successive rests of
- the seq, does not retain the head and returns nil."
- ([coll]
- (when (seq coll)
- (recur (rest coll))))
- ([n coll]
- (when (and (seq coll) (pos? n))
- (recur (dec n) (rest coll)))))
-
-(defn doall
- "When lazy sequences are produced via functions that have side
- effects, any effects other than those needed to produce the first
- element in the seq do not occur until the seq is consumed. doall can
- be used to force any effects. Walks through the successive rests of
- the seq, retains the head and returns it, thus causing the entire
- seq to reside in memory at one time."
- ([coll]
- (dorun coll)
- coll)
- ([n coll]
- (dorun n coll)
- coll))
-
-(defn await
- "Blocks the current thread (indefinitely!) until all actions
- dispatched thus far, from this thread or agent, to the agent(s) have
- occurred."
- [& agents]
- (when *agent*
- (throw (new Exception "Can't await in agent action")))
- (let [latch (new java.util.concurrent.CountDownLatch (count agents))
- count-down (fn [agent] (. latch (countDown)) agent)]
- (doseq agent agents
- (send agent count-down))
- (. latch (await))))
-
-(defn await1 [#^clojure.lang.Agent a]
- (when (pos? (.getQueueCount a))
- (await a))
- a)
-
-(defn await-for
- "Blocks the current thread until all actions dispatched thus
- far (from this thread or agent) to the agents have occurred, or the
- timeout (in milliseconds) has elapsed. Returns nil if returning due
- to timeout, non-nil otherwise."
- [timeout-ms & agents]
- (when *agent*
- (throw (new Exception "Can't await in agent action")))
- (let [latch (new java.util.concurrent.CountDownLatch (count agents))
- count-down (fn [agent] (. latch (countDown)) agent)]
- (doseq agent agents
- (send agent count-down))
- (. latch (await timeout-ms (. java.util.concurrent.TimeUnit MILLISECONDS)))))
-
-(defmacro dotimes
- "Repeatedly executes body (presumably for side-effects) with name
- bound to integers from 0 through n-1."
- [i n & body]
- `(let [n# (int ~n)]
- (loop [~i (int 0)]
- (when (< ~i n#)
- ~@body
- (recur (unchecked-inc ~i))))))
-
-(defn import
- "import-list => (package-symbol class-name-symbols*)
-
- For each name in class-name-symbols, adds a mapping from name to the
- class named by package.name to the current namespace."
- [& import-lists]
- (when import-lists
- (let [#^clojure.lang.Namespace ns *ns*
- pkg (ffirst import-lists)
- classes (rfirst import-lists)]
- (doseq c classes
- (. ns (importClass c (. Class (forName (str pkg "." c)))))) )
- (apply import (rest import-lists))))
-
-(defn into-array
- "Returns an array of the type of the first element in coll,
- containing the contents of coll, which must be of a compatible
- type."
- [aseq]
- (. clojure.lang.RT (seqToTypedArray (seq aseq))))
-
-(defn into
- "Returns a new coll consisting of to-coll with all of the items of
- from-coll conjoined."
- [to from]
- (let [ret to items (seq from)]
- (if items
- (recur (conj ret (first items)) (rest items))
- ret)))
-
-(defn #^{:private true}
- array [& items]
- (into-array items))
-
-(defn pr
- "Prints the object(s) to the output stream that is the current value
- of *out*. Prints the object(s), separated by spaces if there is
- more than one. By default, pr and prn print in a way that objects
- can be read by the reader"
- ([] nil)
- ([x]
- (. clojure.lang.RT (print x *out*))
- nil)
- ([x & more]
- (pr x)
- (. *out* (append \space))
- (apply pr more)))
-
-(defn newline
- "Writes a newline to the output stream that is the current value of
- *out*"
- []
- (. *out* (append \newline))
- nil)
-
-(defn flush
- "Flushes the output stream that is the current value of
- *out*"
- []
- (. *out* (flush))
- nil)
-
-(defn prn
- "Same as pr followed by (newline). Observes *flush-on-newline*"
- [& more]
- (apply pr more)
- (newline)
- (when *flush-on-newline*
- (flush)))
-
-(defn print
- "Prints the object(s) to the output stream that is the current value
- of *out*. print and println produce output for human consumption."
- [& more]
- (binding [*print-readably* nil]
- (apply pr more)))
-
-(defn println
- "Same as print followed by (newline)"
- [& more]
- (binding [*print-readably* nil]
- (apply prn more)))
-
-
-(defn read
- "Reads the next object from stream, which must be an instance of
- java.io.PushbackReader or some derivee. stream defaults to the
- current value of *in* ."
- ([]
- (read *in*))
- ([stream]
- (read stream true nil))
- ([stream eof-error? eof-value]
- (read stream eof-error? eof-value false))
- ([stream eof-error? eof-value recursive?]
- (. clojure.lang.LispReader (read stream eof-error? eof-value recursive?))))
-
-(defn read-line
- "Reads the next line from stream that is the current value of *in* ."
- [] (. *in* (readLine)))
-
-(defmacro with-open
- "Evaluates body in a try expression with name bound to the value of
- init, and a finally clause that calls (. name (close))."
- [name init & body]
- `(let [~name ~init]
- (try
- ~@body
- (finally
- (. ~name (close))))))
-
-(defmacro doto
- "Evaluates x then calls all of the methods with the supplied
- arguments in succession on the resulting object, returning it.
-
- (doto (new java.util.HashMap) (put \"a\" 1) (put \"b\" 2))"
- [x & members]
- (let [gx (gensym)]
- `(let [~gx ~x]
- (do
- ~@(map (fn [m] (list '. gx m))
- members))
- ~gx)))
-
-(defmacro memfn
- "Expands into code that creates a fn that expects to be passed an
- object and any args and calls the named instance method on the
- object passing the args. Use when you want to treat a Java method as
- a first-class fn."
- [name & args]
- `(fn [target# ~@args]
- (. target# (~name ~@args))))
-
-(defmacro time
- "Evaluates expr and prints the time it took. Returns the value of
- expr."
- [expr]
- `(let [start# (. System (nanoTime))
- ret# ~expr]
- (prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs"))
- ret#))
-
-(defn num
- "Coerce to Number"
- {:tag Number
- :inline (fn [x] `(. clojure.lang.Numbers (num ~x)))}
- [x] (. clojure.lang.Numbers (num x)))
-
-(defn int
- "Coerce to int"
- {:tag Integer
- :inline (fn [x] `(. clojure.lang.RT (intCast ~x)))}
- [x] (. clojure.lang.RT (intCast x)))
-
-(defn long
- "Coerce to long"
- {:tag Long
- :inline (fn [x] `(. clojure.lang.RT (longCast ~x)))}
- [#^Number x] (. x (longValue)))
-
-(defn float
- "Coerce to float"
- {:tag Float
- :inline (fn [x] `(. clojure.lang.RT (floatCast ~x)))}
- [#^Number x] (. x (floatValue)))
-
-(defn double
- "Coerce to double"
- {:tag Double
- :inline (fn [x] `(. clojure.lang.RT (doubleCast ~x)))}
- [#^Number x] (. x (doubleValue)))
-
-(defn short
- "Coerce to short"
- {:tag Short}
- [#^Number x] (. x (shortValue)))
-
-(defn byte
- "Coerce to byte"
- {:tag Byte}
- [#^Number x] (. x (byteValue)))
-
-(defn char
- "Coerce to char"
- {:tag Character}
- [x] (. clojure.lang.RT (charCast x)))
-
-(defn boolean
- "Coerce to boolean"
- {:tag Boolean}
- [x] (if x true false))
-
-(defn bigint
- "Coerce to BigInteger"
- {:tag BigInteger}
- [x] (. BigInteger valueOf x))
-
-(defn bigdec
- "Coerce to BigDecimal"
- {:tag BigDecimal}
- [x] (. BigDecimal valueOf x))
-
-(import '(java.lang.reflect Array))
-
-(defn alength
- "Returns the length of the Java array. Works on arrays of all
- types."
- {:inline (fn [a] `(. clojure.lang.RT (alength ~a)))}
- [array] (. clojure.lang.RT (alength array)))
-
-(defn aclone
- "Returns a clone of the Java array. Works on arrays of known
- types."
- {:inline (fn [a] `(. clojure.lang.RT (aclone ~a)))}
- [array] (. clojure.lang.RT (aclone array)))
-
-(defn aget
- "Returns the value at the index/indices. Works on Java arrays of all
- types."
- {:inline (fn [a i] `(. clojure.lang.RT (aget ~a ~i)))
- :inline-arities #{2}}
- ([array idx]
- (. Array (get array idx)))
- ([array idx & idxs]
- (apply aget (aget array idx) idxs)))
-
-(defn aset
- "Sets the value at the index/indices. Works on Java arrays of
- reference types. Returns val."
- {:inline (fn [a i v] `(. clojure.lang.RT (aset ~a ~i ~v)))
- :inline-arities #{3}}
- ([array idx val]
- (. Array (set array idx val))
- val)
- ([array idx idx2 & idxv]
- (apply aset (aget array idx) idx2 idxv)))
-
-(defmacro
- #^{:private true}
- def-aset [name method coerce]
- `(defn ~name
- {:arglists '([~'array ~'idx ~'val] [~'array ~'idx ~'idx2 & ~'idxv])}
- ([array# idx# val#]
- (. Array (~method array# idx# (~coerce val#)))
- val#)
- ([array# idx# idx2# & idxv#]
- (apply ~name (aget array# idx#) idx2# idxv#))))
-
-(def-aset
- #^{:doc "Sets the value at the index/indices. Works on arrays of int. Returns val."}
- aset-int setInt int)
-
-(def-aset
- #^{:doc "Sets the value at the index/indices. Works on arrays of long. Returns val."}
- aset-long setLong long)
-
-(def-aset
- #^{:doc "Sets the value at the index/indices. Works on arrays of boolean. Returns val."}
- aset-boolean setBoolean boolean)
-
-(def-aset
- #^{:doc "Sets the value at the index/indices. Works on arrays of float. Returns val."}
- aset-float setFloat float)
-
-(def-aset
- #^{:doc "Sets the value at the index/indices. Works on arrays of double. Returns val."}
- aset-double setDouble double)
-
-(def-aset
- #^{:doc "Sets the value at the index/indices. Works on arrays of short. Returns val."}
- aset-short setShort short)
-
-(def-aset
- #^{:doc "Sets the value at the index/indices. Works on arrays of byte. Returns val."}
- aset-byte setByte byte)
-
-(def-aset
- #^{:doc "Sets the value at the index/indices. Works on arrays of char. Returns val."}
- aset-char setChar char)
-
-(defn make-array
- "Creates and returns an array of instances of the specified class of
- the specified dimension(s). Note that a class object is required.
- Class objects can be obtained by using their imported or
- fully-qualified name. Class objects for the primitive types can be
- obtained using, e.g., (. Integer TYPE)."
- ([#^Class type len]
- (. Array (newInstance type (int len))))
- ([#^Class type dim & more-dims]
- (let [dims (cons dim more-dims)
- #^"[I" dimarray (make-array (. Integer TYPE) (count dims))]
- (dotimes i (alength dimarray)
- (aset-int dimarray i (nth dims i)))
- (. Array (newInstance type dimarray)))))
-
-(defn to-array-2d
- "Returns a (potentially-ragged) 2-dimensional array of Objects
- containing the contents of coll, which can be any Collection of any
- Collection."
- [#^java.util.Collection coll]
- (let [ret (make-array (. Class (forName "[Ljava.lang.Object;")) (. coll (size)))]
- (loop [i 0 xs (seq coll)]
- (when xs
- (aset ret i (to-array (first xs)))
- (recur (inc i) (rest xs))))
- ret))
-
-(import '(java.util.concurrent Executors LinkedBlockingQueue))
-
-(defn pmap
- ([f coll]
- (let [nthreads (.. Runtime (getRuntime) (availableProcessors))
- exec (. Executors (newFixedThreadPool nthreads))
- todo (ref (seq coll))
- out (ref 0)
- q (new LinkedBlockingQueue)
- produce (fn []
- (let [job (sync nil
- (when @todo
- (let [item (first @todo)]
- (alter todo rest)
- (commute out inc)
- (list item))))]
- (when job
- (. q (put (f (first job))))
- (recur))))
- tasks (doseq dnu (map (fn [task]
- (. exec (submit #^java.util.concurrent.Callable task)))
- (replicate nthreads produce)))
- consume (fn thisfn []
- (if (sync nil (and (or @todo (pos? @out))
- (commute out dec)))
- (fnseq (. q (take)) thisfn)
- (do
- (. exec (shutdown))
- (doseq x tasks)
- nil)))]
- (consume)))
- ([f coll & colls]
- (pmap (fn [items] (apply f items))
- (let [encl-fn (fn thisfn [collseq]
- (when (every? seq collseq)
- (lazy-cons (map first collseq)
- (thisfn (map rest collseq)))))]
- (encl-fn (cons coll colls))))))
-
-(defn macroexpand-1
- "If form represents a macro form, returns its expansion,
- else returns form."
- [form]
- (. clojure.lang.Compiler (macroexpand1 form)))
-
-(defn macroexpand
- "Repeatedly calls macroexpand-1 on form until it no longer
- represents a macro form, then returns it. Note neither
- macroexpand-1 nor macroexpand expand macros in subforms."
- [form]
- (let [ex (macroexpand-1 form)]
- (if (identical? ex form)
- form
- (macroexpand ex))))
-
-(defn create-struct
- "Returns a structure basis object."
- [& keys]
- (. clojure.lang.PersistentStructMap (createSlotMap keys)))
-
-(defmacro defstruct
- "Same as (def name (create-struct keys...))"
- [name & keys]
- `(def ~name (create-struct ~@keys)))
-
-(defn struct-map
- "Returns a new structmap instance with the keys of the
- structure-basis. keyvals may contain all, some or none of the basis
- keys - where values are not supplied they will default to nil.
- keyvals can also contain keys not in the basis."
- [s & inits]
- (. clojure.lang.PersistentStructMap (create s inits)))
-
-(defn struct
- "Returns a new structmap instance with the keys of the
- structure-basis. vals must be supplied for basis keys in order -
- where values are not supplied they will default to nil."
- [s & vals]
- (. clojure.lang.PersistentStructMap (construct s vals)))
-
-(defn accessor
- "Returns a fn that, given an instance of a structmap with the basis,
- returns the value at the key. The key must be in the basis. The
- returned function should be (slightly) more efficient than using
- get, but such use of accessors should be limited to known
- performance-critical areas."
- [s key]
- (. clojure.lang.PersistentStructMap (getAccessor s key)))
-
-(defn subvec
- "Returns a persistent vector of the items in vector from
- start (inclusive) to end (exclusive). If end is not supplied,
- defaults to (count vector). This operation is O(1) and very fast, as
- the resulting vector shares structure with the original and no
- trimming is done."
- ([v start]
- (subvec v start (count v)))
- ([v start end]
- (. clojure.lang.RT (subvec v start end))))
-
-(defn load
- "Sequentially read and evaluate the set of forms contained in the
- stream/file"
- [rdr] (. clojure.lang.Compiler (load rdr)))
-
-(defn resultset-seq
- "Creates and returns a lazy sequence of structmaps corresponding to
- the rows in the java.sql.ResultSet rs"
- [#^java.sql.ResultSet rs]
- (let [rsmeta (. rs (getMetaData))
- idxs (range 1 (inc (. rsmeta (getColumnCount))))
- keys (map (comp keyword (memfn toLowerCase))
- (map (fn [i] (. rsmeta (getColumnName i))) idxs))
- row-struct (apply create-struct keys)
- row-values (fn [] (map (fn [#^Integer i] (. rs (getObject i))) idxs))
- rows (fn thisfn []
- (when (. rs (next))
- (lazy-cons (apply struct row-struct (row-values)) (thisfn))))]
- (rows)))
-
-(defn set
- "Returns a set of the distinct elements of coll."
- [coll] (apply hash-set coll))
-
-(defn #^{:private true}
- filter-key [keyfn pred amap]
- (loop [ret {} es (seq amap)]
- (if es
- (if (pred (keyfn (first es)))
- (recur (assoc ret (key (first es)) (val (first es))) (rest es))
- (recur ret (rest es)))
- ret)))
-
-(defn find-ns
- "Returns the namespace named by the symbol or nil if it doesn't exist."
- [sym] (. clojure.lang.Namespace (find sym)))
-
-(defn create-ns
- "Create a new namespace named by the symbol if one doesn't already
- exist, returns it or the already-existing namespace of the same
- name."
- [sym] (. clojure.lang.Namespace (findOrCreate sym)))
-
-(defn remove-ns
- "Removes the namespace named by the symbol. Use with caution.
- Cannot be used to remove the clojure namespace."
- [sym] (. clojure.lang.Namespace (remove sym)))
-
-(defn all-ns
- "Returns a sequence of all namespaces."
- [] (. clojure.lang.Namespace (all)))
-
-(defn ns-name
- "Returns the name of the namespace, a symbol."
- [#^clojure.lang.Namespace ns]
- (. ns (getName)))
-
-(defn ns-map
- "Returns a map of all the mappings for the namespace."
- [#^clojure.lang.Namespace ns]
- (. ns (getMappings)))
-
-(defn ns-unmap
- "Removes the mappings for the symbol from the namespace."
- [#^clojure.lang.Namespace ns sym]
- (. ns (unmap sym)))
-
-;(defn export [syms]
-; (doseq sym syms
-; (.. *ns* (intern sym) (setExported true))))
-
-(defn ns-publics
- "Returns a map of the public intern mappings for the namespace."
- [#^clojure.lang.Namespace ns]
- (filter-key val (fn [#^clojure.lang.Var v] (and (instance? clojure.lang.Var v)
- (= ns (. v ns))
- (. v (isPublic))))
- (ns-map ns)))
-
-(defn ns-imports
- "Returns a map of the import mappings for the namespace."
- [#^clojure.lang.Namespace ns]
- (filter-key val (partial instance? Class) (ns-map ns)))
-
-(defn refer
- "refers to all public vars of ns, subject to filters.
- filters can include at most one each of:
-
- :exclude list-of-symbols
- :only list-of-symbols
- :rename map-of-fromsymbol-tosymbol
-
- For each public interned var in the namespace named by the symbol,
- adds a mapping from the name of the var to the var to the current
- namespace. Throws an exception if name is already mapped to
- something else in the current namespace. Filters can be used to
- select a subset, via inclusion or exclusion, or to provide a mapping
- to a symbol different from the var's name, in order to prevent
- clashes."
- [ns-sym & filters]
- (let [ns (or (find-ns ns-sym) (throw (new Exception (str "No namespace: " ns-sym))))
- fs (apply hash-map filters)
- nspublics (ns-publics ns)
- rename (or (:rename fs) {})
- exclude (set (:exclude fs))
- to-do (or (:only fs) (keys nspublics))]
- (doseq sym to-do
- (when-not (exclude sym)
- (let [v (nspublics sym)]
- (when-not v
- (throw (new java.lang.IllegalAccessError (str sym " is not public"))))
- (. *ns* (refer (or (rename sym) sym) v)))))))
-
-(defn ns-refers
- "Returns a map of the refer mappings for the namespace."
- [#^clojure.lang.Namespace ns]
- (filter-key val (fn [#^clojure.lang.Var v] (and (instance? clojure.lang.Var v)
- (not= ns (. v ns))))
- (ns-map ns)))
-
-(defn ns-interns
- "Returns a map of the intern mappings for the namespace."
- [#^clojure.lang.Namespace ns]
- (filter-key val (fn [#^clojure.lang.Var v] (and (instance? clojure.lang.Var v)
- (= ns (. v ns))))
- (ns-map ns)))
-
-(defn take-nth
- "Returns a lazy seq of every nth item in coll."
- [n coll]
- (when (seq coll)
- (lazy-cons (first coll) (take-nth n (drop n coll)))))
-
-(defn interleave
- "Returns a lazy seq of the first item in each coll, then the second
- etc."
- [& colls]
- (apply concat (apply map list colls)))
-
-(defn var-get
- "Gets the value in the var object"
- [#^clojure.lang.Var x] (. x (get)))
-
-(defn var-set
- "Sets the value in the var object to val. The var must be
- thread-locally bound."
- [#^clojure.lang.Var x val] (. x (set val)))
-
-(defmacro with-local-vars
- "varbinding=> symbol init-expr
-
- Executes the exprs in a context in which the symbols are bound to
- vars with per-thread bindings to the init-exprs. The symbols refer
- to the var objects themselves, and must be accessed with var-get and
- var-set"
- [name-vals-vec & body]
- `(let [~@(interleave (take-nth 2 name-vals-vec)
- (repeat '(. clojure.lang.Var (create))))]
- (. clojure.lang.Var (pushThreadBindings (hash-map ~@name-vals-vec)))
- (try
- ~@body
- (finally (. clojure.lang.Var (popThreadBindings))))))
-
-(defn ns-resolve
- "Returns the var or Class to which a symbol will be resolved in the
- namespace, else nil. Note that if the symbol is fully qualified,
- the var/Class to which it resolves need not be present in the
- namespace."
- [ns sym]
- (. clojure.lang.Compiler (maybeResolveIn ns sym)))
-
-(defn resolve
- "same as (ns-resolve *ns* symbol)"
- [sym] (ns-resolve *ns* sym))
-
-(defn array-map
- "Constructs an array-map."
- ([] (. clojure.lang.PersistentArrayMap EMPTY))
- ([& keyvals] (new clojure.lang.PersistentArrayMap (to-array keyvals))))
-
-(defn nthrest
- "Returns the nth rest of coll, (seq coll) when n is 0."
- [coll n]
- (loop [n n xs (seq coll)]
- (if (and xs (pos? n))
- (recur (dec n) (rest xs))
- xs)))
-
-(defn symbol?
- "Return true if x is a Symbol"
- [x] (instance? clojure.lang.Symbol x))
-
-(defn keyword?
- "Return true if x is a Keyword"
- [x] (instance? clojure.lang.Keyword x))
-
-;redefine let and loop with destructuring
-(defn destructure [bindings]
- (let [bmap (apply array-map bindings)
- pb (fn pb [bvec b v]
- (let [pvec
- (fn [bvec b val]
- (let [gvec (gensym "vec__")]
- (loop [ret (-> bvec (conj gvec) (conj val))
- n 0
- bs b
- seen-rest? false]
- (if bs
- (let [firstb (first bs)]
- (cond
- (= firstb '&) (recur (pb ret (second bs) (list `nthrest gvec n))
- n
- (rrest bs)
- true)
- (= firstb :as) (pb ret (second bs) gvec)
- :else (if seen-rest?
- (throw (new Exception "Unsupported binding form, only :as can follow & parameter"))
- (recur (pb ret firstb (list `nth gvec n nil))
- (inc n)
- (rest bs)
- seen-rest?))))
- ret))))
- pmap
- (fn [bvec b v]
- (let [gmap (or (:as b) (gensym "map__"))
- defaults (:or b)]
- (loop [ret (-> bvec (conj gmap) (conj v))
- bes (reduce
- (fn [bes entry]
- (reduce #(assoc %1 %2 ((val entry) %2))
- (dissoc bes (key entry))
- ((key entry) bes)))
- (dissoc b :as :or)
- {:keys #(keyword (str %)), :strs str, :syms #(list `quote %)})]
- (if bes
- (let [bb (key (first bes))
- bk (val (first bes))
- has-default (contains? defaults bb)]
- (recur (pb ret bb (if has-default
- (list `get gmap bk (defaults bb))
- (list `get gmap bk)))
- (rest bes)))
- ret))))]
- (cond
- (symbol? b) (-> bvec (conj b) (conj v))
- (vector? b) (pvec bvec b v)
- (map? b) (pmap bvec b v)
- :else (throw (new Exception (str "Unsupported binding form: " b))))))
- process-entry (fn [bvec b] (pb bvec (key b) (val b)))]
- (if (every? symbol? (keys bmap))
- bindings
- (reduce process-entry [] bmap))))
-
-(defmacro let
- "Evaluates the exprs in a lexical context in which the symbols in
- the binding-forms are bound to their respective init-exprs or parts
- therein."
- [bindings & body]
- `(let* ~(destructure bindings) ~@body))
-
-;redefine fn with destructuring
-(defmacro fn
- "(fn name? [params* ] exprs*)
- (fn name? ([params* ] exprs*)+)
-
- params => positional-params* , or positional-params* & rest-param
- positional-param => binding-form
- rest-param => binding-form
- name => symbol
-
- Defines a function"
- [& sigs]
- (let [name (if (symbol? (first sigs)) (first sigs) nil)
- sigs (if name (rest sigs) sigs)
- sigs (if (vector? (first sigs)) (list sigs) sigs)
- psig (fn [sig]
- (let [[params & body] sig]
- (if (every? symbol? params)
- sig
- (loop [params params
- new-params []
- lets []]
- (if params
- (if (symbol? (first params))
- (recur (rest params) (conj new-params (first params)) lets)
- (let [gparam (gensym "p__")]
- (recur (rest params) (conj new-params gparam)
- (-> lets (conj (first params)) (conj gparam)))))
- `(~new-params
- (let ~lets
- ~@body)))))))
- new-sigs (map psig sigs)]
- (with-meta
- (if name
- (list* 'fn* name new-sigs)
- (cons 'fn* new-sigs))
- *macro-meta*)))
-
-(defmacro loop
- "Evaluates the exprs in a lexical context in which the symbols in
- the binding-forms are bound to their respective init-exprs or parts
- therein. Acts as a recur target."
- [bindings & body]
- (let [db (destructure bindings)]
- (if (= db bindings)
- `(loop* ~bindings ~@body)
- (let [vs (take-nth 2 (drop 1 bindings))
- bs (take-nth 2 bindings)
- gs (map (fn [b] (if (symbol? b) b (gensym))) bs)
- bfs (reduce (fn [ret [b v g]]
- (if (symbol? b)
- (conj ret g v)
- (conj ret g v b g)))
- [] (map vector bs vs gs))]
- `(let ~bfs
- (loop* ~(vec (interleave gs gs))
- (let ~(vec (interleave bs gs))
- ~@body)))))))
-
-(defmacro when-first
- "Same as (when (seq xs) (let [x (first xs)] body))"
- [x xs & body]
- `(when (seq ~xs)
- (let [~x (first ~xs)]
- ~@body)))
-
-(defmacro lazy-cat
- "Expands to code which yields a lazy sequence of the concatenation
- of the supplied colls. Each coll expr is not evaluated until it is
- needed."
- ([coll] `(seq ~coll))
- ([coll & colls]
- `(let [iter# (fn iter# [coll#]
- (if (seq coll#)
- (lazy-cons (first coll#) (iter# (rest coll#)))
- (lazy-cat ~@colls)))]
- (iter# ~coll))))
-
-
-
-(defmacro for
- "List comprehension. Takes a vector of one or more
- binding-form/collection-expr pairs, each followed by an optional filtering
- :when/:while expression (:when test or :while test), and yields a
- lazy sequence of evaluations of expr. Collections are iterated in a
- nested fashion, rightmost fastest, and nested coll-exprs can refer to
- bindings created in prior binding-forms.
-
- (take 100 (for [x (range 100000000) y (range 1000000) :while (< y x)] [x y]))"
- ([seq-exprs expr]
- (let [pargs (fn [xs]
- (loop [ret []
- [b e & [w f & wr :as r] :as xs] (seq xs)]
- (if xs
- (cond
- (= w :when) (recur (conj ret {:b b :e e :f f :w :when}) wr)
- (= w :while) (recur (conj ret {:b b :e e :f f :w :while}) wr)
- :else (recur (conj ret {:b b :e e :f true :w :while}) r))
- (seq ret))))
- emit (fn emit [[{b :b f :f w :w} & [{ys :e} :as rses]]]
- (let [giter (gensym "iter__") gxs (gensym "s__")]
- `(fn ~giter [~gxs]
- (when-first ~b ~gxs
- (if ~f
- ~(if rses
- `(let [iterys# ~(emit rses)]
- (lazy-cat (iterys# ~ys)
- (~giter (rest ~gxs))))
- `(lazy-cons ~expr (~giter (rest ~gxs))))
- ~(if (= w :when)
- `(recur (rest ~gxs))
- nil))))))]
- `(let [iter# ~(emit (pargs seq-exprs))]
- (iter# ~(second seq-exprs))))))
-
-(defmacro comment
- "Ignores body, yields nil"
- [& body])
-
-(defmacro with-out-str
- "Evaluates exprs in a context in which *out* is bound to a fresh
- StringWriter. Returns the string created by any nested printing
- calls."
- [& body]
- `(let [s# (new java.io.StringWriter)]
- (binding [*out* s#]
- ~@body
- (str s#))))
-
-(defn pr-str
- "pr to a string, returning it"
- [& xs]
- (with-out-str
- (apply pr xs)))
-
-(defn prn-str
- "prn to a string, returning it"
- [& xs]
- (with-out-str
- (apply prn xs)))
-
-(defn print-str
- "print to a string, returning it"
- [& xs]
- (with-out-str
- (apply print xs)))
-
-(defn println-str
- "println to a string, returning it"
- [& xs]
- (with-out-str
- (apply println xs)))
-
-(defmacro assert
- "Evaluates expr and throws an exception if it does not evaluate to
- logical true."
- [x]
- `(when-not ~x
- (throw (new Exception (str "Assert failed: " (pr-str '~x))))))
-
-(defn test
- "test [v] finds fn at key :test in var metadata and calls it,
- presuming failure will throw exception"
- [v]
- (let [f (:test ^v)]
- (if f
- (do (f) :ok)
- :no-test)))
-
-(defn re-pattern
- "Returns an instance of java.util.regex.Pattern, for use, e.g. in
- re-matcher."
- {:tag java.util.regex.Pattern}
- [s] (. java.util.regex.Pattern (compile s)))
-
-(defn re-matcher
- "Returns an instance of java.util.regex.Matcher, for use, e.g. in
- re-find."
- {:tag java.util.regex.Matcher}
- [#^java.util.regex.Pattern re s]
- (. re (matcher s)))
-
-(defn re-groups
- "Returns the groups from the most recent match/find. If there are no
- nested groups, returns a string of the entire match. If there are
- nested groups, returns a vector of the groups, the first element
- being the entire match."
- [#^java.util.regex.Matcher m]
- (let [gc (. m (groupCount))]
- (if (zero? gc)
- (. m (group))
- (loop [ret [] c 0]
- (if (<= c gc)
- (recur (conj ret (. m (group c))) (inc c))
- ret)))))
-
-(defn re-seq
- "Returns a lazy sequence of successive matches of pattern in string,
- using java.util.regex.Matcher.find(), each such match processed with
- re-groups."
- [#^java.util.regex.Pattern re s]
- (let [m (re-matcher re s)]
- ((fn step []
- (when (. m (find))
- (lazy-cons (re-groups m) (step)))))))
-
-(defn re-matches
- "Returns the match, if any, of string to pattern, using
- java.util.regex.Matcher.matches(). Uses re-groups to return the
- groups."
- [#^java.util.regex.Pattern re s]
- (let [m (re-matcher re s)]
- (when (. m (matches))
- (re-groups m))))
-
-
-(defn re-find
- "Returns the next regex match, if any, of string to pattern, using
- java.util.regex.Matcher.find(). Uses re-groups to return the
- groups."
- ([#^java.util.regex.Matcher m]
- (when (. m (find))
- (re-groups m)))
- ([#^java.util.regex.Pattern re s]
- (let [m (re-matcher re s)]
- (re-find m))))
-
-(defn rand
- "Returns a random floating point number between 0 (inclusive) and
- 1 (exclusive)."
- ([] (. Math (random)))
- ([n] (* n (rand))))
-
-(defn rand-int
- "Returns a random integer between 0 (inclusive) and n (exclusive)."
- [n] (int (rand n)))
-
-(defmacro defn-
- "same as defn, yielding non-public def"
- [name & decls]
- (list* `defn (with-meta name (assoc (meta name) :private true)) decls))
-
-(defn print-doc [v]
- (println "-------------------------")
- (println (str (ns-name (:ns ^v)) "/" (:name ^v)))
- (prn (:arglists ^v))
- (when (:macro ^v)
- (println "Macro"))
- (println " " (:doc ^v)))
-
-(defn find-doc
- "Prints documentation for any var whose documentation or name
- contains a match for re-string"
- [re-string]
- (let [re (re-pattern re-string)]
- (dorun (for [ns (all-ns)
- v (sort-by (comp :name meta) (vals (ns-interns ns)))
- :when (and (:doc ^v)
- (or (re-find (re-matcher re (:doc ^v)))
- (re-find (re-matcher re (str (:name ^v))))))]
- (print-doc v)))))
-
-(defmacro doc
- "Prints documentation for the var named by varname"
- [varname]
- `(print-doc (var ~varname)))
-
-(defn tree-seq
- "returns a lazy sequence of the nodes in a tree, via a depth-first walk.
- branch? must be a fn of one arg that returns true if passed a node
- that can have children (but may not). children must be a fn of one
- arg that returns a sequence of the children. Will only be called on
- nodes for which branch? returns true. Root is the root node of the
- tree, must be a branch."
- [branch? children root]
- (let [walk (fn walk [nodes]
- (when-first node nodes
- (lazy-cons
- node
- (if (branch? node)
- (lazy-cat (walk (children node))
- (walk (rest nodes)))
- (walk (rest nodes))))))]
- (lazy-cons root (walk (children root)))))
-
-(defn file-seq
- "A tree seq on java.io.Files"
- [dir]
- (tree-seq
- (fn [#^java.io.File f] (. f (isDirectory)))
- (fn [#^java.io.File d] (seq (. d (listFiles))))
- dir))
-
-(defn xml-seq
- "A tree seq on the xml elements as per xml/parse"
- [root]
- (tree-seq
- (complement string?)
- (comp seq :content)
- root))
-
-(defn special-symbol?
- "Returns true if s names a special form"
- [s]
- (contains? (. clojure.lang.Compiler specials) s))
-
-(defn var?
- "Returns true if v is of type clojure.lang.Var"
- [v] (instance? clojure.lang.Var v))
-
-(defn class
- "Returns the Class of x"
- [#^Object x] (. x (getClass)))
-
-(defn slurp
- "Reads the file named by f into a string and returns it."
- [#^String f]
- (with-open r (new java.io.BufferedReader (new java.io.FileReader f))
- (let [sb (new StringBuilder)]
- (loop [c (. r (read))]
- (if (neg? c)
- (str sb)
- (do
- (. sb (append (char c)))
- (recur (. r (read)))))))))
-
-(defn subs
- "Returns the substring of s beginning at start inclusive, and ending
- at end (defaults to length of string), exclusive."
- ([#^String s start] (. s (substring start)))
- ([#^String s start end] (. s (substring start end))))
-
-(defn max-key
- "Returns the x for which (k x), a number, is greatest."
- ([k x] x)
- ([k x y] (if (> (k x) (k y)) x y))
- ([k x y & more]
- (reduce #(max-key k %1 %2) (max-key k x y) more)))
-
-(defn min-key
- "Returns the x for which (k x), a number, is least."
- ([k x] x)
- ([k x y] (if (< (k x) (k y)) x y))
- ([k x y & more]
- (reduce #(min-key k %1 %2) (min-key k x y) more)))
-
-(defn distinct
- "Returns a lazy sequence of the elements of coll with duplicates removed"
- [coll]
- (let [step (fn step [[f & r :as xs] seen]
- (when xs
- (if (seen f) (recur r seen)
- (lazy-cons f (step r (conj seen f))))))]
- (step (seq coll) #{})))
-
-(defmacro if-let
- "if test is true, evaluates then with binding-form bound to the value of test, if not, yields else"
- ([binding-form test then]
- `(if-let ~binding-form ~test ~then nil))
- ([binding-form test then else]
- `(let [temp# ~test]
- (if temp#
- (let [~binding-form temp#]
- ~then)
- ~else))))
-
-(defmacro when-let
- "when test is true, evaluates body with binding-form bound to the value of test"
- [binding-form test & body]
- `(let [temp# ~test]
- (when temp#
- (let [~binding-form temp#]
- ~@body))))
-
-(defn replace
- "Given a map of replacement pairs and a vector/collection, returns a
- vector/seq with any elements = a key in smap replaced with the
- corresponding val in smap"
- [smap coll]
- (if (vector? coll)
- (reduce (fn [v i]
- (if-let e (find smap (nth v i))
- (assoc v i (val e))
- v))
- coll (range (count coll)))
- (map #(if-let e (find smap %) (val e) %) coll)))
-
-(defmacro dosync
- "Runs the exprs (in an implicit do) in a transaction that encompasses
- exprs and any nested calls. Starts a transaction if none is already
- running on this thread. Any uncaught exception will abort the
- transaction and flow out of dosync. The exprs may be run more than
- once, but any effects on Refs will be atomic."
- [& exprs]
- `(sync nil ~@exprs))
-
-(defmacro with-precision
- "Sets the precision and rounding mode to be used for BigDecimal operations.
-
- Usage: (with-precision 10 (/ 1M 3))
- or: (with-precision 10 :rounding HALF_DOWN (/ 1M 3))
-
- The rounding mode is one of CEILING, FLOOR, HALF_UP, HALF_DOWN,
- HALF_EVEN, UP, DOWN and UNNECESSARY; it defaults to HALF_UP."
- [precision & exprs]
- (let [[body rm] (if (= (first exprs) :rounding)
- [(rest (rest exprs))
- `((. java.math.RoundingMode ~(second exprs)))]
- [exprs nil])]
- `(binding [*math-context* (java.math.MathContext. ~precision ~@rm)]
- ~@body)))
-
-(defn bound-fn
- {:private true}
- [#^clojure.lang.Sorted sc test key]
- (fn [e]
- (test (.. sc comparator (compare (. sc entryKey e) key)) 0)))
-
-(defn subseq
- "sc must be a sorted collection, test(s) one of <, <=, > or
- >=. Returns a seq of those entries with keys ek for
- which (test (.. sc comparator (compare ek key)) 0) is true"
- ([#^clojure.lang.Sorted sc test key]
- (let [include (bound-fn sc test key)]
- (if (#{> >=} test)
- (when-let [e :as s] (. sc seqFrom key true)
- (if (include e) s (rest s)))
- (take-while include (. sc seq true)))))
- ([#^clojure.lang.Sorted sc start-test start-key end-test end-key]
- (when-let [e :as s] (. sc seqFrom start-key true)
- (take-while (bound-fn sc end-test end-key)
- (if ((bound-fn sc start-test start-key) e) s (rest s))))))
-
-(defn rsubseq
- "sc must be a sorted collection, test(s) one of <, <=, > or
- >=. Returns a reverse seq of those entries with keys ek for
- which (test (.. sc comparator (compare ek key)) 0) is true"
- ([#^clojure.lang.Sorted sc test key]
- (let [include (bound-fn sc test key)]
- (if (#{< <=} test)
- (when-let [e :as s] (. sc seqFrom key false)
- (if (include e) s (rest s)))
- (take-while include (. sc seq false)))))
- ([#^clojure.lang.Sorted sc start-test start-key end-test end-key]
- (when-let [e :as s] (. sc seqFrom end-key false)
- (take-while (bound-fn sc start-test start-key)
- (if ((bound-fn sc end-test end-key) e) s (rest s))))))
-
-(defn repeatedly
- "Takes a function of no args, presumably with side effects, and returns an infinite
- lazy sequence of calls to it"
- [f] (lazy-cons (f) (repeatedly f)))
-
-(defn add-classpath
- "Adds the url (String or URL object) to the classpath per URLClassLoader.addURL"
- [url] (. clojure.lang.RT addURL url))
-
-
-
-(defn hash
- "Returns the hash code of its argument"
- [x] (. clojure.lang.Util (hash x)))
-
-(defn interpose
- "Returns a lazy seq of the elements of coll separated by sep"
- [sep coll] (drop 1 (interleave (repeat sep) coll)))
-
-(defn partition
- "Returns a lazy sequence of lists of n items each, at offsets step
- apart. If step is not supplied, defaults to n, i.e. the partitions
- do not overlap."
- ([n coll]
- (partition n n coll))
- ([n step coll]
- (when (seq coll)
- (let [p (take n coll)]
- (when (= n (count p))
- (lazy-cons p (partition n step (drop step coll))))))))
-
-(defmacro definline
- "Experimental - like defmacro, except defines a named function whose
- body is the expansion, calls to which may be expanded inline as if
- it were a macro"
- [name & decl]
- (let [[args expr] (drop-while (comp not vector?) decl)
- inline (eval (list 'fn args expr))]
- `(do
- (defn ~name ~args ~(apply inline args))
- (let [v# (var ~name)]
- (.setMeta v# (assoc ^v# :inline ~inline))))))
-
-(defn empty
- "Returns an empty collection of the same category as coll, or nil"
- [#^clojure.lang.IPersistentCollection coll]
- (.empty coll))
-
-(defmacro amap
- "Maps an expression across an array a, using an index named idx, and
- return value named ret, initialized to a clone of a, then setting each element of
- ret to the evaluation of expr, returning the new array ret."
- [a idx ret expr]
- `(let [a# ~a
- ~ret (aclone a#)]
- (loop [~idx (int 0)]
- (if (< ~idx (alength a#))
- (do
- (aset ~ret ~idx ~expr)
- (recur (unchecked-inc ~idx)))
- ~ret))))
-
-(defmacro areduce
- "Reduces an expression across an array a, using an index named idx,
- and return value named ret, initialized to init, setting ret to the evaluation of expr at
- each step, returning ret."
- [a idx ret init expr]
- `(let [a# ~a]
- (loop [~idx (int 0) ~ret ~init]
- (if (< ~idx (alength a#))
- (recur (unchecked-inc ~idx) ~expr)
- ~ret))))
-
-(defn float-array
- "Creates an array of floats"
- {:inline (fn [& args] `(. clojure.lang.Numbers float_array ~@args))
- :inline-arities #{1 2}}
- ([size-or-seq] (. clojure.lang.Numbers float_array size-or-seq))
- ([size init-val-or-seq] (. clojure.lang.Numbers float_array size init-val-or-seq)))
-
-(defn double-array
- "Creates an array of doubles"
- {:inline (fn [& args] `(. clojure.lang.Numbers double_array ~@args))
- :inline-arities #{1 2}}
- ([size-or-seq] (. clojure.lang.Numbers double_array size-or-seq))
- ([size init-val-or-seq] (. clojure.lang.Numbers double_array size init-val-or-seq)))
-
-(defn int-array
- "Creates an array of ints"
- {:inline (fn [& args] `(. clojure.lang.Numbers int_array ~@args))
- :inline-arities #{1 2}}
- ([size-or-seq] (. clojure.lang.Numbers int_array size-or-seq))
- ([size init-val-or-seq] (. clojure.lang.Numbers int_array size init-val-or-seq)))
-
-(defn long-array
- "Creates an array of ints"
- {:inline (fn [& args] `(. clojure.lang.Numbers long_array ~@args))
- :inline-arities #{1 2}}
- ([size-or-seq] (. clojure.lang.Numbers long_array size-or-seq))
- ([size init-val-or-seq] (. clojure.lang.Numbers long_array size init-val-or-seq)))
-
-(definline floats
- "Casts to float[]"
- [xs] `(. clojure.lang.Numbers floats ~xs))
-
-(definline ints
- "Casts to int[]"
- [xs] `(. clojure.lang.Numbers ints ~xs))
-
-(definline doubles
- "Casts to double[]"
- [xs] `(. clojure.lang.Numbers doubles ~xs))
-
-(definline longs
- "Casts to long[]"
- [xs] `(. clojure.lang.Numbers longs ~xs))
-
-(import '(java.util.concurrent BlockingQueue LinkedBlockingQueue))
-
-(defn seque
- "Creates a queued seq on another (presumably lazy) seq s. The queued
- seq will produce a concrete seq in the background, and can get up to
- n items ahead of the consumer. n-or-q can be an integer n buffer
- size, or an instance of java.util.concurrent BlockingQueue. Note
- that reading from a seque can block if the reader gets ahead of the
- producer."
- ([s] (seque 100 s))
- ([n-or-q s]
- (let [#^BlockingQueue q (if (instance? BlockingQueue n-or-q)
- n-or-q
- (LinkedBlockingQueue. (int n-or-q)))
- NIL (Object.) ;nil sentinel since LBQ doesn't support nils
- agt (agent (seq s))
- fill (fn [s]
- (try
- (loop [[x & xs :as s] s]
- (if s
- (if (.offer q (if (nil? x) NIL x))
- (recur xs)
- s)
- (.put q q))) ; q itself is eos sentinel
- (catch Exception e
- (.put q q)
- (throw e))))
- drain (fn drain []
- (let [x (.take q)]
- (if (identical? x q) ;q itself is eos sentinel
- @agt ;will be nil - touch agent just to propagate errors
- (do
- (send-off agt fill)
- (lazy-cons (if (identical? x NIL) nil x) (drain))))))]
- (send-off agt fill)
- (drain)))) \ No newline at end of file
diff --git a/src/genclass.clj b/src/genclass.clj
deleted file mode 100644
index cdc09845..00000000
--- a/src/genclass.clj
+++ /dev/null
@@ -1,517 +0,0 @@
-; Copyright (c) Rich Hickey. All rights reserved.
-; The use and distribution terms for this software are covered by the
-; Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
-; which can be found in the file CPL.TXT at the root of this distribution.
-; By using this software in any fashion, you are agreeing to be bound by
-; the terms of this license.
-; You must not remove this notice, or any other, from this software.
-
-(in-ns 'clojure)
-
-(import '(java.lang.reflect Modifier Constructor)
- '(clojure.asm ClassWriter ClassVisitor Opcodes Type)
- '(clojure.asm.commons Method GeneratorAdapter)
- '(clojure.lang IPersistentMap))
-
-;(defn method-sig [#^java.lang.reflect.Method meth]
-; [(. meth (getName)) (seq (. meth (getParameterTypes)))])
-
-(defn- non-private-methods [#^Class c]
- (loop [mm {}
- considered #{}
- c c]
- (if c
- (let [[mm considered]
- (loop [mm mm
- considered considered
- meths (concat
- (seq (. c (getDeclaredMethods)))
- (seq (. c (getMethods))))]
- (if meths
- (let [#^java.lang.reflect.Method meth (first meths)
- mods (. meth (getModifiers))
- mk (method-sig meth)]
- (if (or (considered mk)
- (. Modifier (isPrivate mods))
- (. Modifier (isStatic mods))
- (. Modifier (isFinal mods))
- (= "finalize" (.getName meth)))
- (recur mm (conj considered mk) (rest meths))
- (recur (assoc mm mk meth) (conj considered mk) (rest meths))))
- [mm considered]))]
- (recur mm considered (. c (getSuperclass))))
- mm)))
-
-(defn- ctor-sigs [super]
- (for [#^Constructor ctor (. super (getDeclaredConstructors))
- :when (not (. Modifier (isPrivate (. ctor (getModifiers)))))]
- (apply vector (. ctor (getParameterTypes)))))
-
-(defn- escape-class-name [c]
- (.. (.getSimpleName c)
- (replace "[]" "<>")))
-
-(defn- overload-name [mname pclasses]
- (if (seq pclasses)
- (apply str mname (interleave (repeat \-)
- (map escape-class-name pclasses)))
- (str mname "-void")))
-
-;(distinct (map first(keys (mapcat non-private-methods [Object IPersistentMap]))))
-
-(defn gen-class
- "Generates compiled bytecode for a class with the given
- package-qualified cname (which, as all names in these parameters, can
- be a string or symbol). The gen-class construct contains no
- implementation, as the implementation will be dynamically sought by
- the generated class in functions in a corresponding Clojure
- namespace. Given a generated class org.mydomain.MyClass, methods
- will be implemented that look for same-named functions in a Clojure
- namespace called org.domain.MyClass. The init and main
- functions (see below) will be found similarly. The static
- initializer for the generated class will attempt to load the Clojure
- support code for the class as a resource from the claspath, e.g. in
- the example case, org/mydomain/MyClass.clj
-
- Returns a map containing :name and :bytecode. Most uses will be
- satisfied by the higher-level gen-and-load-class and
- gen-and-store-class functions, which generate and immediately load,
- or generate and store to disk, respectively.
-
- Options should be a set of key/value pairs, all of which are optional:
-
- :extends aclass
-
- Specifies the superclass, the non-private methods of which will be
- overridden by the class. If not provided, defaults to Object.
-
- :implements [interface ...]
-
- One or more interfaces, the methods of which will be implemented by the class.
-
- :init name
-
- If supplied, names a function that will be called with the arguments
- to the constructor. Must return [ [superclass-constructor-args] state]
- If not supplied, the constructor args are passed directly to
- the superclass constructor and the state will be nil
-
- :constructors {[param-types] [super-param-types], ...}
-
- By default, constructors are created for the generated class which
- match the signature(s) of the constructors for the superclass. This
- parameter may be used to explicitly specify constructors, each entry
- providing a mapping from a constructor signature to a superclass
- constructor signature. When you supply this, you must supply an :init
- specifier.
-
- :methods [ [name [param-types] return-type], ...]
-
- The generated class automatically defines all of the non-private
- methods of its superclasses/interfaces. This parameter can be used
- to specify the signatures of additional methods of the generated
- class. Static methods can be specified with #^{:static true} in the
- signature's metadata. Do not repeat superclass/interface signatures
- here.
-
- :main boolean
-
- If supplied and true, a static public main function will be
- generated. It will pass each string of the String[] argument as a
- separate argument to a function called 'main.
-
- :factory name
-
- If supplied, a (set of) public static factory function(s) will be
- created with the given name, and the same signature(s) as the
- constructor(s).
-
- :state name
-
- If supplied, a public final instance field with the given name will be
- created. You must supply an :init function in order to provide a
- value for the state. Note that, though final, the state can be a ref
- or agent, supporting the creation of Java objects with transactional
- or asynchronous mutation semantics.
-
- :exposes {protected-field-name {:get name :set name}, ...}
-
- Since the implementations of the methods of the generated class
- occur in Clojure functions, they have no access to the inherited
- protected fields of the superclass. This parameter can be used to
- generate public getter/setter methods exposing the protected field(s)
- for use in the implementation."
-
- [cname & options]
- (let [name (str cname)
- {:keys [extends implements constructors methods main factory state init exposes]} (apply hash-map options)
- super (or extends Object)
- interfaces implements
- supers (cons super (seq interfaces))
- ctor-sig-map (or constructors (zipmap (ctor-sigs super) (ctor-sigs super)))
- cv (new ClassWriter (. ClassWriter COMPUTE_MAXS))
- cname (. name (replace "." "/"))
- ctype (. Type (getObjectType cname))
- iname (fn [c] (.. Type (getType c) (getInternalName)))
- totype (fn [c] (. Type (getType c)))
- to-types (fn [cs] (if (pos? (count cs))
- (into-array (map totype cs))
- (make-array Type 0)))
- obj-type (totype Object)
- arg-types (fn [n] (if (pos? n)
- (into-array (replicate n obj-type))
- (make-array Type 0)))
- super-type (totype super)
- init-name (str init)
- factory-name (str factory)
- state-name (str state)
- main-name "main"
- var-name (fn [s] (str s "__var"))
- rt-type (totype clojure.lang.RT)
- var-type (totype clojure.lang.Var)
- ifn-type (totype clojure.lang.IFn)
- iseq-type (totype clojure.lang.ISeq)
- ex-type (totype java.lang.UnsupportedOperationException)
- all-sigs (distinct (concat (map #(let[[m p] (key %)] {m [p]}) (mapcat non-private-methods supers))
- (map (fn [[m p]] {(str m) [p]}) methods)))
- sigs-by-name (apply merge-with concat {} all-sigs)
- overloads (into {} (filter (fn [[m s]] (rest s)) sigs-by-name))
- var-fields (concat (and init [init-name])
- (and main [main-name])
- (distinct (concat (keys sigs-by-name)
- (mapcat (fn [[m s]] (map #(overload-name m %) s)) overloads)
- (mapcat (comp (partial map str) vals val) exposes))))
- emit-get-var (fn [gen v]
- (let [false-label (. gen newLabel)
- end-label (. gen newLabel)]
- (. gen getStatic ctype (var-name v) var-type)
- (. gen dup)
- (. gen invokeVirtual var-type (. Method (getMethod "boolean isBound()")))
- (. gen ifZCmp (. GeneratorAdapter EQ) false-label)
- (. gen invokeVirtual var-type (. Method (getMethod "Object get()")))
- (. gen goTo end-label)
- (. gen mark false-label)
- (. gen pop)
- (. gen visitInsn (. Opcodes ACONST_NULL))
- (. gen mark end-label)))
- emit-forwarding-method
- (fn [mname pclasses rclass as-static else-gen]
- (let [ptypes (to-types pclasses)
- rtype (totype rclass)
- m (new Method mname rtype ptypes)
- is-overload (overloads mname)
- gen (new GeneratorAdapter (+ (. Opcodes ACC_PUBLIC) (if as-static (. Opcodes ACC_STATIC) 0))
- m nil nil cv)
- found-label (. gen (newLabel))
- else-label (. gen (newLabel))
- end-label (. gen (newLabel))]
- (. gen (visitCode))
- (when is-overload
- (emit-get-var gen (overload-name mname pclasses))
- (. gen (dup))
- (. gen (ifNonNull found-label))
- (. gen (pop)))
- (emit-get-var gen mname)
- (. gen (dup))
- (. gen (ifNull else-label))
- (when is-overload
- (. gen (mark found-label)))
- ;if found
- (when-not as-static
- (. gen (loadThis)))
- ;box args
- (dotimes i (count ptypes)
- (. gen (loadArg i))
- (. clojure.lang.Compiler$HostExpr (emitBoxReturn nil gen (nth pclasses i))))
- ;call fn
- (. gen (invokeInterface ifn-type (new Method "invoke" obj-type
- (to-types (replicate (+ (count ptypes)
- (if as-static 0 1))
- Object)))))
- ;(into-array (cons obj-type
- ; (replicate (count ptypes) obj-type))))))
- ;unbox return
- (. gen (unbox rtype))
- (when (= (. rtype (getSort)) (. Type VOID))
- (. gen (pop)))
- (. gen (goTo end-label))
-
- ;else call supplied alternative generator
- (. gen (mark else-label))
- (. gen (pop))
-
- (else-gen gen m)
-
- (. gen (mark end-label))
- (. gen (returnValue))
- (. gen (endMethod))))
- ]
- ;start class definition
- (. cv (visit (. Opcodes V1_5) (+ (. Opcodes ACC_PUBLIC) (. Opcodes ACC_SUPER))
- cname nil (iname super)
- (when interfaces
- (into-array (map iname interfaces)))))
-
- ;static fields for vars
- (doseq v var-fields
- (. cv (visitField (+ (. Opcodes ACC_PUBLIC) (. Opcodes ACC_FINAL) (. Opcodes ACC_STATIC))
- (var-name v)
- (. var-type getDescriptor)
- nil nil)))
-
- ;instance field for state
- (when state
- (. cv (visitField (+ (. Opcodes ACC_PUBLIC) (. Opcodes ACC_FINAL))
- state-name
- (. obj-type getDescriptor)
- nil nil)))
-
- ;static init to set up var fields and load clj
- (let [gen (new GeneratorAdapter (+ (. Opcodes ACC_PUBLIC) (. Opcodes ACC_STATIC))
- (. Method getMethod "void <clinit> ()")
- nil nil cv)]
- (. gen (visitCode))
- (doseq v var-fields
- (. gen push name)
- (. gen push v)
- (. gen (invokeStatic rt-type (. Method (getMethod "clojure.lang.Var var(String,String)"))))
- (. gen putStatic ctype (var-name v) var-type))
-
- (. gen push ctype)
- (. gen push (str (. name replace \. (. java.io.File separatorChar)) ".clj"))
- (. gen (invokeStatic rt-type (. Method (getMethod "void loadResourceScript(Class,String)"))))
-
- (. gen (returnValue))
- (. gen (endMethod)))
-
- ;ctors
- (doseq [pclasses super-pclasses] ctor-sig-map
- (let [ptypes (to-types pclasses)
- super-ptypes (to-types super-pclasses)
- m (new Method "<init>" (. Type VOID_TYPE) ptypes)
- super-m (new Method "<init>" (. Type VOID_TYPE) super-ptypes)
- gen (new GeneratorAdapter (. Opcodes ACC_PUBLIC) m nil nil cv)
- no-init-label (. gen newLabel)
- end-label (. gen newLabel)
- nth-method (. Method (getMethod "Object nth(Object,int)"))
- local (. gen newLocal obj-type)]
- (. gen (visitCode))
-
- (if init
- (do
- (emit-get-var gen init-name)
- (. gen dup)
- (. gen ifNull no-init-label)
- ;box init args
- (dotimes i (count pclasses)
- (. gen (loadArg i))
- (. clojure.lang.Compiler$HostExpr (emitBoxReturn nil gen (nth pclasses i))))
- ;call init fn
- (. gen (invokeInterface ifn-type (new Method "invoke" obj-type
- (arg-types (count ptypes)))))
- ;expecting [[super-ctor-args] state] returned
- (. gen dup)
- (. gen push 0)
- (. gen (invokeStatic rt-type nth-method))
- (. gen storeLocal local)
-
- (. gen (loadThis))
- (. gen dupX1)
- (dotimes i (count super-pclasses)
- (. gen loadLocal local)
- (. gen push i)
- (. gen (invokeStatic rt-type nth-method))
- (. clojure.lang.Compiler$HostExpr (emitUnboxArg nil gen (nth super-pclasses i))))
- (. gen (invokeConstructor super-type super-m))
-
- (if state
- (do
- (. gen push 1)
- (. gen (invokeStatic rt-type nth-method))
- (. gen (putField ctype state-name obj-type)))
- (. gen pop))
-
- (. gen goTo end-label)
- ;no init found
- (. gen mark no-init-label)
- (. gen (throwException ex-type (str init-name " not defined")))
- (. gen mark end-label))
- (if (= pclasses super-pclasses)
- (do
- (. gen (loadThis))
- (. gen (loadArgs))
- (. gen (invokeConstructor super-type super-m)))
- (throw (new Exception ":init not specified, but ctor and super ctor args differ"))))
-
- (. gen (returnValue))
- (. gen (endMethod))
- ;factory
- (when factory
- (let [fm (new Method factory-name ctype ptypes)
- gen (new GeneratorAdapter (+ (. Opcodes ACC_PUBLIC) (. Opcodes ACC_STATIC))
- fm nil nil cv)]
- (. gen (visitCode))
- (. gen newInstance ctype)
- (. gen dup)
- (. gen (loadArgs))
- (. gen (invokeConstructor ctype m))
- (. gen (returnValue))
- (. gen (endMethod))))))
-
- ;add methods matching supers', if no fn -> call super
- (let [mm (non-private-methods super)]
- (doseq #^java.lang.reflect.Method meth (vals mm)
- (emit-forwarding-method (.getName meth) (.getParameterTypes meth) (.getReturnType meth) false
- (fn [gen m]
- (. gen (loadThis))
- ;push args
- (. gen (loadArgs))
- ;call super
- (. gen (visitMethodInsn (. Opcodes INVOKESPECIAL)
- (. super-type (getInternalName))
- (. m (getName))
- (. m (getDescriptor)))))))
- ;add methods matching interfaces', if no fn -> throw
- (doseq #^Class iface interfaces
- (doseq #^java.lang.reflect.Method meth (. iface (getMethods))
- (when-not (contains? mm (method-sig meth))
- (emit-forwarding-method (.getName meth) (.getParameterTypes meth) (.getReturnType meth) false
- (fn [gen m]
- (. gen (throwException ex-type (. m (getName)))))))))
- ;extra methods
- (doseq [mname pclasses rclass :as msig] methods
- (emit-forwarding-method (str mname) pclasses rclass (:static ^msig)
- (fn [gen m]
- (. gen (throwException ex-type (. m (getName))))))))
-
- ;main
- (when main
- (let [m (. Method getMethod "void main (String[])")
- gen (new GeneratorAdapter (+ (. Opcodes ACC_PUBLIC) (. Opcodes ACC_STATIC))
- m nil nil cv)
- no-main-label (. gen newLabel)
- end-label (. gen newLabel)]
- (. gen (visitCode))
-
- (emit-get-var gen main-name)
- (. gen dup)
- (. gen ifNull no-main-label)
- (. gen loadArgs)
- (. gen (invokeStatic rt-type (. Method (getMethod "clojure.lang.ISeq seq(Object)"))))
- (. gen (invokeInterface ifn-type (new Method "applyTo" obj-type
- (into-array [iseq-type]))))
- (. gen pop)
- (. gen goTo end-label)
- ;no main found
- (. gen mark no-main-label)
- (. gen (throwException ex-type (str main-name " not defined")))
- (. gen mark end-label)
- (. gen (returnValue))
- (. gen (endMethod))))
- ;field exposers
- (doseq [f {getter :get setter :set}] exposes
- (let [fld (.getField super (str f))
- ftype (totype (.getType fld))]
- (when getter
- (let [m (new Method (str getter) ftype (to-types []))
- gen (new GeneratorAdapter (. Opcodes ACC_PUBLIC) m nil nil cv)]
- (. gen (visitCode))
- (. gen loadThis)
- (. gen getField ctype (str f) ftype)
- (. gen (returnValue))
- (. gen (endMethod))))
- (when setter
- (let [m (new Method (str setter) (. Type VOID_TYPE) (into-array [ftype]))
- gen (new GeneratorAdapter (. Opcodes ACC_PUBLIC) m nil nil cv)]
- (. gen (visitCode))
- (. gen loadThis)
- (. gen loadArgs)
- (. gen putField ctype (str f) ftype)
- (. gen (returnValue))
- (. gen (endMethod))))))
- ;finish class def
- (. cv (visitEnd))
- {:name name :bytecode (. cv (toByteArray))}))
-
-(defn gen-and-load-class
- "Generates and immediately loads the bytecode for the specified
- class. Note that a class generated this way can be loaded only once
- - the JVM supports only one class with a given name per
- classloader. Subsequent to generation you can import it into any
- desired namespaces just like any other class. See gen-class for a
- description of the options."
-
- [name & options]
- (let [{:keys [name bytecode]}
- (apply gen-class (str name) options)]
- (.. clojure.lang.RT ROOT_CLASSLOADER (defineClass (str name) bytecode))))
-
-(defn gen-and-save-class
- "Generates the bytecode for the named class and stores in a .class
- file in a subpath of the supplied path, the directories for which
- must already exist. See gen-class for a description of the options"
-
- [path name & options]
- (let [{:keys [name bytecode]} (apply gen-class (str name) options)
- file (java.io.File. path (str (. name replace \. (. java.io.File separatorChar)) ".class"))]
- (.createNewFile file)
- (with-open f (java.io.FileOutputStream. file)
- (.write f bytecode))))
-
-(comment
-;usage
-(gen-class
- package-qualified-name
- ;all below are optional
- :extends aclass
- :implements [interface ...]
- :constructors {[param-types] [super-param-types], }
- :methods [[name [param-types] return-type], ]
- :main boolean
- :factory name
- :state name
- :init name
- :exposes {protected-field {:get name :set name}, })
-
-(gen-and-load-class
-;(clojure/gen-and-save-class
-; "/Users/rich/Downloads"
- 'fred.lucy.Ethel
- :extends clojure.lang.Box ;APersistentMap
- :implements [clojure.lang.IPersistentMap]
- :state 'state
- ;:constructors {[Object] [Object]}
- ;:init 'init
- :main true
- :factory 'create
- :methods [#^{:static true} ['foo [Object] Object]
- ['bar [] Object]]
- :exposes {'val {:get 'getVal :set 'setVal}})
-
-(in-ns 'fred.lucy.Ethel)
-(clojure/refer 'clojure :exclude '(assoc seq count cons empty))
-(defn init [n] [[] n])
-(defn foo
- ([x] x))
-(defn main [x y] (println x y))
-(in-ns 'user)
-(def ethel (new fred.lucy.Ethel__2276 42))
-(def ethel (fred.lucy.Ethel__2276.create 21))
-(fred.lucy.Ethel__2276.main (into-array ["lucy" "ricky"]))
-(.state ethel)
-(.foo ethel 7)
-(.foo ethel)
-(.getVal ethel)
-(.setVal ethel 12)
-
-(gen-class org.clojure.MyComparator :implements [Comparator])
-(in-ns 'org.clojure.MyComparator)
-(defn compare [this x y] ...)
-
-(load-file "/Users/rich/dev/clojure/src/genclass.clj")
-
-(clojure/gen-and-save-class "/Users/rich/dev/clojure/gen/"
- 'org.clojure.ClojureServlet
- :extends javax.servlet.http.HttpServlet)
-
-)
diff --git a/src/inspector.clj b/src/inspector.clj
deleted file mode 100644
index ad0999de..00000000
--- a/src/inspector.clj
+++ /dev/null
@@ -1,110 +0,0 @@
-; Copyright (c) Rich Hickey. All rights reserved.
-; The use and distribution terms for this software are covered by the
-; Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
-; which can be found in the file CPL.TXT at the root of this distribution.
-; By using this software in any fashion, you are agreeing to be bound by
-; the terms of this license.
-; You must not remove this notice, or any other, from this software.
-
-(in-ns 'inspector)
-(clojure/refer 'clojure)
-
-(import '(javax.swing.tree TreeModel)
- '(javax.swing.table TableModel)
- '(javax.swing JTree JTable JScrollPane JFrame))
-
-(defn atom? [x]
- (not (instance? clojure.lang.IPersistentCollection x)))
-
-(defn collection-tag [x]
- (cond
- (instance? java.util.Map$Entry x) :entry
- (instance? clojure.lang.IPersistentMap x) :map
- (instance? java.util.Map x) :map
- (instance? clojure.lang.Sequential x) :seq
- :else :atom))
-
-(defmulti is-leaf collection-tag)
-(defmulti get-child (fn [parent index] (collection-tag parent)))
-(defmulti get-child-count collection-tag)
-
-(defmethod is-leaf :default [node]
- (atom? node))
-(defmethod get-child :default [parent index]
- (nth parent index))
-(defmethod get-child-count :default [parent]
- (count parent))
-
-(defmethod is-leaf :entry [e]
- (is-leaf (val e)))
-(defmethod get-child :entry [e index]
- (get-child (val e) index))
-(defmethod get-child-count :entry [e]
- (count (val e)))
-
-(defmethod is-leaf :map [m]
- false)
-(defmethod get-child :map [m index]
- (nth (seq m) index))
-
-(defn tree-model [data]
- (proxy [TreeModel] []
- (getRoot [] data)
- (addTreeModelListener [treeModelListener])
- (getChild [parent index]
- (get-child parent index))
- (getChildCount [parent]
- (get-child-count parent))
- (isLeaf [node]
- (is-leaf node))
- (valueForPathChanged [path newValue])
- (getIndexOfChild [parent child]
- -1)
- (removeTreeModelListener [treeModelListener])))
-
-
-(defn table-model [data]
- (let [row1 (first data)
- colcnt (count row1)
- cnt (count data)
- vals (if (instance? clojure.lang.IPersistentMap row1) vals identity)]
- (proxy [TableModel] []
- (addTableModelListener [tableModelListener])
- (getColumnClass [columnIndex] Object)
- (getColumnCount [] colcnt)
- (getColumnName [columnIndex]
- (if (instance? clojure.lang.IPersistentMap row1)
- (name (nth (keys row1) columnIndex))
- (str columnIndex)))
- (getRowCount [] cnt)
- (getValueAt [rowIndex columnIndex]
- (nth (vals (nth data rowIndex)) columnIndex))
- (isCellEditable [rowIndex columnIndex] false)
- (removeTableModelListener [tableModelListener]))))
-
-(defn inspect-tree
- "creates a graphical (Swing) inspector on the supplied hierarchical data"
- [data]
- (doto (new JFrame "Clojure Inspector")
- (add (new JScrollPane (new JTree (tree-model data))))
- (setSize 400 600)
- (setVisible true)))
-
-(defn inspect-table
- "creates a graphical (Swing) inspector on the supplied regular
- data, which must be a sequential data structure of data structures
- of equal length"
- [data]
- (doto (new JFrame "Clojure Inspector")
- (add (new JScrollPane (new JTable (table-model data))))
- (setSize 400 600)
- (setVisible true)))
-
-(comment
-
-(load-file "src/inspector.clj")
-(refer 'inspector)
-(inspect-tree {:a 1 :b 2 :c [1 2 3 {:d 4 :e 5 :f [6 7 8]}]})
-(inspect-table [[1 2 3][4 5 6][7 8 9][10 11 12]])
-
-) \ No newline at end of file
diff --git a/src/parallel.clj b/src/parallel.clj
deleted file mode 100644
index 80e92b81..00000000
--- a/src/parallel.clj
+++ /dev/null
@@ -1,248 +0,0 @@
-; Copyright (c) Rich Hickey. All rights reserved.
-; The use and distribution terms for this software are covered by the
-; Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
-; which can be found in the file CPL.TXT at the root of this distribution.
-; By using this software in any fashion, you are agreeing to be bound by
-; the terms of this license.
-; You must not remove this notice, or any other, from this software.
-
-(in-ns 'parallel)
-(clojure/refer 'clojure)
-
-(comment "
-The parallel library wraps the ForkJoin library scheduled for inclusion in JDK 7:
-
-http://gee.cs.oswego.edu/dl/concurrency-interest/index.html
-
-You'll need jsr166y.jar in your classpath in order to use this
-library. The basic idea is that Clojure collections, and most
-efficiently vectors, can be turned into parallel arrays for use by
-this library with the function par, although most of the functions
-take collections and will call par if needed, so normally you will
-only need to call par explicitly in order to attach bound/filter/map
-ops. Parallel arrays support the attachment of bounds, filters and
-mapping functions prior to realization/calculation, which happens as
-the result of any of several operations on the
-array (pvec/psort/pfilter-nils/pfilter-dupes). Rather than perform
-composite operations in steps, as would normally be done with
-sequences, maps and filters are instead attached and thus composed by
-providing ops to par. Note that there is an order sensitivity to the
-attachments - bounds precede filters precede mappings. All operations
-then happen in parallel, using multiple threads and a sophisticated
-work-stealing system supported by fork-join, either when the array is
-realized, or to perform aggregate operations like preduce/pmin/pmax
-etc. A parallel array can be realized into a Clojure vector using
-pvec.
-")
-
-(import '(jsr166y.forkjoin ParallelArray ParallelArrayWithBounds ParallelArrayWithFilter
- ParallelArrayWithMapping
- Ops$Op Ops$BinaryOp Ops$Reducer Ops$Predicate Ops$BinaryPredicate
- Ops$IntAndObjectPredicate Ops$IntAndObjectToObject))
-
-(defn- op [f]
- (proxy [Ops$Op] []
- (op [x] (f x))))
-
-(defn- binary-op [f]
- (proxy [Ops$BinaryOp] []
- (op [x y] (f x y))))
-
-(defn- int-and-object-to-object [f]
- (proxy [Ops$IntAndObjectToObject] []
- (op [i x] (f x i))))
-
-(defn- reducer [f]
- (proxy [Ops$Reducer] []
- (op [x y] (f x y))))
-
-(defn- predicate [f]
- (proxy [Ops$Predicate] []
- (op [x] (boolean (f x)))))
-
-(defn- binary-predicate [f]
- (proxy [Ops$BinaryPredicate] []
- (op [x y] (boolean (f x y)))))
-
-(defn- int-and-object-predicate [f]
- (proxy [Ops$IntAndObjectPredicate] []
- (op [i x] (boolean (f x i)))))
-
-(defn par
- "Creates a parallel array from coll. ops, if supplied, perform
- on-the-fly filtering or transformations during parallel realization
- or calculation. ops form a chain, and bounds must precede filters,
- must precede maps. ops must be a set of keyword value pairs of the
- following forms:
-
- :bound [start end]
-
- Only elements from start (inclusive) to end (exclusive) will be
- processed when the array is realized.
-
- :filter pred
-
- Filter preds remove elements from processing when the array is realized. pred
- must be a function of one argument whose return will be processed
- via boolean.
-
- :filter-index pred2
-
- pred2 must be a function of two arguments, which will be an element
- of the collection and the corresponding index, whose return will be
- processed via boolean.
-
- :filter-with [pred2 coll2]
-
- pred2 must be a function of two arguments, which will be
- corresponding elements of the 2 collections.
-
- :map f
-
- Map fns will be used to transform elements when the array is
- realized. f must be a function of one argument.
-
- :map-index f2
-
- f2 must be a function of two arguments, which will be an element of
- the collection and the corresponding index.
-
- :map-with [f2 coll2]
-
- f2 must be a function of two arguments, which will be corresponding
- elements of the 2 collections."
-
- ([coll]
- (if (instance? ParallelArrayWithMapping coll)
- coll
- (. ParallelArray createUsingHandoff
- (to-array coll)
- (. ParallelArray defaultExecutor))))
- ([coll & ops]
- (reduce (fn [pa [op args]]
- (cond
- (= op :bound) (. pa withBounds (args 0) (args 1))
- (= op :filter) (. pa withFilter (predicate args))
- (= op :filter-with) (. pa withFilter (binary-predicate (args 0)) (par (args 1)))
- (= op :filter-index) (. pa withIndexedFilter (int-and-object-predicate args))
- (= op :map) (. pa withMapping (parallel/op args))
- (= op :map-with) (. pa withMapping (binary-op (args 0)) (par (args 1)))
- (= op :map-index) (. pa withIndexedMapping (int-and-object-to-object args))
- :else (throw (Exception. (str "Unsupported par op: " op)))))
- (par coll)
- (partition 2 ops))))
-
-;;;;;;;;;;;;;;;;;;;;; aggregate operations ;;;;;;;;;;;;;;;;;;;;;;
-(defn pany
- "Returns some (random) element of the coll if it satisfies the bound/filter/map"
- [coll]
- (. (par coll) any))
-
-(defn pmax
- "Returns the maximum element, presuming Comparable elements, unless
- a Comparator comp is supplied"
- ([coll] (. (par coll) max))
- ([coll comp] (. (par coll) max comp)))
-
-(defn pmin
- "Returns the minimum element, presuming Comparable elements, unless
- a Comparator comp is supplied"
- ([coll] (. (par coll) min))
- ([coll comp] (. (par coll) min comp)))
-
-(defn- summary-map [s]
- {:min (.min s) :max (.max s) :size (.size s) :min-index (.indexOfMin s) :max-index (.indexOfMax s)})
-
-(defn psummary
- "Returns a map of summary statistics (min. max, size, min-index, max-index,
- presuming Comparable elements, unless a Comparator comp is supplied"
- ([coll] (summary-map (. (par coll) summary)))
- ([coll comp] (summary-map (. (par coll) summary comp))))
-
-(defn preduce
- "Returns the reduction of the realized elements of coll
- using function f. Note f will not necessarily be called
- consecutively, and so must be commutative. Also note that
- (f base an-element) might be performed many times, i.e. base is not
- an initial value as with sequential reduce."
- [f base coll]
- (. (par coll) (reduce (reducer f) base)))
-
-;;;;;;;;;;;;;;;;;;;;; collection-producing operations ;;;;;;;;;;;;;;;;;;;;;;
-
-(defn- pa-to-vec [pa]
- (vec (. pa getArray)))
-
-(defn- pall
- "Realizes a copy of the coll as a parallel array, with any bounds/filters/maps applied"
- [coll]
- (if (instance? ParallelArrayWithMapping coll)
- (. coll all)
- (par coll)))
-
-(defn pvec
- "Returns the realized contents of the parallel array pa as a Clojure vector"
- [pa] (pa-to-vec (pall pa)))
-
-(defn pdistinct
- "Returns a parallel array of the distinct elements of coll"
- [coll]
- (pa-to-vec (. (pall coll) allUniqueElements)))
-
-;this doesn't work, passes null to reducer?
-(defn- pcumulate [coll f init]
- (.. (pall coll) (precumulate (reducer f) init)))
-
-(defn psort
- "Returns a new vector consisting of the realized items in coll, sorted,
- presuming Comparable elements, unless a Comparator comp is supplied"
- ([coll] (pa-to-vec (. (pall coll) sort)))
- ([coll comp] (pa-to-vec (. (pall coll) sort comp))))
-
-(defn pfilter-nils
- "Returns a vector containing the non-nil (realized) elements of coll"
- [coll]
- (pa-to-vec (. (pall coll) removeNulls)))
-
-(defn pfilter-dupes
- "Returns a vector containing the (realized) elements of coll,
- without any consecutive duplicates"
- [coll]
- (pa-to-vec (. (pall coll) removeConsecutiveDuplicates)))
-
-
-(comment
-(load-file "src/parallel.clj")
-(refer 'parallel)
-(pdistinct [1 2 3 2 1])
-;(pcumulate [1 2 3 2 1] + 0) ;broken, not exposed
-(def a (make-array Object 1000000))
-(dotimes i (count a)
- (aset a i (rand-int i)))
-(time (reduce + 0 a))
-(time (preduce + 0 a))
-(time (count (distinct a)))
-(time (count (pdistinct a)))
-
-(preduce + 0 [1 2 3 2 1])
-(preduce + 0 (psort a))
-(pvec (par [11 2 3 2] :filter-index (fn [x i] (> i x))))
-(pvec (par [11 2 3 2] :filter-with [(fn [x y] (> y x)) [110 2 33 2]]))
-
-(psummary ;or pvec/pmax etc
- (par [11 2 3 2]
- :filter-with [(fn [x y] (> y x))
- [110 2 33 2]]
- :map #(* % 2)))
-
-(preduce + 0
- (par [11 2 3 2]
- :filter-with [< [110 2 33 2]]))
-
-(time (reduce + 0 (map #(* % %) (range 1000000))))
-(time (preduce + 0 (par (range 1000000) :map-index *)))
-(def v (range 1000000))
-(time (preduce + 0 (par v :map-index *)))
-(time (preduce + 0 (par v :map #(* % %))))
-(time (reduce + 0 (map #(* % %) v)))
-) \ No newline at end of file
diff --git a/src/proxy.clj b/src/proxy.clj
deleted file mode 100644
index f72111a4..00000000
--- a/src/proxy.clj
+++ /dev/null
@@ -1,307 +0,0 @@
-; Copyright (c) Rich Hickey. All rights reserved.
-; The use and distribution terms for this software are covered by the
-; Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
-; which can be found in the file CPL.TXT at the root of this distribution.
-; By using this software in any fashion, you are agreeing to be bound by
-; the terms of this license.
-; You must not remove this notice, or any other, from this software.
-
-(in-ns 'clojure)
-
-(import
- '(clojure.asm ClassWriter ClassVisitor Opcodes Type)
- '(java.lang.reflect Modifier Constructor)
- '(clojure.asm.commons Method GeneratorAdapter)
- '(clojure.lang IProxy Reflector DynamicClassLoader IPersistentMap PersistentHashMap RT))
-
-(def *proxy-classes* (ref {}))
-
-(defn method-sig [#^java.lang.reflect.Method meth]
- [(. meth (getName)) (seq (. meth (getParameterTypes))) (. meth getReturnType)])
-
-(defn get-proxy-class
- "Takes an optional single class followed by zero or more
- interfaces. If not supplied class defaults to Object. Creates an
- returns an instance of a proxy class derived from the supplied
- classes. The resulting value is cached and used for any subsequent
- requests for the same class set. Returns a Class object."
- [& bases]
- (let [bases (if (. (first bases) (isInterface))
- (cons Object bases)
- bases)
- [super & interfaces] bases]
- (or (get @*proxy-classes* bases)
- (let [cv (new ClassWriter (. ClassWriter COMPUTE_MAXS))
- cname (str "clojure/lang/" (gensym "Proxy__"))
- ctype (. Type (getObjectType cname))
- iname (fn [c] (.. Type (getType c) (getInternalName)))
- fmap "__clojureFnMap"
- totype (fn [c] (. Type (getType c)))
- to-types (fn [cs] (if (pos? (count cs))
- (into-array (map totype cs))
- (make-array Type 0)))
- super-type (totype super)
- map-type (totype PersistentHashMap)
- ifn-type (totype clojure.lang.IFn)
- obj-type (totype Object)
- sym-type (totype clojure.lang.Symbol)
- rt-type (totype clojure.lang.RT)
- ex-type (totype java.lang.UnsupportedOperationException)
- gen-method
- (fn [#^java.lang.reflect.Method meth else-gen]
- (let [pclasses (. meth (getParameterTypes))
- ptypes (to-types pclasses)
- rtype (totype (. meth (getReturnType)))
- m (new Method (. meth (getName)) rtype ptypes)
- gen (new GeneratorAdapter (. Opcodes ACC_PUBLIC) m nil nil cv)
- else-label (. gen (newLabel))
- end-label (. gen (newLabel))
- decl-type (. Type (getType (. meth (getDeclaringClass))))]
- (. gen (visitCode))
- (. gen (loadThis))
- (. gen (getField ctype fmap map-type))
- ;get symbol corresponding to name
- (. gen (push (. meth (getName))))
- (. gen (invokeStatic sym-type (. Method (getMethod "clojure.lang.Symbol create(String)"))))
- ;lookup fn in map
- (. gen (invokeStatic rt-type (. Method (getMethod "Object get(Object, Object)"))))
- (. gen (dup))
- (. gen (ifNull else-label))
- ;if found
- (. gen (loadThis))
- ;box args
- (dotimes i (count ptypes)
- (. gen (loadArg i))
- (. clojure.lang.Compiler$HostExpr (emitBoxReturn nil gen (nth pclasses i))))
- ;call fn
- (. gen (invokeInterface ifn-type (new Method "invoke" obj-type
- (into-array (cons obj-type
- (replicate (count ptypes) obj-type))))))
- ;unbox return
- (. gen (unbox rtype))
- (when (= (. rtype (getSort)) (. Type VOID))
- (. gen (pop)))
- (. gen (goTo end-label))
-
- ;else call supplied alternative generator
- (. gen (mark else-label))
- (. gen (pop))
-
- (else-gen gen m)
-
- (. gen (mark end-label))
- (. gen (returnValue))
- (. gen (endMethod))))]
-
- ;start class definition
- (. cv (visit (. Opcodes V1_5) (+ (. Opcodes ACC_PUBLIC) (. Opcodes ACC_SUPER))
- cname nil (iname super)
- (into-array (map iname (cons IProxy interfaces)))))
- ;add field for fn mappings
- (. cv (visitField (+ (. Opcodes ACC_PRIVATE) (. Opcodes ACC_VOLATILE))
- fmap (. map-type (getDescriptor)) nil nil))
- ;add ctors matching/calling super's
- (doseq #^Constructor ctor (. super (getDeclaredConstructors))
- (when-not (. Modifier (isPrivate (. ctor (getModifiers))))
- (let [ptypes (to-types (. ctor (getParameterTypes)))
- m (new Method "<init>" (. Type VOID_TYPE) ptypes)
- gen (new GeneratorAdapter (. Opcodes ACC_PUBLIC) m nil nil cv)]
- (. gen (visitCode))
- ;call super ctor
- (. gen (loadThis))
- (. gen (dup))
- (. gen (loadArgs))
- (. gen (invokeConstructor super-type m))
- ;init fmap
- (. gen (getStatic map-type "EMPTY" map-type))
- (. gen (putField ctype fmap map-type))
-
- (. gen (returnValue))
- (. gen (endMethod)))))
- ;add IProxy methods
- (let [m (. Method (getMethod "void __updateClojureFnMappings(clojure.lang.IPersistentMap)"))
- gen (new GeneratorAdapter (. Opcodes ACC_PUBLIC) m nil nil cv)]
- (. gen (visitCode))
- (. gen (loadThis))
- (. gen (dup))
- (. gen (getField ctype fmap map-type))
- (. gen (loadArgs))
- (. gen (invokeInterface (totype clojure.lang.IPersistentCollection)
- (. Method (getMethod "clojure.lang.IPersistentCollection cons(Object)"))))
- (. gen (checkCast map-type))
- (. gen (putField ctype fmap map-type))
-
- (. gen (returnValue))
- (. gen (endMethod)))
- (let [m (. Method (getMethod "clojure.lang.IPersistentMap __getClojureFnMappings()"))
- gen (new GeneratorAdapter (. Opcodes ACC_PUBLIC) m nil nil cv)]
- (. gen (visitCode))
- (. gen (loadThis))
- (. gen (getField ctype fmap map-type))
- (. gen (returnValue))
- (. gen (endMethod)))
-
- ;calc set of supers' non-private instance methods
- (let [mm (loop [mm {} considered #{} c super]
- (if c
- (let [[mm considered]
- (loop [mm mm
- considered considered
- meths (concat
- (seq (. c (getDeclaredMethods)))
- (seq (. c (getMethods))))]
- (if meths
- (let [#^java.lang.reflect.Method meth (first meths)
- mods (. meth (getModifiers))
- mk (method-sig meth)]
- (if (or (considered mk)
- (. Modifier (isPrivate mods))
- (. Modifier (isStatic mods))
- (. Modifier (isFinal mods))
- (= "finalize" (.getName meth)))
- (recur mm (conj considered mk) (rest meths))
- (recur (assoc mm mk meth) (conj considered mk) (rest meths))))
- [mm considered]))]
- (recur mm considered (. c (getSuperclass))))
- mm))]
- ;add methods matching supers', if no mapping -> call super
- (doseq #^java.lang.reflect.Method meth (vals mm)
- (gen-method meth
- (fn [gen m]
- (. gen (loadThis))
- ;push args
- (. gen (loadArgs))
- ;call super
- (. gen (visitMethodInsn (. Opcodes INVOKESPECIAL)
- (. super-type (getInternalName))
- (. m (getName))
- (. m (getDescriptor)))))))
-
- ;add methods matching interfaces', if no mapping -> throw
- (doseq #^Class iface interfaces
- (doseq #^java.lang.reflect.Method meth (. iface (getMethods))
- (when-not (contains? mm (method-sig meth))
- (gen-method meth
- (fn [gen m]
- (. gen (throwException ex-type (. m (getName))))))))))
-
- ;finish class def
- (. cv (visitEnd))
- ;generate, cache and return class object
- (let [loader (. RT ROOT_CLASSLOADER)
- c (. loader (defineClass (. cname (replace "/" "."))
- (. cv (toByteArray))))]
- (sync nil (commute *proxy-classes* assoc bases c))
- c)))))
-
-(defn construct-proxy
- "Takes a proxy class and any arguments for its superclass ctor and
- creates and returns an instance of the proxy."
- [c & ctor-args]
- (. Reflector (invokeConstructor c (to-array ctor-args))))
-
-(defn update-proxy
- "Takes a proxy instance and a map of symbols (whose names must
- correspond to methods of the proxy superclass/superinterfaces) to
- fns (which must take arguments matching the corresponding method,
- plus an additional (explicit) first arg corresponding to this, and
- updates (via assoc) the proxy's fn map. nil can be passed instead of
- a fn, in which case the corresponding method will revert to the
- default behavior. Note that this function can be used to update the
- behavior of an existing instance without changing its identity."
- [#^IProxy proxy mappings]
- (. proxy (__updateClojureFnMappings mappings)))
-
-(defn proxy-mappings
- "Takes a proxy instance and returns the proxy's fn map."
- [#^IProxy proxy]
- (. proxy (__getClojureFnMappings)))
-
-(defmacro proxy
- "class-and-interfaces - a vector of class names
-
- args - a (possibly empty) vector of arguments to the superclass
- constructor.
-
- f => (name [params*] body) or
- (name ([params*] body) ([params+] body) ...)
-
- Expands to code which creates a instance of a proxy class that
- implements the named class/interface(s) by calling the supplied
- fns. A single class, if provided, must be first. If not provided it
- defaults to Object.
-
- The interfaces names must be valid interface types. If a method fn
- is not provided for a class method, the superclass methd will be
- called. If a method fn is not provided for an interface method, an
- UnsupportedOperationException will be thrown should it be
- called. Method fns are closures and can capture the environment in
- which proxy is called. Each method fn takes an additional implicit
- first arg, which is bound to 'this. Note that while method fns can
- be provided to override protected methods, they have no other access
- to protected members, nor to super, as these capabilities cannot be
- proxied."
- [class-and-interfaces args & fs]
- `(let [pc# (get-proxy-class ~@class-and-interfaces)
- p# (construct-proxy pc# ~@args)]
- (update-proxy p#
- ~(loop [fmap {} fs fs]
- (if fs
- (let [[sym & meths] (first fs)
- meths (if (vector? (first meths))
- (list meths)
- meths)
- meths (map (fn [[params & body]]
- (cons (apply vector 'this params) body))
- meths)]
- (recur (assoc fmap (list `quote (symbol (name sym))) (cons `fn meths)) (rest fs)))
- fmap)))
- p#))
-
-(defn proxy-call-with-super [call this meth]
- (let [m (proxy-mappings this)]
- (update-proxy this (assoc m meth nil))
- (let [ret (call)]
- (update-proxy this m)
- ret)))
-
-(defmacro proxy-super
- "Use to call a superclass method in the body of a proxy method.
- Note, expansion captures 'this"
- [meth & args]
- `(proxy-call-with-super (fn [] (. ~'this ~meth ~@args)) ~'this '~(symbol (name meth))))
-
-(defn bean
- "Takes a Java object and returns a read-only implementation of the
- map abstraction based upon its JavaBean properties."
- [#^Object x]
- (let [c (. x (getClass))
- pmap (reduce (fn [m #^java.beans.PropertyDescriptor pd]
- (let [name (. pd (getName))
- method (. pd (getReadMethod))]
- (if (and method (zero? (alength (. method (getParameterTypes)))))
- (assoc m (keyword name) (fn [] (. method (invoke x nil))))
- m)))
- {}
- (seq (.. java.beans.Introspector
- (getBeanInfo c)
- (getPropertyDescriptors))))
- v (fn [k] ((pmap k)))
- snapshot (fn []
- (reduce (fn [m e]
- (assoc m (key e) ((val e))))
- {} (seq pmap)))]
- (proxy [clojure.lang.APersistentMap]
- []
- (containsKey [k] (contains? pmap k))
- (entryAt [k] (when (contains? pmap k) (new clojure.lang.MapEntry k (v k))))
- (valAt ([k] (v k))
- ([k default] (if (contains? pmap k) (v k) default)))
- (cons [m] (conj (snapshot) m))
- (count [] (count pmap))
- (assoc [k v] (assoc (snapshot) k v))
- (without [k] (dissoc (snapshot) k))
- (seq [] ((fn thisfn [pseq]
- (when pseq
- (lazy-cons (new clojure.lang.MapEntry (first pseq) (v (first pseq)))
- (thisfn (rest pseq))))) (keys pmap))))))
diff --git a/src/set.clj b/src/set.clj
deleted file mode 100644
index e5e34cc0..00000000
--- a/src/set.clj
+++ /dev/null
@@ -1,116 +0,0 @@
-; Copyright (c) Rich Hickey. All rights reserved.
-; The use and distribution terms for this software are covered by the
-; Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
-; which can be found in the file CPL.TXT at the root of this distribution.
-; By using this software in any fashion, you are agreeing to be bound by
-; the terms of this license.
-; You must not remove this notice, or any other, from this software.
-
-(in-ns 'set)
-(clojure/refer 'clojure)
-
-(defn union
- "Returns a set that is the union of the two sets."
- [xset yset]
- (reduce conj xset yset))
-
-(defn difference
- "Returns a set that is xset without the elements of yset."
- [xset yset]
- (reduce disj xset yset))
-
-(defn intersection
- "Returns a set of the elements present in both xset and yset."
- [xset yset]
- (difference xset (difference xset yset)))
-
-(defn select
- "Returns a set of the elements for which pred is true"
- [pred xset]
- (reduce (fn [s k] (if (pred k) s (disj s k)))
- xset xset))
-
-(defn project
- "Returns a rel of the elements of xrel with only the keys in ks"
- [xrel ks]
- (set (map #(select-keys % ks) xrel)))
-
-(defn rename-keys
- "Returns the map with the keys in kmap renamed to the vals in kmap"
- [map kmap]
- (reduce
- (fn [m [old new]]
- (if (not= old new)
- (-> m (assoc new (m old)) (dissoc old))
- m))
- map kmap))
-
-(defn rename
- "Returns a rel of the maps in xrel with the keys in kmap renamed to the vals in kmap"
- [xrel kmap]
- (set (map #(rename-keys % kmap) xrel)))
-
-(defn index
- "Returns a map of the distinct values of ks in the xrel mapped to a
- set of the maps in xrel with the corresponding values of ks."
- [xrel ks]
- (reduce
- (fn [m x]
- (let [ik (select-keys x ks)]
- (assoc m ik (conj (get m ik #{}) x))))
- {} xrel))
-
-(defn map-invert
- "Returns the map with the vals mapped to the keys."
- [m] (reduce (fn [m [k v]] (assoc m v k)) {} m))
-
-(defn join
- "When passed 2 rels, returns the rel corresponding to the natural
- join. When passed an additional keymap, joins on the corresponding
- keys."
- ([xrel yrel] ;natural join
- (if (and (seq xrel) (seq yrel))
- (let [ks (intersection (set (keys (first xrel))) (set (keys (first yrel))))
- [r s] (if (<= (count xrel) (count yrel))
- [xrel yrel]
- [yrel xrel])
- idx (index r ks)]
- (reduce (fn [ret x]
- (let [found (idx (select-keys x ks))]
- (if found
- (reduce #(conj %1 (merge %2 x)) ret found)
- ret)))
- #{} s))
- #{}))
- ([xrel yrel km] ;arbitrary key mapping
- (let [[r s k] (if (<= (count xrel) (count yrel))
- [xrel yrel (map-invert km)]
- [yrel xrel km])
- idx (index r (vals k))]
- (reduce (fn [ret x]
- (let [found (idx (rename-keys (select-keys x (keys k)) k))]
- (if found
- (reduce #(conj %1 (merge %2 x)) ret found)
- ret)))
- #{} s))))
-
-(comment
-(refer 'set)
-(def xs #{{:a 11 :b 1 :c 1 :d 4}
- {:a 2 :b 12 :c 2 :d 6}
- {:a 3 :b 3 :c 3 :d 8 :f 42}})
-
-(def ys #{{:a 11 :b 11 :c 11 :e 5}
- {:a 12 :b 11 :c 12 :e 3}
- {:a 3 :b 3 :c 3 :e 7 }})
-
-(join xs ys)
-(join xs (rename ys {:b :yb :c :yc}) {:a :a})
-
-(union #{:a :b :c} #{:c :d :e })
-(difference #{:a :b :c} #{:c :d :e})
-(intersection #{:a :b :c} #{:c :d :e})
-
-(index ys [:b])
-)
-
diff --git a/src/xml.clj b/src/xml.clj
deleted file mode 100644
index 7ad8198c..00000000
--- a/src/xml.clj
+++ /dev/null
@@ -1,117 +0,0 @@
-; Copyright (c) Rich Hickey. All rights reserved.
-; The use and distribution terms for this software are covered by the
-; Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
-; which can be found in the file CPL.TXT at the root of this distribution.
-; By using this software in any fashion, you are agreeing to be bound by
-; the terms of this license.
-; You must not remove this notice, or any other, from this software.
-
-(in-ns 'xml)
-(clojure/refer 'clojure)
-
-(import '(org.xml.sax ContentHandler Attributes SAXException)
- '(javax.xml.parsers SAXParser SAXParserFactory))
-
-(def *stack*)
-(def *current*)
-(def *state*) ; :element :chars :between
-(def *sb*)
-
-(defstruct element :tag :attrs :content)
-
-(def tag (accessor element :tag))
-(def attrs (accessor element :attrs))
-(def content (accessor element :content))
-
-(def content-handler
- (let [push-content (fn [e c]
- (assoc e :content (conj (or (:content e) []) c)))
- push-chars (fn []
- (when (and (= *state* :chars)
- (some (complement #(. Character (isWhitespace %))) (str *sb*)))
- (set! *current* (push-content *current* (str *sb*)))))]
- (new clojure.lang.XMLHandler
- (proxy [ContentHandler] []
- (startElement [uri local-name q-name #^Attributes atts]
- (let [attrs (fn [ret i]
- (if (neg? i)
- ret
- (recur (assoc ret
- (. clojure.lang.Keyword (intern (symbol (. atts (getQName i)))))
- (. atts (getValue i)))
- (dec i))))
- e (struct element
- (. clojure.lang.Keyword (intern (symbol q-name)))
- (when (pos? (. atts (getLength)))
- (attrs {} (dec (. atts (getLength))))))]
- (push-chars)
- (set! *stack* (conj *stack* *current*))
- (set! *current* e)
- (set! *state* :element))
- nil)
- (endElement [uri local-name q-name]
- (push-chars)
- (set! *current* (push-content (peek *stack*) *current*))
- (set! *stack* (pop *stack*))
- (set! *state* :between)
- nil)
- (characters [ch start length]
- (when-not (= *state* :chars)
- (set! *sb* (new StringBuilder)))
- (let [#^StringBuilder sb *sb*]
- (. sb (append ch start length))
- (set! *state* :chars))
- nil)
- (setDocumentLocator [locator])
- (startDocument [])
- (endDocument [])
- (startPrefixMapping [prefix uri])
- (endPrefixMapping [prefix])
- (ignorableWhitespace [ch start length])
- (processingInstruction [target data])
- (skippedEntity [name])
- ))))
-
-(defn startparse-sax [s ch]
- (.. SAXParserFactory (newInstance) (newSAXParser) (parse s ch)))
-
-(defn parse
- "Parses and loads the source s, which can be a File, InputStream or
- String naming a URI. Returns a tree of the xml/element struct-map,
- which has the keys :tag, :attrs, and :content. and accessor fns tag,
- attrs, and content. Other parsers can be supplied by passing
- startparse, a fn taking a source and a ContentHandler and returning
- a parser"
- ([s] (parse s startparse-sax))
- ([s startparse]
- (binding [*stack* nil
- *current* (struct element)
- *state* :between
- *sb* nil]
- (startparse s content-handler)
- ((:content *current*) 0))))
-
-(defn emit-element [e]
- (if (instance? String e)
- (println e)
- (do
- (print (str "<" (name (:tag e))))
- (when (:attrs e)
- (doseq attr (:attrs e)
- (print (str " " (name (key attr)) "='" (val attr)"'"))))
- (if (:content e)
- (do
- (println ">")
- (doseq c (:content e)
- (emit-element c))
- (println (str "</" (name (:tag e)) ">")))
- (println "/>")))))
-
-(defn emit [x]
- (println "<?xml version='1.0' encoding='UTF-8'?>")
- (emit-element x))
-
-;(export '(tag attrs content parse element emit emit-element))
-
-;(load-file "/Users/rich/dev/clojure/src/xml.clj")
-;(def x (xml/parse "http://arstechnica.com/journals.rssx"))
diff --git a/src/zip.clj b/src/zip.clj
deleted file mode 100644
index e6794e73..00000000
--- a/src/zip.clj
+++ /dev/null
@@ -1,248 +0,0 @@
-; Copyright (c) Rich Hickey. All rights reserved.
-; The use and distribution terms for this software are covered by the
-; Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
-; which can be found in the file CPL.TXT at the root of this distribution.
-; By using this software in any fashion, you are agreeing to be bound by
-; the terms of this license.
-; You must not remove this notice, or any other, from this software.
-
-;functional hierarchical zipper, with navigation, editing and enumeration
-;see Huet
-
-(in-ns 'zip)
-(clojure/refer 'clojure :exclude '(replace))
-
-(defn zipper
- "Creates a new zipper structure.
-
- branch? is a fn that, given a node, returns true if can have
- children, even if it currently doesn't.
-
- children is a fn that, given a branch node, returns a seq of its
- children.
-
- make-node is a fn that, given an existing node and a seq of
- children, returns a new branch node with the supplied children.
- root is the root node."
- [branch? children make-node root]
- #^{:zip/branch? branch? :zip/children children :zip/make-node make-node}
- [root nil])
-
-(defn seq-zip
- "Returns a zipper for nested sequences, given a root sequence"
- [root]
- (zipper seq? identity (fn [node children] children) root))
-
-(defn vector-zip
- "Returns a zipper for nested vectors, given a root vector"
- [root]
- (zipper vector? seq (fn [node children] (apply vector children)) root))
-
-(defn xml-zip
- "Returns a zipper for xml elements (as from xml/parse),
- given a root element"
- [root]
- (zipper (complement string?)
- (comp seq :content)
- (fn [node children]
- (assoc node :content (and children (apply vector children))))
- root))
-
-(defn node
- "Returns the node at loc"
- [loc] (loc 0))
-
-(defn branch?
- "Returns true if the node at loc is a branch"
- [loc]
- ((:zip/branch? ^loc) (node loc)))
-
-(defn children
- "Returns a seq of the children of node at loc, which must be a branch"
- [loc]
- ((:zip/children ^loc) (node loc)))
-
-(defn make-node
- "Returns a new branch node, given an existing node and new
- children. The loc is only used to supply the constructor."
- [loc node children]
- ((:zip/make-node ^loc) node children))
-
-(defn path
- "Returns a seq of nodes leading to this loc"
- [loc]
- (:pnodes (loc 1)))
-
-(defn lefts
- "Returns a seq of the left siblings of this loc"
- [loc]
- (seq (:l (loc 1))))
-
-(defn rights
- "Returns a seq of the right siblings of this loc"
- [loc]
- (:r (loc 1)))
-
-
-(defn down
- "Returns the loc of the leftmost child of the node at this loc, or
- nil if no children"
- [loc]
- (let [[node path] loc
- [c & crest :as cs] (children loc)]
- (when cs
- (with-meta [c {:l []
- :pnodes (if path (conj (:pnodes path) node) [node])
- :ppath path
- :r crest}] ^loc))))
-
-(defn up
- "Returns the loc of the parent of the node at this loc, or nil if at
- the top"
- [loc]
- (let [[node {l :l, ppath :ppath, pnodes :pnodes r :r, changed? :changed?, :as path}] loc]
- (when path
- (let [pnode (peek pnodes)]
- (with-meta (if changed?
- [(make-node loc pnode (concat l (cons node r)))
- (and ppath (assoc ppath :changed? true))]
- [pnode ppath])
- ^loc)))))
-
-(defn root
- "zips all the way up and returns the root node, reflecting any
- changes."
- [loc]
- (if (= :end (loc 1))
- (node loc)
- (let [p (up loc)]
- (if p
- (recur p)
- (node loc)))))
-
-(defn right
- "Returns the loc of the right sibling of the node at this loc, or nil"
- [loc]
- (let [[node {l :l [r & rrest :as rs] :r :as path}] loc]
- (when (and path rs)
- (with-meta [r (assoc path :l (conj l node) :r rrest)] ^loc))))
-
-(defn left
- "Returns the loc of the left sibling of the node at this loc, or nil"
- [loc]
- (let [[node {l :l r :r :as path}] loc]
- (when (and path (seq l))
- (with-meta [(peek l) (assoc path :l (pop l) :r (cons node r))] ^loc))))
-
-(defn insert-left
- "Inserts the item as the left sibling of the node at this loc,
- without moving"
- [loc item]
- (let [[node {l :l :as path}] loc]
- (if (nil? path)
- (throw (new Exception "Insert at top"))
- (with-meta [node (assoc path :l (conj l item) :changed? true)] ^loc))))
-
-(defn insert-right
- "Inserts the item as the right sibling of the node at this loc,
- without moving"
- [loc item]
- (let [[node {r :r :as path}] loc]
- (if (nil? path)
- (throw (new Exception "Insert at top"))
- (with-meta [node (assoc path :r (cons item r) :changed? true)] ^loc))))
-
-(defn replace
- "Replaces the node at this loc, without moving"
- [loc node]
- (let [[_ path] loc]
- (with-meta [node (assoc path :changed? true)] ^loc)))
-
-(defn edit
- "Replaces the node at this loc with the value of (f node args)"
- [loc f & args]
- (replace loc (apply f (node loc) args)))
-
-(defn insert-child
- "Inserts the item as the leftmost child of the node at this loc,
- without moving"
- [loc item]
- (replace loc (make-node loc (node loc) (cons item (children loc)))))
-
-(defn append-child
- "Inserts the item as the rightmost child of the node at this loc,
- without moving"
- [loc item]
- (replace loc (make-node loc (node loc) (concat (children loc) [item]))))
-
-(defn next
- "Moves to the next loc in the hierarchy, depth-first. When reaching
- the end, returns a distinguished loc detectable via end?. If already
- at the end, stays there."
- [loc]
- (if (= :end (loc 1))
- loc
- (or
- (and (branch? loc) (down loc))
- (right loc)
- (loop [p loc]
- (if (up p)
- (or (right (up p)) (recur (up p)))
- [(node p) :end])))))
-
-(defn end?
- "Returns true if loc represents the end of a depth-first walk"
- [loc]
- (= :end (loc 1)))
-
-(defn remove
- "Removes the node at loc, returning the loc that would have preceded
- it in a depth-first walk."
- [loc]
- (let [[node {l :l, ppath :ppath, pnodes :pnodes, rs :r, :as path}] loc]
- (if (nil? path)
- (throw (new Exception "Remove at top"))
- (if (pos? (count l))
- (with-meta [(peek l) (assoc path :l (pop l) :changed? true)] ^loc)
- (with-meta [(make-node loc (peek pnodes) rs)
- (and ppath (assoc ppath :changed? true))]
- ^loc)))))
-
-(comment
-
-(load-file "/Users/rich/dev/clojure/src/zip.clj")
-(refer 'zip)
-(def data '[[a * b] + [c * d]])
-(def dz (vector-zip data))
-
-(right (down (right (right (down dz)))))
-(lefts (right (down (right (right (down dz))))))
-(rights (right (down (right (right (down dz))))))
-(up (up (right (down (right (right (down dz)))))))
-(path (right (down (right (right (down dz))))))
-
-(-> dz down right right down right)
-(-> dz down right right down right (replace '/) root)
-(-> dz next next (edit str) next next next (replace '/) root)
-(-> dz next next next next next next next next next remove root)
-(-> dz next next next next next next next next next remove (insert-right 'e) root)
-(-> dz next next next next next next next next next remove up (append-child 'e) root)
-
-(end? (-> dz next next next next next next next next next remove next))
-
-(-> dz next remove next remove root)
-
-(loop [loc dz]
- (if (end? loc)
- (root loc)
- (recur (next (if (= '* (node loc))
- (replace loc '/)
- loc)))))
-
-(loop [loc dz]
- (if (end? loc)
- (root loc)
- (recur (next (if (= '* (node loc))
- (remove loc)
- loc)))))
-)