Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure - How to make my macro expand before system macros?

Tags:

macros

clojure

If I do, for example:

(defmacro qqq [] '(toString [this] "Qqq"))
(reify Object (qqq))

it fails because of reify sees (qqq) instead of (toString [this] "Qqq").

The usual solution is a macro that wraps "reify" call with my own thing, but it is longer and more intrusive.

How to make my macros stronger that usual macros to be expanded first?

Expecting something like:

(defmacro ^{:priority 100500} qqq [] '(toString [this] "Qqq"))
(reify Object (qqq))

or

(defmacro qqq [] '(toString [this] "Qqq"))
(expand-first #{qqq} (reify Object (qqq)))
like image 693
Vi. Avatar asked Feb 13 '11 13:02

Vi.


2 Answers

There is a reader-macro to evaluate things at read-time (before macro-expansion time)..

(defn qqq [] '(toString [this] "Qqq"))
(reify Object #=(qqq))

I've never seen this done in "real" code, and I think most people would consider it a hack, but it's there if you need it.

like image 133
Chris Perkins Avatar answered Nov 03 '22 22:11

Chris Perkins


The macro that forces given user macros to expand first (requires clojure.walk):

(defmacro expand-first [the-set & code] 
 `(do ~@(prewalk 
  #(if (and (list? %) (contains? the-set (first %)))
  (macroexpand-all %)
  %) code)))

Who has ideas how to make it better?

like image 23
Vi. Avatar answered Nov 03 '22 22:11

Vi.