Fork me on GitHub

It might be possible to eliminate the single biggest cause of lack of portability to self-hosted ClojureScript and I’m interested in feedback: When using syntax quote in a macros namespace, currently in self-hosted, unqualified things like

turn into
and the fix / workaround is to explicitly qualify:
I’m struggling to think of a case where you would actually want the $macros suffix to appear in the resolved symbol. If you elide it, you appear to always get what you want. I’ve done an experiment that essentially elides $macros when resolving in this case (see elide-macros-suffix at the top here), along with eliminating the explicit qualifications we’ve littered the codebase with, and the unit tests pass: I’m thinking a similar argument holds for keywords: ::baz should turn in to :foo.core/baz, never :foo.core$macros/baz.


I wonder if you went as far as removing the core/ from cljs.core


(I can see in the diff above that you didn’t try)


need to pick your brains up, playing with advanced mode optimizations to finetune cljs-oops, have this interesting problem, see this source: the code should have no effect, oget is generalized aget, when I implement it using aget the code does not get fully DCE-ed, suprisingly enough when I implement it using goog.object.get, the code gets completely DCE-ed see txt files here I tried to play with different forms for a bit, but I don’t see what triggers it, any ideas?


fyi: here are generated sources before passed to closure compiler:


at least first two “gets” look pretty much the same to me and should be DCE-ed in both cases


Regarding the self-hosted “avoid $macros suffix when resolving” experiment from earlier today: It is also possible to take care of the same for keywords (dispensing with the need to qualify just for self-host (for example, ::conform-all can be used instead of :cljs.spec/conform-all). A change illustrating that: @anmonteiro With respect to the core/ construct—I’m pretty sure that’s a different thing altogether that was needed ever since the beginning of self-hosted, prior to syntax quote even qualifying. Regardless, I tried it and FWIW it didn’t work.


@mfikes: yeah I suspected it's a different thing. It doesn't even matter though, as your patch is much more focused on external stuff


If it pans out that nothing actually fails, this would be a big help for library compatibility with self host


@anmonteiro Yeah, it seems promising enough. I’ll throw it into an enhancement JIRA so the patch is readily available for people to try, and I’ll spend more time trying to break it as well.


@mfikes: one thing that might work too is removing some $macros special cases in the analyzer


Should make for (even if only a bit) more shared code


Yes, there might be more avenues to approach the general problem.


hrm I didn't mean it as an alternative


Ahh, gotcha… something like this could enable further cleanup.


More like, since you're eliding the $macros suffix in cljs.js there might be some unused branches in the analyzer now


The $macros stuff above is now captured in


(thinking aloud) I don’t know much, but I still have a feeling that the whole $macros suffix idea is a hack with unintended consequences. Isn’t there really some other (hacky) idea to explore to keep both macros and fns in the same namespace? This problem would go away.


@darwin Yes, we've all seen this particular pattern many times (where you reuse an existing mechanism internally to achieve something but that use ends up leaking out). I think it has been a workable pragmatic solution to the problem, but I agree, it would be nice if there was some other way to keep them separate. Perhaps the same class of thing occurs for vars and namespaces in ClojureScript, but in the opposite way: Since nothing is keeping them separated when realized as JavaScript, they can collide.


one such wild idea would be to explore storing macros in second level of namespace objects’ prototype chain, instead of looking into $macros namespace, runtime would look to the second hop of prototype chain if it was already shadowed by function with the same name, or something along those lines