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.

blog comments powered by Disqus