Skip to content

Instantly share code, notes, and snippets.

@ck
Forked from fogus/defrecord++.clj
Created August 2, 2010 16:54
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 ck/504938 to your computer and use it in GitHub Desktop.
Save ck/504938 to your computer and use it in GitHub Desktop.
;; stolen from http://cemerick.com/2010/08/02/defrecord-slot-defaults/
(defmacro defrecord+defaults
"Defines a new record, along with a new-RecordName factory function that
returns an instance of the record initialized with the default values
provided as part of the record's slot declarations. e.g.
(defrecord+ Foo [a 5 b \"hi\"])
(new-Foo)
=> #user.Foo{:a 5, :b \"hi\"}"
[name slots & etc]
(let [fields (->> slots (partition 2) (map first) vec)
defaults (->> slots (partition 2) (map second))]
`(do
(defrecord ~name
~fields
~@etc)
(defn ~(symbol (str "new-" name))
~(str "A factory function returning a new instance of " name
" initialized with the defaults specified in the corresponding defrecord+ form.")
[& {:as kwargs#}]
(-> (~(symbol (str name \.)) ~@defaults)
(merge kwargs#)))
~name)))
(defrecord+defaults Foo [a 1 b 2])
(new-Foo :a 42)
;=> #:user.Foo{:a 42, :b 2}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment