Skip to content

Instantly share code, notes, and snippets.

@RutledgePaulV
Last active July 3, 2016 19:26
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 RutledgePaulV/dfb6b0ce31be3fbeef05e73316abaef7 to your computer and use it in GitHub Desktop.
Save RutledgePaulV/dfb6b0ce31be3fbeef05e73316abaef7 to your computer and use it in GitHub Desktop.
A macro wrapping def-record that also defines a constructor function with default values.
(defmacro make-model
[name args & body]
(let [defaults (if (map? (first body)) (first body) {})
constructor-name (str/lower-case (str "make-" name))]
`(do (defrecord ~name ~args ~@(if (map? (first body)) (rest body) body))
(defn ~(symbol constructor-name)
([] (~(symbol constructor-name) {}))
([values#] (~(symbol (str "map->" name)) (merge ~defaults values#)))))))
@RutledgePaulV
Copy link
Author

Usage like:

(make-model User [firstName lastName] {:lastName "Smith"})
=> #'user/make-user
(make-user {:firstName "John"})
=> #user.User{:firstName "John", :lastName "Smith"}

Default arguments are optional and so too are any arguments to the constructor.

(make-model User [firstName lastName])
=> #'user/make-user
(make-user)
=> #user.User{:firstName nil, :lastName nil}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment