Done!
I was close with my guess in the last post. What ended up working was
(let [name (munge (symbol (str (-> env :ns :name) "." (munge (str sym)))))])
For some reason, (name sym) would crash the compiler from the
parse method but it wouldn't from other functions caled from the
parse method. I finally gave up worrying about that and just used
(str sym) instead, since that is guaranteed to be the same in this
case – there is an (assert (not (namespace sym))) just before the
let line. I gave up on worrying about it, but someone who knows
more about the compiler than me might want to try to figure out why
it is.
I also needed to allow names defined in cljs.core but redefined in
another namespace to be called or referred to. This involved
changing the resolve-existing-var function. Again, cljs.core is
hardcoded:
(let [full-ns (if (and (core-name? env sym) (nil? (get-in @namespaces [(-> env :ns :name) :defs sym])))
'cljs.core
(-> env :ns :name))])
I added the second test: it simply asks whether the variable has
been defined in the namespace. If it hasn't, and the variable is
defined in cljs.core, only then is the namespace set to
cljs.core.
Remove the macros
It was also necessary to remove many of the macros from core.clj
in order to redefine the functions that I needed to in my project.
As I noted earlier, my project is to implement rationals in
Clojurescript, so I need to redefine most of the functions that work
with numbers. (At least, that is the way I am implementing it --
there may be a better way that I don't know about.) Many of these
functions were implemented twice: once as a macro in core.clj and
once as a function in core.cljs. I am obviously biased towards
being able to redefine these functions, so I think the macros should
be removed, but at least one of the implementations is redundant.