I have a function my-plus-in-macro that contains a macro named my-macro. But my-macro is declared after my-plus-macro definition. I use declare to avoid unable-to-resolve symbol error.
I type these codes in my repl.
(declare my-macro my-plus)
(defn my-plus-in-macro [x y]
(my-macro (my-plus x y)))
(defmacro my-macro [my-fn]
`~my-fn)
(defn my-plus [x y]
(+ x y))
Then, I expect to get 3 if execute this
(my-plus-in-macro 1 2)
but instead I get,
ArityException Wrong number of args (1) passed to: user$my-macro clojure.lang.AFn.throwArity (AFn.java:437)
But, if I execute this my-plus-in-macro definition again in the repl
(defn my-plus-in-macro [x y]
(my-macro (my-plus x y)))
then I execute this (my-plus-in-macro 1 2)
Just what I expect, 3
What happens in my first execution of (my-plus-in-macro 1 2)?
Somehow, when I define my-plus-in-macro for the first time, clojure sees my-macro symbol but it doesn't know yet that I intend to use it as a name for a macro.
Although I have define my-macro as a symbol right after I define my-plus-in-macro, clojure still doesn't know that my-macro is a symbol for a macro. That's why I get ArityException.
But, somehow, when I redefine my-plus-in-macro with the same code, Clojure now knows that my-macro is a macro and treats it as such and then my code works.
Of course I don't get any exception if I put my-macro definition before my-plus-in-macro definition. But does that mean I can not use declare to reserve a symbol for a macro?
EDIT
based on answer from @xsc, these code works. I just have to call my-macro in my-plus-in-macro definition using "correct" way by supplying :form and :env
(declare my-macro my-plus)
(defn my-plus-in-macro [x y]
(my-macro :form :env (my-plus x y)))
(defmacro my-macro [my-fn]
`~my-fn)
(defn my-plus [x y]
(+ x y))
(my-plus-in-macro 1 2)
3
EDIT-0
@xsc you are right, I can not use declare to forward-declare symbols for macros. I must put macro definition before any function that use it.
so, this is the right code
(declare my-plus)
(defmacro my-macro [my-fn]
`~my-fn)
(defn my-plus-in-macro [x y]
(my-macro (my-plus x y)))
(defn my-plus [x y]
(+ x y))
(my-plus-in-macro 1 2)
3