Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
145 views
in Technique[技术] by (71.8m points)

Can I reference a macro from within a macro in Clojure?

Clojure. Cursive. REPL. Windows 10. All up-to-date.

Here's my 'base' macro:

(defmacro PutProp! [Sym Val PName]
  `(reset-meta! (var ~Sym) (assoc (meta (var ~Sym)) ~PName ~Val)))

I have no idea if this is even correct in doing what I want to do, which is to modify Sym's metadata keyname PName with the new Val value. I'm new at this and I'm SURE I've jumped into the pool at the deep end. I'm using a macro because I thought it would avoid messy variable binding issues which I don't understand in Clojure.

Then I wrote another macro to define a lot of metadata on a single call:

(defmacro DefMeta! [L]  ;; Given a symbol (first L), define metadata for it given in (next L).
  `(let [S (first ~@L)]     ;; The symbol we're modifying is the first element in list L.
     (map (fn [[K V]] (PutProp! S V K)) (next ~@L))))   ;; (next L) is the list of key/value pairs.

I'm also not sure this is what I want to write. Working at the REPL, I define a symbol:

(def Sym 0)

Then I do a macroexpand-1 of DefMeta!:

(macroexpand-1 '(DefMeta! [Sym :VName :VValue]))

I get the following:

(clojure.core/let
 [thic.core/S (clojure.core/first Sym :VName :VValue)]
 (clojure.core/map
  (clojure.core/fn [[thic.core/K thic.core/V]] (thic.core/PutProp! thic.core/S thic.core/V thic.core/K))
  (clojure.core/next Sym :VName :VValue)))

which doesn't macro-expand the PutProp! macro.

I'm stumped. I have four books on Clojure programming and none of them mentions macro calls from within macro calls. Is it even legal? If so, how do I fully expand the inner macro so that I can see if what I've written is what I want? [...the perennial programmer problem...]

PS I tried macroexpand-all and I'm overwhelmed with the macroexpansion of EVERYTHING, even Clojure core functions.
Something less than that, please. Please?

question from:https://stackoverflow.com/questions/65829408/can-i-reference-a-macro-from-within-a-macro-in-clojure

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It is perfectly legal (& common) for the definition of a macro to make use of another macro.

You can see an example of the best way IMHO to build up a macro step-by-step in this question.

I don't like using the macroexpand-* functions. The answer in the above link uses simple helper functions with println and friends so you can see what is occurring one step at a time in the macro writing process. Enjoy!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...