In Clojure REPL:
(macroexpand-1 `(sum 2 1)) ; (user/sum 2 1)
In Clojurescript REPL:
(macroexpand-1 `(sum 2 1)) ; AssertionError: Assert failed: Argument to macroexpand-1 must be quoted
Why it happens? Can you explain evalutation process in Clojurescript please?
In Clojure, macroexpand-1
can be a function, because Clojure has access to the compiler at runtime, so macroexpand-1
can inspect any list you construct. Clojurescript is compiled to Javascript, and doesn't have access to the compiler at runtime. So macroexpand is only useful at compile-time, and must be a macro in order to run then. It therefore doesn't evaluate its argument, and needs it to be a literal quoted list.
You might now ask: "Doesn't syntax-quote return a quoted list?". But it doesn't. It returns some expression that evaluates to the right list; in principle it could return a quoted list when you don't use any unquoting, but in practice it doesn't. You can see this in the repl by quoting a syntax-quoted expression, to see its expansion instead of evaluating it:
In a Clojure repl:
user=> '`(sum 1 2)
(clojure.core/seq (clojure.core/concat (clojure.core/list (quote user/sum)) (clojure.core/list 1) (clojure.core/list 2)))
In a Clojurescript repl:
user=> '`(sum 1 2)
(cljs.core/sequence (cljs.core/concat (clojure.core/list (quote cljs.user/sum)) (clojure.core/list 1) (clojure.core/list 2)))