Skip to content

Instantly share code, notes, and snippets.

@astrangeguy
Created June 7, 2010 18:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save astrangeguy/429027 to your computer and use it in GitHub Desktop.
Save astrangeguy/429027 to your computer and use it in GitHub Desktop.
(defmacro my-defrecord [the-name [& fields] & opt+specs]
(let [full-classname (symbol (str (.name *ns*) \. the-name))]
`(do
(ns-unmap *ns* '~the-name)
(defrecord ~the-name [~@fields] ~@opt+specs)
(ns-unmap *ns* '~the-name)
(defn ~the-name
([~@fields]
(new ~full-classname ~@fields nil nil))
([~@fields ~'meta ~'extmap]
(new ~full-classname ~@fields ~'meta ~'extmap))))))
(comment
user> (defprotocol P (what [p]))
P
user> (my-defrecord Foo [] P (what [_] :old))
#'user/Foo
user> (defn call-what-on-a-Foo [] (what (Foo)))
#'user/call-what-on-a-Foo
user> (call-what-on-a-Foo)
:old
user> (my-defrecord Foo [] P (what [_] :new))
#'user/Foo
user> (call-what-on-a-Foo)
:old
)
; but this works:
(defmacro my-defrecord [the-name [& fields] & opt+specs]
`(do
(defrecord ~the-name [~@fields] ~@opt+specs)
(defn ~(symbol (str "make-" the-name))
([~@fields]
(new ~the-name ~@fields nil nil))
([~@fields ~'meta ~'extmap]
(new ~the-name ~@fields ~'meta ~'extmap)))))
(comment
user> (defprotocol P (what [p]))
P
user> (my-defrecord Foo [] P (what [_] :old))
#'user/make-Foo
user> (defn call-what-on-a-Foo [] (what (make-Foo)))
#'user/call-what-on-a-Foo
user> (call-what-on-a-Foo)
:old
user> (my-defrecord Foo [] P (what [_] :new))
#'user/make-Foo
user> (call-what-on-a-Foo)
:new
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment