Problem statement
Authors writing a macro for clojurescript don't have a facility for resolving symbols to vars. That is: to expand at macroexpansion time a symbol to its fully qualified form:
+ ;; -> cljs.core/+
s/def ;; -> cljs.spec.alpha/def
In the JVM, this is certainly a possibility.
In cljs, there's no such possibility, at least cleanly.
- There is the
cljs.core/resolve
macro, but I'd say that it is aimed to be used in cljs final code, not in macros targeting cljs.
- Specifically,
cljs.core/resolve
expects a quoted symbol, which is an unnecessary restriction for macro authors.
cljs.core/resolve
returns a new var, not the original var. This drops user-provided metadata.
- Macro authors, consequently, cannot observe user-provided metadata for performing macroexpansion-time custom logic
Request
Make cljs.core/resolve
more flexible, or create a separate resolving function specifically aimed at macro authors
Use case
I had some existing JVM macros, using resolve
at macroexpansion time that needed a port to cljs. i.e. this request comes from a practical need.
Workaround
The following function works fine, satisfying the described requirements.
However it's reasonable to think it's playing with cljs internals, and that accordingly it may break with new cljs releases.
(defn cljs-resolve
[env sym]
(let [[var meta] (try
(let [var (cljs.analyzer/resolve-var env sym (cljs.analyzer/confirm-var-exists-throw))]
[var (cljs.analyzer/var-meta var)])
(catch Throwable t
[(cljs.analyzer/resolve-var env sym) nil]))]
(some-> var
:name
(vary-meta assoc :cljs.analyzer/no-resolve true)
(vary-meta merge meta))))