diff options
author | Stuart Sierra <mail@stuartsierra.com> | 2010-08-07 16:41:53 -0400 |
---|---|---|
committer | Stuart Sierra <mail@stuartsierra.com> | 2010-08-07 16:41:53 -0400 |
commit | a6a92b9b3d2bfd9a56e1e5e9cfba706d1aeeaae5 (patch) | |
tree | f1f3da9887dc2dc557df3282b0bcbd4d701ec593 /modules/def | |
parent | e7930c85290f77815cdb00a60604feedfa2d0194 (diff) |
Split all namespaces into sub-modules.
* Examples and tests have not been copied over.
* Clojure test/compile phases are commented out in parent POM.
* May require installing parent POM before full build.
Diffstat (limited to 'modules/def')
-rw-r--r-- | modules/def/pom.xml | 16 | ||||
-rw-r--r-- | modules/def/src/main/clojure/clojure/contrib/def.clj | 149 |
2 files changed, 165 insertions, 0 deletions
diff --git a/modules/def/pom.xml b/modules/def/pom.xml new file mode 100644 index 00000000..be980ac8 --- /dev/null +++ b/modules/def/pom.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http//www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 + http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.clojure.contrib</groupId> + <artifactId>parent</artifactId> + <version>1.3.0-SNAPSHOT</version> + <relativePath>../parent</relativePath> + </parent> + <artifactId>def</artifactId> + <dependencies> + </dependencies> +</project>
\ No newline at end of file diff --git a/modules/def/src/main/clojure/clojure/contrib/def.clj b/modules/def/src/main/clojure/clojure/contrib/def.clj new file mode 100644 index 00000000..c3cd2c42 --- /dev/null +++ b/modules/def/src/main/clojure/clojure/contrib/def.clj @@ -0,0 +1,149 @@ +;; Copyright (c) Stephen C. Gilardi. All rights reserved. The use and +;; distribution terms for this software are covered by the Eclipse Public +;; License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can +;; be found in the file epl-v10.html 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 + +(ns + ^{:author "Stephen C. Gilardi", + :doc "def.clj provides variants of def that make including doc strings and +making private definitions more succinct."} + clojure.contrib.def) + +(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 defonce- + "Same as defonce but yields a private definition" + ([name expr] + (list `defonce (with-meta name (assoc (meta name) :private true)) expr)) + ([name expr doc] + (list `defonce (with-meta name (assoc (meta name) :private true :doc doc)) expr))) + +(defmacro defalias + "Defines an alias for a var: a new var with the same root binding (if + any) and similar metadata. The metadata of the alias is its initial + metadata (as provided by def) merged into the metadata of the original." + ([name orig] + `(do + (alter-meta! + (if (.hasRoot (var ~orig)) + (def ~name (.getRoot (var ~orig))) + (def ~name)) + ;; When copying metadata, disregard {:macro false}. + ;; Workaround for http://www.assembla.com/spaces/clojure/tickets/273 + #(conj (dissoc % :macro) + (apply dissoc (meta (var ~orig)) (remove #{:macro} (keys %))))) + (var ~name))) + ([name orig doc] + (list `defalias (with-meta name (assoc (meta name) :doc doc)) orig))) + +; defhinted by Chouser: +(defmacro defhinted + "Defines a var with a type hint matching the class of the given + init. Be careful about using any form of 'def' or 'binding' to a + value of a different type. See http://paste.lisp.org/display/73344" + [sym init] + `(do + (def ~sym ~init) + (alter-meta! (var ~sym) assoc :tag (class ~sym)) + (var ~sym))) + +; name-with-attributes by Konrad Hinsen: +(defn name-with-attributes + "To be used in macro definitions. + Handles optional docstrings and attribute maps for a name to be defined + in a list of macro arguments. If the first macro argument is a string, + it is added as a docstring to name and removed from the macro argument + list. If afterwards the first macro argument is a map, its entries are + added to the name's metadata map and the map is removed from the + macro argument list. The return value is a vector containing the name + with its extended metadata map and the list of unprocessed macro + arguments." + [name macro-args] + (let [[docstring macro-args] (if (string? (first macro-args)) + [(first macro-args) (next macro-args)] + [nil macro-args]) + [attr macro-args] (if (map? (first macro-args)) + [(first macro-args) (next macro-args)] + [{} macro-args]) + attr (if docstring + (assoc attr :doc docstring) + attr) + attr (if (meta name) + (conj (meta name) attr) + attr)] + [(with-meta name attr) macro-args])) + +; defnk by Meikel Brandmeyer: +(defmacro defnk + "Define a function accepting keyword arguments. Symbols up to the first + keyword in the parameter list are taken as positional arguments. Then + an alternating sequence of keywords and defaults values is expected. The + values of the keyword arguments are available in the function body by + virtue of the symbol corresponding to the keyword (cf. :keys destructuring). + defnk accepts an optional docstring as well as an optional metadata map." + [fn-name & fn-tail] + (let [[fn-name [args & body]] (name-with-attributes fn-name fn-tail) + [pos kw-vals] (split-with symbol? args) + syms (map #(-> % name symbol) (take-nth 2 kw-vals)) + values (take-nth 2 (rest kw-vals)) + sym-vals (apply hash-map (interleave syms values)) + de-map {:keys (vec syms) + :or sym-vals}] + `(defn ~fn-name + [~@pos & options#] + (let [~de-map (apply hash-map options#)] + ~@body)))) + +; defn-memo by Chouser: +(defmacro defn-memo + "Just like defn, but memoizes the function using clojure.core/memoize" + [fn-name & defn-stuff] + `(do + (defn ~fn-name ~@defn-stuff) + (alter-var-root (var ~fn-name) memoize) + (var ~fn-name))) |