(defmacro deftype
"Define a data type by a type tag (a namespace-qualified keyword)
and a symbol naming the constructor function. Optionally, a
constructor and a deconstructor function can be given as well,
the defaults being clojure.core/identity and clojure.core/list.
The full constructor associated with constructor-name calls the
constructor function and attaches the type tag to its result
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."
{: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 [[constructor-name options] (name-with-attributes
constructor-name options)
[constructor deconstructor] options
constructor (if (nil? constructor)
'clojure.core/identity
constructor)
deconstructor (if (nil? deconstructor)
'clojure.core/list
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 {})))))))
Used in 0 other vars
Comments top
No comments for deftype. Log in to add a comment.