Skip to content

Instantly share code, notes, and snippets.

@acthp
Last active August 29, 2015 14:10
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 acthp/8f42bf23aa0839811931 to your computer and use it in GitHub Desktop.
Save acthp/8f42bf23aa0839811931 to your computer and use it in GitHub Desktop.
clojure bean macro
(let [t (fn [type prop] ; type hint a property
(with-meta prop {:tag type}))
cc (fn [prop] ; camel-case a property
(str (.toUpperCase (subs (str prop) 0 1)) (subs (str prop) 1)))
m (fn [prop method] ; construct method name for property
(symbol (str method (cc prop))))
bean-interface (fn [bean-name & props] ; define interface for bean
(let [set (fn [type prop]
`(~(m prop 'set) [~(t type 's)]))
get (fn [type prop]
`(~(t type (m prop 'get)) []))
methods (for [[t p] (partition 2 props) method [set get]]
(method t p))]
`(definterface ~(symbol (str "I" bean-name)) ~@methods)))
bean-type (fn [bean-name & props] ; define type for bean
(let [prop-list (mapv (fn [[type prop]]
(with-meta prop {:volatile-mutable true :tag type}))
(partition 2 props))
set (fn [type prop]
`(~(m prop 'set) [~'this ~(t type 's)] (set! ~prop ~'s)))
get (fn [type prop]
`(~(t type (m prop 'get)) [~'this] ~prop))
methods (for [[t p] (partition 2 props) method [set get]]
(method t p))]
`(deftype ~bean-name ~prop-list java.io.Serializable ~(symbol (str "I" bean-name)) ~@methods)))]
(defmacro defbean [bean-name & props]
(list 'do
(apply bean-interface bean-name props)
(apply bean-type bean-name props))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment