marginalia
marginalia copied to clipboard
macros
Marginalia seems to be evaluating macros. This can be problematic.
https://gist.github.com/941466
Here is an example where everything goes wrong https://gist.github.com/941481
I was able to get around this with (eval (macroexpand (call-to-macrodefined-fn)))
Marginalia evaluates macros to handle def* macros. To be able to strip the docstring wherever it is in the definition, it currently check the actual var docstring and strip it off from the parsed code. I'm not sure there's a better way to do that. Anyway in most cases macro shouldn't have side-effects. In the case of debugging macros like in your example, you might try this other approach:
(def *dbg* false)
(defmacro dbg [x]
(if *dbg*
`(let [x# ~x]
(println '~x "=" x#)
x#)
x))
(defn pythag [x y]
(dbg (* (dbg (* x x))
(dbg (* y y)))))
(pythag 4 5)
;; no output
(def *dbg* true)
(defn pythag [x y]
(dbg (* (dbg (* x x))
(dbg (* y y)))))
(pythag 4 5)
;; (* x x) = 16
;; (* y y) = 25
;; (* (dbg (* x x)) (dbg (* y y))) = 400
The only issue with this code is that if you rebind dbg dynamically, you'll need to expand the macros recursively at compile time which (in the case you use a simple walker) will have expanded you inner calls to dbg:
(use 'clojure.walk)
(defmacro with-dbg [x]
(binding [*dbg* true]
(prewalk #(macroexpand %) x)))
(with-dbg
(defn pythag [x y]
(dbg (* (dbg (* x x))
(dbg (* y y))))))
(pythag 4 5)
;; (* x x) = 16
;; (* y y) = 25
;; (* (let* [x__4681__auto__ (* x x)] (clojure.core/println (quote (* x x)) = x__4681__auto__) x__4681__auto__) (let* [x__4681__auto__ (* y y)] (clojure.core/println (quote (* y y)) = x__4681__auto__) x__4681__auto__)) = 400