Search code examples
clojuremacrosclojurescript

Cljs macros requiring fully qualified symbols


At a normal repl this works:

(defmacro evaluate
  [to-eval]
  (eval to-eval))
(evaluate +) ;=> #function[clojure.core/+]

However in clojurescript when using separate files like so:

file one: macro.clj
(ns space.macro)
(defmacro evaluate
  [to-eval]
  (eval to-eval))

file two: core.cljs
(ns space.core
  (:require-macros [space.macro :refer [evaluate]))
(evaluate clojure.core/+) ;=> No error
(evaluate +) ;=> Unable to resolve symbol: + in this context

We get some errors. Which begs the question why? And how do you fix this?


Solution

  • This is because you need to have the symbol + get evaluated before it's handed to the macro so that the symbol is resolved before it's handed to the other namespace. You can do that with quoting like so:

    (defmacro evaluate
      [to-eval]
      `(eval ~to-eval))
    

    Check out the chapter on macros in "Clojure For the Brave and True" for a better explanation: http://www.braveclojure.com/writing-macros/#Simple_Quoting