diff options
author | scgilardi <scgilardi@gmail.com> | 2008-08-16 23:08:30 +0000 |
---|---|---|
committer | scgilardi <scgilardi@gmail.com> | 2008-08-16 23:08:30 +0000 |
commit | 881815127c98c4c38d8f78a0fd3cd5e1ab72b1af (patch) | |
tree | 1d398f0e03698714116dc6b5ac2d251644bb6429 | |
parent | 818e0f3182ef69c35e510c144256deebddaf1de6 (diff) |
add Revisions log and remove obsolete top level libs
-rw-r--r-- | Revisions | 7 | ||||
-rw-r--r-- | def.clj | 74 | ||||
-rw-r--r-- | duck-streams.clj | 120 | ||||
-rw-r--r-- | enum.clj | 47 | ||||
-rw-r--r-- | except.clj | 44 | ||||
-rw-r--r-- | fcase.clj | 93 | ||||
-rw-r--r-- | import-static.clj | 60 | ||||
-rw-r--r-- | javalog.clj | 98 | ||||
-rw-r--r-- | lazy-seqs.clj | 90 | ||||
-rw-r--r-- | lib.clj | 351 | ||||
-rw-r--r-- | memoize.clj | 32 | ||||
-rw-r--r-- | ns-utils.clj | 88 | ||||
-rw-r--r-- | pred.clj | 108 | ||||
-rw-r--r-- | seq-utils.clj | 54 | ||||
-rw-r--r-- | sql.clj | 126 | ||||
-rw-r--r-- | str-utils.clj | 44 | ||||
-rw-r--r-- | string.clj | 29 | ||||
-rw-r--r-- | test-is.clj | 211 | ||||
-rw-r--r-- | trace.clj | 55 |
19 files changed, 7 insertions, 1724 deletions
diff --git a/Revisions b/Revisions new file mode 100644 index 00000000..65f2cf00 --- /dev/null +++ b/Revisions @@ -0,0 +1,7 @@ +2008-08-16 All namespace-directory-aware libs have been moved to +src/clojure/contrib. Please udpate your clojure classpaths accordingly. + +2008-08-16 Revision 134 is the last to contain +non-namespace-directory-aware libs at the top level of this repository. At +the time of this writing, Clojure's SVN version is 1001. + diff --git a/def.clj b/def.clj deleted file mode 100644 index 367d1fda..00000000 --- a/def.clj +++ /dev/null @@ -1,74 +0,0 @@ -;; Copyright (c) Stephen C. Gilardi. 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. -;; -;; File: def.clj -;; -;; def.clj provides variants of def that make including doc strings and -;; making private definitions more succinct. -;; -;; scgilardi (gmail) -;; 17 May 2008 - -(clojure/in-ns 'def) -(clojure/refer 'clojure) - -(defmacro init-once - "Initializes a var exactly once. The var must already exist." - [var init] - `(let [v# (resolve '~var)] - (when-not (.isBound v#) - (.bindRoot v# ~init)))) - -(defmacro defvar - "Defines a var with an optional intializer and doc string" - ([name] - (list `def name)) - ([name init] - (list `def name init)) - ([name init doc] - (list `def (with-meta name (assoc (meta name) :doc doc)) init))) - -(defmacro defunbound - "Defines an unbound var with optional doc string" - ([name] - (list `def name)) - ([name doc] - (list `def (with-meta name (assoc (meta name) :doc doc))))) - -(defmacro defmacro- - "Same as defmacro but yields a private definition" - [name & decls] - (list* `defmacro (with-meta name (assoc (meta name) :private true)) decls)) - -(defmacro defvar- - "Same as defvar but yields a private definition" - [name & decls] - (list* `defvar (with-meta name (assoc (meta name) :private true)) decls)) - -(defmacro defunbound- - "Same as defunbound but yields a private definition" - [name & decls] - (list* `defunbound (with-meta name (assoc (meta name) :private true)) decls)) - -(defmacro defstruct- - "Same as defstruct but yields a private definition" - [name & decls] - (list* `defstruct (with-meta name (assoc (meta name) :private true)) decls)) - -(defmacro defalias - "Defines an alias for a var: a new var with the same value and metadata - as another with the exception of :namespace, :name, :file, :line, and - optionally :doc which are those of new var." - ([name orig] - `(let [v# (def ~name ~orig)] - (. v# (setMeta (merge (meta #'~orig) (meta #'~name)))) - v#)) - ([name orig doc] - `(let [v# (def ~name ~orig)] - (. v# (setMeta (merge (meta #'~orig) (assoc (meta #'~name) :doc ~doc)))) - v#))) diff --git a/duck-streams.clj b/duck-streams.clj deleted file mode 100644 index 5c6cba09..00000000 --- a/duck-streams.clj +++ /dev/null @@ -1,120 +0,0 @@ -;;; duck-streams.clj -- duck-typed I/O streams for Clojure - -;; by Stuart Sierra <mail@stuartsierra.com> -;; April 8, 2008 - -;; Copyright (c) 2008 Stuart Sierra. All rights reserved. The use and -;; distribution terms for this software are covered by the Common -;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.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. - - -;; This file defines "duck-typed" I/O utility functions for Clojure. -;; The 'reader' and 'writer' functions will open and return an -;; instance of java.io.BufferedReader and java.io.PrintWriter, -;; respectively, for a variety of argument types -- filenames as -;; strings, URLs, java.io.File's, etc. These functions are not very -;; efficient, because they have to perform a number of 'instance?' -;; checks, but they are convenient when you just want to open a file -;; and don't want to deal with all the Java I/O classes. -;; -;; This file also defines two convenience functions, 'spit' (opposite -;; of 'slurp') and 'write-lines' (opposite of 'line-seq'). - - -(clojure/in-ns 'duck-streams) -(clojure/refer 'clojure) - -(import '(java.io Reader InputStream InputStreamReader FileReader - BufferedReader File PrintWriter OutputStream - OutputStreamWriter BufferedWriter Writer FileWriter) - '(java.net URI URL MalformedURLException)) - -(defmacro bufr - {:private true} - [reader] - `(new java.io.BufferedReader ~reader)) - -(defn reader - "Attempts to coerce its argument into an open - java.io.BufferedReader. Argument may be an instance of Reader, - BufferedReader, InputStream, File, URI, URL, or String. - - If argument is a String, it tries to resolve it first as a URI, then - as a local file name. URIs with a 'file' protocol are converted to - local file names. - - Should be used inside with-open to ensure the Reader is properly - closed." - [x] - (cond - (instance? BufferedReader x) x - (instance? Reader x) (bufr x) - (instance? InputStream x) (bufr (new InputStreamReader x)) - (instance? File x) (bufr (new FileReader #^File x)) - (instance? URL x) (if (= (. #^URL x (getProtocol)) "file") - (bufr (new FileReader (. #^URL x (getPath)))) - (bufr (new InputStreamReader (. #^URL x (openStream))))) - (instance? URI x) (reader (. #^URI x (toURL))) - (instance? String x) (try (let [url (new URL x)] - (reader url)) - (catch MalformedURLException err - (bufr (new FileReader #^String x)))) - :else (throw (new Exception (str "Cannot coerce " (class x) - " into a Reader."))))) - -(defmacro bufw - {:private true} - [writer] - `(new java.io.PrintWriter (new java.io.BufferedWriter ~writer))) - -(defn writer - "Attempts to coerce its argument into an open java.io.PrintWriter - wrapped around a java.io.BufferedWriter. Argument may be an - instance of Writer, PrintWriter, BufferedWriter, OutputStream, File, - URI, URL, or String. - - If argument is a String, it tries to resolve it first as a URI, then - as a local file name. URIs with a 'file' protocol are converted to - local file names. - - Should be used inside with-open to ensure the Writer is properly - closed." - [x] - (cond - (instance? PrintWriter x) x - (instance? BufferedWriter x) (new PrintWriter #^BufferedWriter x) - (instance? Writer x) (bufw x) ; includes FileWriter - (instance? OutputStream x) (bufw (new OutputStreamWriter x)) - (instance? File x) (bufw (new FileWriter #^File x)) - (instance? URL x) (if (= (. #^URL x (getProtocol)) "file") - (bufw (new FileWriter (. #^URL x (getPath)))) - (throw (new Exception (str "Cannot write to non-file URL <" x ">.")))) - (instance? URI x) (writer (. #^URI x (toURL))) - (instance? String x) (try (let [url (new URL x)] - (writer url)) - (catch MalformedURLException err - (bufw (new FileWriter #^String x)))) - :else (throw (new Exception (str "Cannot coerce " (class x) - " into a Writer."))))) - -(defn write-lines - "Opposite of 'line-seq'. Writes lines (a seq) to writer (an open - java.io.PrintWriter), separated by newlines." - [#^PrintWriter writer lines] - (let [line (first lines)] - (when line - (. writer (write (str line))) - (. writer (println)) - (recur writer (rest lines))))) - -(defn spit - "Opposite of 'slurp'. Writes 'contents' to the file named by - 'filename'." - [filename contents] - (with-open w (#^PrintWriter writer filename) - (. w (print contents)))) - diff --git a/enum.clj b/enum.clj deleted file mode 100644 index f8aa5dc4..00000000 --- a/enum.clj +++ /dev/null @@ -1,47 +0,0 @@ -;;; enum.clj -- Java enum classes in Clojure - -;; by Stuart Sierra, http://www.stuartsierra.com/ -;; May 29, 2008 - -;; Copyright (c) 2008 Stuart Sierra. All rights reserved. The use and -;; distribution terms for this software are covered by the Common -;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.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. - - -;; This file helps define Java Enums, introduced in Java 1.5. Use it -;; when you need to define an enum to pass to a Java method. -;; -;; This file depends on genclass.clj in the Clojure distribution. - - -(clojure/in-ns 'enum) -(clojure/refer 'clojure) - -(defmacro defenum - "Generates and loads a subclass of java.lang.Enum, then - defs symbols as enumerated instances of that class. - - Example: (defenum my.package.MyEnum FOO BAR) - ;; FOO and BAR are now instances of MyEnum - - Java equivalent: enum MyEnum { FOO, BAR }; - - Caveats: - 1. The generated class has no values() method. - 2. The generated class returns false for Class.isEnum(). - 3. Enum.valueOf(Class, String) will not work. - 4. Redefining an enum is allowed, but enumeration resets - to zero." - [class & symbols] - ;; Can't load a class twice, so check first: - (try (. Class (forName (str class))) - (catch java.lang.ClassNotFoundException e - (gen-and-load-class (str class) :extends java.lang.Enum))) - (cons 'do - (map (fn [sym val] - `(def ~sym (new ~class ~(str sym) ~val))) - symbols (iterate inc 0)))) diff --git a/except.clj b/except.clj deleted file mode 100644 index e89246cb..00000000 --- a/except.clj +++ /dev/null @@ -1,44 +0,0 @@ -;; Copyright (c) Stephen C. Gilardi. 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. -;; -;; except.clj -;; -;; scgilardi (gmail) -;; Created 07 July 2008 - -(clojure/in-ns 'except) -(clojure/refer 'clojure) - -(lib/use string) - -(defn throw-if - "Throws an exception with a message if pred is true. Arguments are: - - pred class? format format-args* - - class is optional and defaults to Exception. If present, it must be a - Class in the tree under Throwable with a constructor that takes a single - String. - - format is a string as documented for java.util.Formatter. - - format-args are zero or more objects that correspond to the format - specifiers in format." - [pred & args] - (if pred - (let [class-present (instance? Class (first args)) - args (if class-present args (cons Exception args)) - [class fmt & fmt-args] args - ctor (.getConstructor (identity class) (into-array [String])) - message (apply format fmt fmt-args) - exception (.newInstance ctor (into-array [message])) - raw-trace (.getStackTrace exception) - boring? #(not= (.getMethodName %) "doInvoke") - trace (into-array (drop 2 (drop-while boring? raw-trace)))] - (.setStackTrace exception trace) - (throw exception)))) diff --git a/fcase.clj b/fcase.clj deleted file mode 100644 index 77018f1a..00000000 --- a/fcase.clj +++ /dev/null @@ -1,93 +0,0 @@ -;;; fcase.clj -- simple variants of "case" for Clojure - -;; by Stuart Sierra <mail@stuartsierra.com> -;; April 7, 2008 - -;; Copyright (c) 2008 Stuart Sierra. All rights reserved. The use and -;; distribution terms for this software are covered by the Common -;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.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. - - -;; This file defines a generic "case" macro called "fcase" which takes -;; the equality-testing function as an argument. It also defines a -;; traditional "case" macro that tests using "=" and variants that -;; test for regular expressions and class membership. - - -(clojure/in-ns 'fcase) -(clojure/refer 'clojure) - - -(defmacro fcase - "Generic switch/case macro. 'fcase' is short for 'function case'. - - The 'compare-fn' is a fn of two arguments. - - The 'test-expr-clauses' are value-expression pairs without - surrounding parentheses, like in Clojure's 'cond'. - - The 'case-value' is evaluated once and cached. Then, 'compare-fn' - is called once for each clause, with the clause's test value as its - first argument and 'case-value' as its second argument. If - 'compare-fn' returns logical true, the clause's expression is - evaluated and returned. If 'compare-fn' returns false/nil, we go to - the next test value. - - If 'test-expr-clauses' contains an odd number of items, the last - item is the default expression evaluated if no case-value matches. - If there is no default expression and no case-value matches, fcase - returns nil. - - See specific forms of this macro in 'case' and 're-case'. - - The test expressions in 'fcase' are always evaluated linearly, in - order. For a large number of case expressions it may be more - efficient to use a hash lookup." - [compare-fn case-value & - test-expr-clauses] - (let [test-val-sym (gensym "test_val") - test-fn-sym (gensym "test_fn") - cond-loop (fn this [clauses] - (cond - (>= (count clauses) 2) - (list 'if (list test-fn-sym (first clauses) test-val-sym) - (second clauses) - (this (rest (rest clauses)))) - (= (count clauses) 1) (first clauses)))] - (list 'let [test-val-sym case-value, test-fn-sym compare-fn] - (cond-loop test-expr-clauses)))) - -(defmacro case - "Like cond, but test-value is compared against the value of each - test expression with =. If they are equal, executes the \"body\" - expression. Optional last expression is executed if none of the - test expressions match." - [test-value & clauses] - `(fcase = ~test-value ~@clauses)) - -(defmacro re-case - "Like case, but the test expressions are regular expressions, tested - with re-find." - [test-value & clauses] - `(fcase re-find ~test-value ~@clauses)) - -(defmacro instance-case - "Like case, but the test expressions are Java class names, tested with - 'instance?'." - [test-value & clauses] - `(fcase instance? ~test-value ~@clauses)) - -(defn- in-case-test [test-seq case-value] - (some (fn [item] (= item case-value)) - test-seq)) - -(defmacro in-case - "Like case, but test expressions are sequences. The test expression - is true if any item in the sequence is equal (tested with '=') to - the test value." - [test-value & clauses] - `(fcase in-case-test ~test-value ~@clauses)) diff --git a/import-static.clj b/import-static.clj deleted file mode 100644 index b26132e9..00000000 --- a/import-static.clj +++ /dev/null @@ -1,60 +0,0 @@ -;;; import-static.clj -- import static Java methods/fields into Clojure - -;; by Stuart Sierra, http://stuartsierra.com/ -;; June 1, 2008 - -;; Copyright (c) 2008 Stuart Sierra. All rights reserved. The use and -;; distribution terms for this software are covered by the Common -;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.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. - - - -(clojure/in-ns 'import-static) -(clojure/refer 'clojure) - -(defmacro import-static - "Imports the named static fields and/or static methods of the class - as (private) symbols in the current namespace. - - Example: - user=> (import-static java.lang.Math PI sqrt) - nil - user=> PI - 3.141592653589793 - user=> (sqrt 16) - 4.0 - - Note: The class name must be fully qualified, even if it has already - been imported. Static methods are defined as MACROS, not - first-class fns." - [class & fields-and-methods] - (let [only (set (map str fields-and-methods)) - the-class (. Class forName (str class)) - static? (fn [x] - (. java.lang.reflect.Modifier - (isStatic (. x (getModifiers))))) - statics (fn [array] - (set (map (memfn getName) - (filter static? array)))) - all-fields (statics (. the-class (getFields))) - all-methods (statics (. the-class (getMethods))) - fields-to-do (set/intersection all-fields only) - methods-to-do (set/intersection all-methods only) - make-sym (fn [string] - (with-meta (symbol string) {:private true})) - import-field (fn [name] - (list 'def (make-sym name) - (list '. class (symbol name)))) - import-method (fn [name] - (list 'defmacro (make-sym name) - '[& args] - (list 'list ''. (list 'quote class) - (list 'apply 'list - (list 'quote (symbol name)) - 'args))))] - `(do ~@(map import-field fields-to-do) - ~@(map import-method methods-to-do)))) diff --git a/javalog.clj b/javalog.clj deleted file mode 100644 index 97554886..00000000 --- a/javalog.clj +++ /dev/null @@ -1,98 +0,0 @@ -;;; javalog.clj -- convenient access to java.util.logging in Clojure - -;; by Stuart Sierra <mail@stuartsierra.com> -;; April 8, 2008 - -;; Copyright (c) 2008 Stuart Sierra. All rights reserved. The use and -;; distribution terms for this software are covered by the Common -;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.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. - - -;; This file defines some convenience functions for using the Java -;; logging framework from Clojure. It is oriented towards simple -;; development and debugging rather than complex production -;; environments. - - - -(clojure/in-ns 'javalog) -(clojure/refer 'clojure) - -(import '(java.util.logging Logger Level ConsoleHandler - FileHandler SimpleFormatter)) - -(def - #^{:tag Logger - :doc "The current java.util.logging.Logger. By default, the - global logger, modified by 'with-logger'."} - *logger* - (. Logger - (getLogger - (. Logger GLOBAL_LOGGER_NAME)))) - -(defmacro log-level - "Translates 'level' (a lower-case keyword) into a static field of - java.util.logging.Level, by name. - - Example: (log-level :severe) => java.util.logging.Level.SEVERE - - If 'level' is not a keyword, it is assumed to be a user-defined - instance of java.util.logging.Level and is returned unchanged." - [level] - (if (keyword? level) - `(. java.util.logging.Level - ~(symbol (. (name level) (toUpperCase)))) - level)) - -(defn root-logger - "Returns the root Logger instance." - ([] (root-logger *logger*)) - ([logger] (let [parent (. logger (getParent))] - (if parent - (recur parent) - logger)))) - -(defn set-console-log-level - "Attempts to set the level of the current logger and the root - ConsoleHandler to 'level' (a java.util.logging.Level). Useful for - debugging at the REPL." - [level] - (let [console-handler - (some (fn [h] (if (instance? ConsoleHandler h) h)) - (. (root-logger) (getHandlers)))] - (if console-handler - (do (. *logger* (setLevel level)) - (. console-handler (setLevel level))) - (throw (new Exception "No ConsoleHandler on root logger."))))) - -(defn add-log-file - "Attaches a log file, using SimpleFormatter, with the given level, - to the named logger. 'level' defaults to ALL. Note: multiple - invocations will create multiple log files, with numbers appended to - the names." - ([logger-name filename] - (add-log-file logger-name filename (. Level ALL))) - ([logger-name filename level] - (let [logger (. Logger (getLogger logger-name)) - handler (new FileHandler filename)] - (. handler (setFormatter (new SimpleFormatter))) - (. handler (setLevel level)) - (. logger (addHandler handler))))) - -(defmacro with-logger - "Executes 'body' with *logger* bound to a logger with the given name - and level. 'level' is expanded with 'log-level'." - [logger-name level & body] - `(binding [*logger* (. Logger (getLogger ~logger-name))] - (. *logger* (setLevel (log-level ~level))) - ~@body)) - -(defmacro log - "Logs a message to *logger*. 'level' is expanded with 'log-level'. - Example: (log :severe \"Bad argument: \" object)" - [level & strings] - `(. *logger* (log (log-level ~level) (str ~@strings)))) diff --git a/lazy-seqs.clj b/lazy-seqs.clj deleted file mode 100644 index 7891bcfa..00000000 --- a/lazy-seqs.clj +++ /dev/null @@ -1,90 +0,0 @@ -;; Copyright (c) Stephen C. Gilardi. 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. -;; -;; lazy-seqs.clj -;; -;; == Lazy sequences == -;; -;; primes - based on the "naive" implemention described in [1] plus a -;; small "wheel" which eliminates multiples of 2, 3, 5, and -;; 7 from consideration by incrementing past them. Also inspired -;; by code from Christophe Grand in [2]. -;; -;; fibs - based on code from Rich Hickey at the Clojure wiki [3] -;; -;; powers-of-2 - all the powers of 2 -;; -;; == Lazy sequence functions == -;; -;; rotations - returns a lazy seq of all the rotations of a seq -;; -;; permutations - returns a lazy seq of all the permutations of a seq -;; -;; [1] http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf -;; [2] http://clj-me.blogspot.com/2008/06/primes.html -;; [3] http://en.wikibooks.org/wiki/Clojure_Programming#Examples -;; -;; scgilardi (gmail) -;; Created 07 June 2008 - -(clojure/in-ns 'lazy-seqs) -(clojure/refer 'clojure) - -(lib/use def) - -(defvar primes - (lazy-cat [2 3 5 7] - (let [primes-from - (fn primes-from [n [f & r]] - (if (some #(zero? (rem n %)) - (take-while #(<= (* % %) n) primes)) - (recur (+ n f) r) - (lazy-cons n (primes-from (+ n f) r)))) - wheel (cycle [2 4 2 4 6 2 6 4 2 4 6 6 2 6 4 2 - 6 4 6 8 4 2 4 2 4 8 6 4 6 2 4 6 - 2 6 6 4 2 4 6 2 6 4 2 4 2 10 2 10])] - (primes-from 11 wheel))) - "A lazy sequence of all the prime numbers.") - -(defvar fibs - (lazy-cat [0 1] - (let [rest-fn - (fn rest-fn [a b] - (let [next (+ a b)] - (lazy-cons next (rest-fn b next))))] - (rest-fn 0 1))) - "A lazy sequence of all the fibonacci numbers.") - -(defvar powers-of-2 - (lazy-cons 1 - (let [rest-fn - (fn rest-fn [n] - (let [next (bit-shift-left n 1)] - (lazy-cons next (rest-fn next))))] - (rest-fn 1))) - "A lazy sequence of all the powers of 2") - -(defn rotations - "Returns a lazy seq of all rotations of a seq" - [x] - (if (seq x) - (map - (fn [n _] - (lazy-cat (drop n x) (take n x))) - (iterate inc 0) x) - (list nil))) - -(defn permutations - "Returns a lazy seq of all permutations of a seq" - [x] - (if (seq x) - (mapcat - (fn [[f & r]] - (map #(cons f %) (permutations r))) - (rotations x)) - (list nil))) diff --git a/lib.clj b/lib.clj deleted file mode 100644 index 186be509..00000000 --- a/lib.clj +++ /dev/null @@ -1,351 +0,0 @@ -;; Copyright (c) Stephen C. Gilardi. 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. -;; -;; File: lib.clj -;; -;; lib.clj provides facilities for loading and managing libs. A lib is a -;; unit of Clojure code contained in a file or other resource within -;; classpath. Lib names must be valid Clojure symbol names. The name of a -;; lib's container is the lib name followed by ".clj". lib.clj also -;; provides general functions for finding and loading resources using the -;; class loaders visible to the Clojure runtime. -;; -;; Here is a brief overview of what's in lib.clj. For detailed docs please -;; see the doc strings for the individual functions and macros. -;; -;; Resources -;; -;; Function: find-resource -;; Searches available class loaders for a resource, returns URL or nil -;; -;; Function: load-resource -;; Loads Clojure source from an absolute path: URI, URL or String -;; -;; Core -;; -;; Function: load-libs -;; Loads lib(s) based libspecs and flags -;; -;; Function: libs -;; Returns a sorted set of symbols naming the currently loaded libs -;; -;; Convenience -;; -;; Macro: require -;; Loads libs. By default doesn't reload any that are already loaded -;; -;; Macro: use -;; Loads libs like require and refers to each lib's namespace -;; -;; Examples -;; -;; (load-libs :require 'sql '(sql-test :in "private/unit-tests")) -;; (require sql (sql-test :in "private/unit-tests")) -;; -;; (load-libs :require :use 'sql 'ns-utils :verbose) -;; (use sql ns-utils :verbose) -;; -;; (use :reload-all :verbose -;; (sql :exclude '(get-connection) -;; :rename '{execute-commands do-commands}) -;; ns-utils) -;; -;; (use (sql)) -;; -;; (load-libs :require :use '(genclass :ns 'clojure)) -;; (use (genclass :ns 'clojure)) -;; -;; scgilardi (gmail) -;; Created 7 April 2008 -;; -;; Thanks to Stuart Sierra for providing many useful ideas, discussions -;; and code contributions for lib.clj. - -(clojure/in-ns 'lib) -(clojure/refer 'clojure) - -(alias 'set 'clojure.set) - -(import '(clojure.lang RT)) -(import '(java.io BufferedReader InputStreamReader)) -(import '(java.net URI URL)) - -;; Private - -(defmacro init-once - "Initializes a var exactly once. The var must already exist." - {:private true} - [var init] - `(let [v# (resolve '~var)] - (when-not (.isBound v#) - (.bindRoot v# ~init)))) - -(def - #^{:private true :doc - "A ref to a set of symbols representing loaded libs"} - *libs*) -(init-once *libs* (ref (sorted-set))) - -(def - #^{:private true :doc - "True while a verbose load is pending"} - *verbose*) -(init-once *verbose* false) - -(def - #^{:private true :doc - "A list of keywords that clojure/refer recognizes as filters"} - *filter-keys*) -(init-once *filter-keys* '(:exclude :only :rename)) - -(def - #^{:private true :doc - "A vector of the available class loaders ordered by the degree to which - they are controlled by Clojure. The root loader's classpath can be - extended with clojure/add-classpath"} - *class-loaders* - (let [root (.ROOT_CLASSLOADER RT) - runtime (.getClassLoader (identity RT)) - system (.getSystemClassLoader ClassLoader)] - (if (= system runtime) - [root system] - [root runtime system]))) - -(defn- format - "Formats a string using String/format" - [fmt & args] - (String/format fmt (to-array args))) - -(defn- printf - "Prints formatted output" - [fmt & args] - (print (apply format fmt args))) - -(defn- throw-if - "Throws an exception with a message if pred is true. See - java.util.Formatter for format string syntax." - [pred fmt & args] - (when pred (throw (Exception. (apply format fmt args))))) - -(def find-resource) ; forward declaration -(def load-resource) ; forward declaration - -(defn- load-one - "Loads one lib from a resoure and ensures that namespace ns (if - specified) exists" - [sym url ns] - (load-resource url) - (throw-if (and ns (not (find-ns ns))) - "namespace '%s' not found after loading '%s'" ns url) - (dosync - (commute *libs* conj sym))) - -(defn- load-all - "Loads a lib from a resource and forces a load of any libs which it - directly or indirectly loads via require/use/load-libs" - [sym url ns] - (dosync - (commute *libs* set/union - (binding [*libs* (ref (sorted-set))] - (load-one sym url ns) - @*libs*)))) - -(defn sym-file - "Returns the implementation file path for a libspec sym" - [sym] - (let [n (name sym) - index (inc (.lastIndexOf n (int \.))) - leaf (.substring n index) - ns (if (zero? index) (name (ns-name *ns*)) n) - file-new (str (.replace ns \. \/) \/ leaf ".clj") - file-old (str sym ".clj")] - (if (find-resource file-new) - file-new - file-old))) - -(defn- load-lib - "Loads a lib with options: sequential keywords and arguments. The - arguments to all options are evaluated so literal symbols or lists must - be quoted" - [sym & options] - (let [raw-opts (apply hash-map options) - opts (zipmap (keys raw-opts) (map eval (vals raw-opts))) - in (:in opts) - ns (:ns opts) - reload (:reload opts) - reload-all (:reload-all opts) - require (:require opts) - use (:use opts) - verbose (:verbose opts) - loaded (contains? @*libs* sym) - load (cond reload-all - load-all - (or reload (not require) (not loaded)) - load-one) - namespace (when use (or ns sym)) - path (str (if in (str in \/)) (sym-file sym)) - url (find-resource path) - filter-opts (select-keys opts *filter-keys*)] - (binding [*verbose* (or *verbose* verbose)] - (when load - (when *verbose* - (printf "(lib/load-resource \"%s\")\n" url) - (flush)) - (throw-if (not url) "'%s' not found in classpath" path) - (load sym url namespace)) - (when namespace - (when *verbose* - (printf "(clojure/in-ns '%s)\n" (ns-name *ns*)) - (printf "(clojure/refer '%s" namespace) - (dorun (map - #(printf " %s '%s" (key %) (prin |