Syntax-Quote Alias Resolution
This is a short technical note on a new capability that landed in ClojureScript.
Currently in ClojureScript, if you use syntax-quote on a symbol that is qualified with an alias, resolution does not occur:
cljs.user=> (require '[clojure.string :as string]) nil cljs.user=> `string/reverse string/reverse
But, with the change for CLJS-1612, this properly reflects the behavior you'd see in Clojure:
cljs.user=> `string/reverse clojure.string/reverse
Thomas Jack gets credit for the fix—in this case, a nice change to a line in the compiler does the trick.
You might be asking, what does this get us?
Well, since syntax quote is often used in macros, this issue hasn't really caused much of a problem in the past. Consider a macro namespace like this one:
(ns foo.core (:require [clojure.string :as string])) (defmacro reverse-capitalize [s] `(-> ~s string/reverse string/capitalize))
If you put the above in a
.clj file and use it from JVM ClojureScript, things will work fine, with
But... things won't pan out so well with bootstrap ClojureScript, where macro namespaces are compiled as ClojureScript. In bootstrap, if you
(macroexpand '(reverse-capitalize "clojurescript"))
you will get
(string/capitalize (string/reverse "clojurescript"))
which won't work (unless you have
string aliased to
clojure.string in the namespace you are expanding into—but relying on something like that would defeat the entire purpose of syntax quote).
With the patch in place, the above macro expands to
(clojure.string/capitalize (clojure.string/reverse "clojurescript"))
and thus works perfectly well in bootstrap environments like Planck.