A question on referring functions in macros

Currently I write macros with .cljc files:

(defmacro m1 [x]
  `(f1 ~x))

f1 is a function from n1.core/f1.

Then in n2.core, I use that macro m1. What will happen?

  1. nothing should happen, it’s correct
  2. compiler should throw an error, “f1 not declared”
  3. compiler should be find, but it throw exceptions in runtime like f1 undefined
  4. as long as n1.core is referred, it will be ok
  5. or else?

You should really just test this out, questions like these are quite easy to test at a repl. E.g. what happens if you evaluate

(let [x 5] `(f1 x))

or

(macroexpand-1 '(m1 5))

But to answer your question, backquotes automatically expand symbols to be fully namespace qualified,

`f1

is the same as

'n1.core/f1

In other words, option 4), your macro will work fine, as long as f1 is defined or referred in the same namespace as m1

Yes, I did. But my code was a mess, I haven’t managed to finish a minimal example yet. I tried it in REPL actually, but as I compiled my code and see errors for so many times, I became uncertain.

my code is a mess anyway… https://github.com/Respo/respo/commit/275a24fb66a86bc8e15889a1a9aa9fad12c9f1ec

I’m guessing it may be based on implementation. I will try shadow-cljs later.

Finished my demo in shadow-cljs, https://github.com/minimal-xyz/minimal-cljs-macro/blob/93be7d55773d61f1cda9783f37b0f26e23e1dfe1/src/server/main.cljs#L4-L6

Like told by @plexus , need that thing in the same namespace.

(ns server.main
  (:require-macros [server.macros :refer [some-macro]])
  (:require [server.foo]))

; server.foo is required... or compiler will warn

(defn main! []
  (some-macro "Hello!"))

I remembered in my previous demos, it was more complicated because I got exceptions even with (:require [server.foo]). I have to write (:require [server.foo :refer [bar]]) to make it work. Strange. Maybe fake memory…