 (defmacro defprint-method
   "Defines a print-method for the given class which writes out the EDN
   serialization from `edn-str`."
-  [c]
-  `(defmethod print-method ~c
+  [t]
+  `(defmethod print-method ~t
      [v# ^java.io.Writer w#]
        (.write w# (edn-str v#))))
+
+
+
+;; EXTENSION FUNCTIONS
+
+(defmacro extend-tagged-value
+  "Extends the TaggedValue protocol with implementations which return the
+  given symbol as the tag and use the body to calculate the value. The symbol
+  'this' is bound to the data. This macro also defines a print-method which
+  delegates to edn-str."
+  [t tag & body]
+  `(do
+     (extend-type ~t
+       TaggedValue
+       (edn-tag [~'this] (quote ~tag))
+       (edn-value [~'this]
+         ~@(if (and (= 1 (count body)) (symbol? (first body)))
+             (list (list (first body) 'this))
+             body)))
+     (defprint-method ~t)))
+
+
+(defmacro extend-tagged-str
+  [c tag]
+  `(extend-tagged-value ~c ~tag str))
+
+
+(defmacro extend-tagged-map
+  [c tag]
+  `(extend-tagged-value ~c ~tag (into {} (seq ~'this))))
 
 
 



; #uri - Universal Resource Identifier string.

(extend-type URI
  TaggedValue
  (edn-tag [this] 'uri)
  (edn-value [this] (str this)))


(defprint-method URI)


(defn read-uri

    (.format date-format date)))


(extend-tagged-value Date inst format-utc)


; #uuid - Universally-unique identifier string.
(extend-tagged-str UUID uuid)



;; EXPANDED EDN TAG SUPPORT

; #bin - Binary data in the form of byte arrays.
(extend-tagged-value
  (Class/forName "[B") bin
  (->> this b64/encode (map char) (apply str)))


(defn read-bin
