I’m using resolve
in my program in several places. And I don’t really know how to do this correctly. I expect the calling function (someone using my library) to provide a quoted hierarchical list which designates particular semantics which are explained in the library documentation. In that quoted list, the caller is allowed to name classes such as Boolean
or java.lang.Comparable
or clojure.lang.Symbol
.
Such a list might look like the following in the client code.
(deftest t-canonicalize-pattern-subtypes
(testing "canonicalize-pattern with subtypes"
(is (= 'Number (canonicalize-pattern '(:or Integer Number)))
"Number")
(is (= '(:* :sigma) (canonicalize-pattern '(:or Number (:not Number))))
"sigma")
(is (= 'Integer (canonicalize-pattern '(:and Integer Number)))
"Integer")))
(deftest t-canonicalize-pattern-14
(testing "canonicalize-pattern 14"
(is (= '(:or (:and
clojure.lang.IMeta
clojure.lang.IReduceInit
java.io.Serializable)
(:and
clojure.lang.IMeta
clojure.lang.IReduceInit
java.lang.Comparable))
(canonicalize-pattern '(:and (:or java.io.Serializable java.lang.Comparable)
clojure.lang.IMeta clojure.lang.IReduceInit)))
"and-distribute")))
My code examines the given symbol to determine whether it really names a class. This is done with code similar to the following:
(and (symbol? type-designator)
(resolve type-designator)
(class? (resolve type-designator)))
The problem is that resolve
is documented to search in the namespace *ns*
. However, when the user runs my program he might have set his repl namespace to anything. So relying on the current namespace is certainly not the correct thing to do.
However, if I use (ns-resolve (find-ns 'clojure.core) type-designator)
or even the namespace my program is written using, (ns-resolve (find-ns 'clojure-rte.core) type-designator)
then the call to ns-resolve
won’t notice classes the user has defined, nor variables the user has defined such as (def Symbol clojure.lang.symbol)
.
QUESTION: How can I figure out how to resolve the symbol the user has given me?
My original implement of this program was in Common Lisp where this kind of problem does not occur. In CL the reader resolves the symbols to the correct namespace. As I understand it, in clojure, this namespace resolution must be done at runtime, when there doesn’t seem to be enough information to do so.