Skip to content

Instantly share code, notes, and snippets.

@AdamSaleh
Created April 5, 2013 15:01
Show Gist options
  • Save AdamSaleh/5319970 to your computer and use it in GitHub Desktop.
Save AdamSaleh/5319970 to your computer and use it in GitHub Desktop.
(defmacro defrecord [rec args]
`(do (clojure.core/defrecord ~rec ~args
'clojure.lang.IFn
(list 'invoke '[this] 'this)
(list 'invoke '[this n] '(repeat n this))
(list 'applyTo '[this args] (list 'clojure.lang.AFn/applyToHelper 'this 'args)))
(def ~(symbol (str "new" rec)) ~(symbol (str "map->" rec)))))
@AdamSaleh
Copy link
Author

ClassCastException clojure.lang.Cons cannot be cast to clojure.lang.Symbol

@weissjeffm
Copy link

you already have a syntax-quote on line 2, so you don't need to do any more quoting. However you should use the gensym (trailing #) for safety purposes. Otherwise it's possible for the macro to be invoked somewhere where the symbols this,n, or args might refer to something else. In this case it should be fine either way, but that's the usual practice.

this is untested by the way:

(defmacro defrecord [rec args]
  `(do (clojure.core/defrecord ~rec ~args clojure.lang.IFn
         (invoke [this#] this#)
         (invoke [this# n#] (repeat n# this#))
         (applyTo [this# args#] (clojure.lang.AFn/applyToHelper this# args#))
       (def ~(symbol (str "new" rec)) ~(symbol (str "map->" rec)))))

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