diff options
author | Konrad Hinsen <konrad.hinsen@laposte.net> | 2009-04-16 13:06:47 +0000 |
---|---|---|
committer | Konrad Hinsen <konrad.hinsen@laposte.net> | 2009-04-16 13:06:47 +0000 |
commit | e2db839a3ce9c5aa4cc0e287f560d6600b683f3a (patch) | |
tree | 45eceea01e7c5f9b843e2787b0b1aab5a793bc2b | |
parent | e7ee840f2df7b51a1f4eb8d9002f67fd6211a4d8 (diff) |
types: optional docstring and attribute map in deftype
-rw-r--r-- | src/clojure/contrib/types.clj | 51 | ||||
-rw-r--r-- | src/clojure/contrib/types/examples.clj | 3 |
2 files changed, 36 insertions, 18 deletions
diff --git a/src/clojure/contrib/types.clj b/src/clojure/contrib/types.clj index 672d537f..c66ed68c 100644 --- a/src/clojure/contrib/types.clj +++ b/src/clojure/contrib/types.clj @@ -1,7 +1,7 @@ ;; Data types ;; by Konrad Hinsen -;; last updated March 29, 2009 +;; last updated April 16, 2009 ;; Copyright (c) Konrad Hinsen, 2009. All rights reserved. The use ;; and distribution terms for this software are covered by the Eclipse @@ -60,22 +60,39 @@ as metadata. The deconstructor function must return the arguments to be passed to the constructor in order to create an equivalent object. It is used for printing and matching." - ([type-tag constructor-name] - `(deftype ~type-tag ~constructor-name - clojure.core/identity clojure.core/list)) - ([type-tag constructor-name constructor] - `(deftype ~type-tag ~constructor-name - ~constructor clojure.core/list)) - ([type-tag constructor-name constructor deconstructor] - `(do - (derive ~type-tag ::type) - (let [meta-map# {:type ~type-tag - ::constructor - (quote ~(qualified-symbol constructor-name))}] - (def ~constructor-name - (comp (fn [~'x] (with-meta ~'x meta-map#)) ~constructor)) - (defmethod deconstruct ~type-tag [~'x] - (~deconstructor (with-meta ~'x {}))))))) + {:arglists + '([type-tag constructor-name docstring? attr-map?] + [type-tag constructor-name docstring? attr-map? constructor] + [type-tag constructor-name docstring? attr-map? constructor deconstructor])} + [type-tag constructor-name & options] + (let [[docstring options] (if (string? (first options)) + [(first options) (next options)] + [nil options]) + [attr options] (if (map? (first options)) + [(first options) (next options)] + [{} options]) + [constructor deconstructor] options + constructor (if (nil? constructor) + 'clojure.core/identity + constructor) + deconstructor (if (nil? deconstructor) + 'clojure.core/list + deconstructor) + attr (if docstring + (assoc attr :doc docstring) + attr) + attr (if (meta constructor-name) + (conj (meta constructor-name) attr) + attr)] + `(do + (derive ~type-tag ::type) + (let [meta-map# {:type ~type-tag + ::constructor + (quote ~(qualified-symbol constructor-name))}] + (def ~(with-meta constructor-name attr) + (comp (fn [~'x] (with-meta ~'x meta-map#)) ~constructor)) + (defmethod deconstruct ~type-tag [~'x] + (~deconstructor (with-meta ~'x {}))))))) (defmacro deftype- "Same as deftype but the constructor is private." diff --git a/src/clojure/contrib/types/examples.clj b/src/clojure/contrib/types/examples.clj index fc9435fe..1ee27964 100644 --- a/src/clojure/contrib/types/examples.clj +++ b/src/clojure/contrib/types/examples.clj @@ -18,7 +18,8 @@ ; The most basic type definition. A more elaborate version could add ; a constructor that verifies that its argument is a map with integer values. -(deftype ::multiset multiset) +(deftype ::multiset multiset + "Multiset (demo implementation)") ; Some set operations generalized to multisets ; Note that the multiset constructor is nowhere called explicitly, as the |