When investigating what the closure compiler does with cljs output, I discovered the following:
Google closure does not eliminate unused var reads. This means that e.g. a deftype (deftype A []) which compiles to workbench.foo.A = (function (){ .... snip .... }); workbench.foo.A; // <-- because of this does not get stripped out of the compilate if A is never used even with advanced optimizations. What can we do about this? I tried changing clojurescript's deftype macro to not return the type itself. This shrank a clojurescript hello world from *about 100k to 75k*. Quite an improvement for a single line change. Obviously, we do want deftype to return its generated type, so my next attempt was to eliminate the unused reads with a compiler optimization. My first cut works by adding an entry point function for an optimizer, which gets passed a single toplevel form from the analyzer at a time. You can see the draft implementation here: https://github.com/bendlas/clojurescript/commit/2152ffff138f59fe1401f7537a26c68bd769bebb Output from this modified compiler generates file sizes similar to the version with the modified macro. Of course we don't want a single static entry point for a hypothetical optimizer. Instead I'd like a variant of the compile function, that takes optimizations as a parameter. Such optimizations should also be able to operate globally under a closed world assumption with explicit exports. == Before implementing a hook to enable whole program optimizations, I'd to get some feedback on my proposal on how to do it: a) Have the compiler gain a notion of a compilation unit, expressed as a sequence of top level forms. Compilation units are conceptionally similar, but orthogonal, to name spaces. A CU can be as small as a form on the REPL and as big as a whole application. In real world applications, namespaces and compilation units will often align. b) Compilation units are embodied as a function (compile-unit env forms dst optimization) in cljs.compiler, which returns an updated env and serves as the base for all other compilation functions. optimization is a function, that gets passed the sequence of analyzed toplevel forms and returns a possibly optimized version, which is passed to emit. c) cljs.optimizer contains common code like builtin optimizations, optimization combinators and analysis tree walkers. Each optimization checks its own preconditions (assign once? no eval? no var? ... getting ahead of myself) Is there interest in including hooks for optimizations in CLJS? If so, is the approach outlined above reasonably straightforward or do we need a confluence page? kind regards -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en