, так как переменная будет определена / создана во время выполнения, как только макрос завершит свою работу и уйдет, макрос может вместо этого предсказать, как будет названа переменная, и создать символ напрямую, а не совершать циклический переходчерез пространство имен и обратно
Давайте сначала сделаем это вручную
user> (def foo)
#'user/foo
user> (resolve 'foo)
#'user/foo
, что выглядит правильно, теперь давайте сделаем это, создав символ:
user> (symbol (str *ns* "/" "foo"))
user/foo
и скопируем этов определение макроса:
user> (defmacro def&resolve [a b]
`(do
(def ~a 12)
(def ~b ~(symbol (str *ns* "/" "foo")))))
#'user/def&resolve
и протестируйте его
user> (def&resolve foo bar)
#'user/bar
user> bar
12
Этот метод предпочтительнее подхода intern
для создания символа в пространстве имен с использованием фиктивного значения, во время расширения макроса, затем resolve
, используя его также во время расширения макроса.В результате чего же значение.Преимущество этого подхода состоит в том, что он выполняет работу по разрешению во время расширения макроса, как в исходном вопросе
user> (do (intern *ns* 'a :dummy-value)
(resolve 'a))
#'user/a
, хотя я рекомендую использовать подход генерации символов.