ClojureScript w/o Google Closure


#1

Hello folks!

I don’t want to be that guy but I will ask anyways: would it be a good thing to devise a plan in case Google Closure gets shut down/deprecated?

Reading http://neugierig.org/software/blog/2018/09/typescript-at-google.html today and I do not like a single word of it :slight_smile:

Not saying it will happen, not saying when. Just would like to trigger some light conversation around it.


#2

Not saying the day won’t come, but they mention they’ve integrated typescript with Google Closure compiler. So it doesn’t sound like it’s going away.


#3

I think clojurescript would be much faster and lightweight without the runtime depending on google.closure library, which is a piece of bloatware. I am not sure how people can design such unintuitive libraries? Rich has designed an excellent language in clojure but some of his design decisions are hard to understand. I actually like the architecture of RacketScript https://youtu.be/n4UQLiByP1Q


#4

It doesn’t it’s true. I don’t also know whether the compiler would be necessary if no optimizations are to be used.

One thing would be good to do is to check for which purpose the GCC is used and if we could put a layer (maybe there is one already) of abstraction on top so that we can swap in whatever alternative.

Definitely early for that and low priority. I know David would tell me to dedicate my energy somewhere better :slight_smile:


#5

Are you sure it uses GCC somewhere?


#6

Is this really a problem with advanced optimisation?


#7

I think if there were a compiler which compiled cljs -> Js (No Dependencies) compared to cljs -> Js + Clj/Runtime + Goog. Former would be better than an optimization compiler could produce.
Also i dont know anyone who reaches out to goo.dom or goog.Something to get anything done.
Most people reach out to .js/Api in the browser or other cljs libs.


#8

I really doubt it would be better then the optimized output. Nothing beats GCC in terms of optimization. It leaves you with only the lines of code that are actually used.

With it, your output is as free as bloat as is possible honestly. I don’t think anything else in the JS world is as good.

That said, it comes with a high price. It makes things a little more complicated to work with. So maybe the trade off for you isn’t worth it.

Also, I believe, that a lot of the CLJS runtime depends on GCC. So it’s hard to say how big it would be without GCC, as it would need to re-implement some of GCC.


#9

Complained about if we can step away from Google Closure before when I found ClojureScript not work with Webpack and npm packages in the old days. Thheller told me optimizations of Google Closure is really important to ClojureScript. I was somehow convinced.

However I’m still thinking that the Webpack world still works without optimizations provided by Google Closure. At least it works fine and healthy. And actually I would love to see ClojureScript become closer to Webpack ecosystem by moving away from Google Closure.


#10

This is true only in theory. Specs cannot be trimmed for instance and many other things are actually keeping trimmable code from being deleted. Not saying GCC does a poor job, it is a mix of the two world that makes this not really optimal. Cannot recall the details now but can look it up.


#11

I actually read that blogpost in a positive way. Google is investing in Closure to optimize typescript compiled code. At least that was my reading.

Sure closure isn’t perfect but it’s dead code elimination is probably as good as it gets. Calling Closure bloatware doesn’t really make sense to me. You get what you use. And you’ll get it in a way that’s compatible with various older browsers. I get that the necessity for this is decreasing but I wouldn’t call it bloat as such.

That said it admittedly would be cool if the ClojureScript compiler would emit modules in some format that are understandable by the Closure compiler as well as other popular tools like webpack.

Good point. Here’s an example of this preventing unused Rum components from being DCE‘d. The issue is fixable but it’s unfortunate that it occurred in the first place.

With regards to spec that’s a bit of a bummer. I guess it’s due to the global atom that is opaque to Closure? Would be curious if @mfikes or @dnolen have thought about this in any way.


#12

Clojure runtime after compilation is quite big, i am not sure the optimisation is even working for all parts of the code. A compiled tetris game in cljs is around 602Kbytes while in JS it could be under 40K.


#13

I might be misunderstanding but there is no “Clojure Runtime” in Javascript compiled by ClojureScript. There are persistent data structures and other stuff that take up some space in the bundle but these are the reasons you use ClojureScript and so whatever you do they likely would stay around anyways.

Tetris being much larger in a CLJS codebase could be due to all kinds of reasons (e.g. React being used) so it’s hard to discuss these things without actual code.


#14

I certainly cannot comment on what Google is doing but they are still actively working on the Closure Compiler.

I made quite a big commitment using the Closure Compiler within shadow-cljs and the reason for this is quite simple: There is nothing comparable available today. webpack is slowly getting better but nowhere near as capable. The JS world is going to realize that you are going to need to sacrifice some weird patterns to get some of the more :advanced optimizations.

Now lets not confuse the use of the Google Closure Compiler with the use of the Google Closure Library. You can completely remove the Library and still use the Compiler. The Library however has vast amounts of really high quality. There is a gigantic advantage to having a sane “standard library” available and not having to piece together random npm modules. Yes, the UI parts are not using the latest hype tech but you don’t have to use them.

No, it is not “bloatware”. No, ClojureScript would not be any faster or lightweight without Closure. That is just a completely false statement. ClojureScript only uses tiny amounts of the Closure Library directly so you could easily swap those out. Why would you though? The code is guaranteed to be compatible and heavily tested, I take that over a random npm lib any day.

Did you know that a big chunk of JS libs use the object.assign or object-assign npm packages? Both provide Object.assign polyfills but the JS world apparently couldn’t agree on the package name so now it is quite common that both end up in a build. The amount of duplicated code in some JS libs is mind-boggling. It is an absolute mess. One of the major ideas behind Closure and the reason ClojureScript uses it is whole program optimizations. This means that you take unpackaged raw code, compile it and optimize it together removing all the “bloat”. It takes a while to realize how important this idea is and the majority of the JS world has not realized this yet.

shadow-cljs actually addresses many of the issues the author is complaining about, so most of them I consider solved problems for ClojureScript + Closure + npm.

As a side note: I do think that it could possibly be useful for the CLJS compiler to emit ES6 code but that would not in any way affect usefulness of the Closure Compiler + Library.


#15

That actually makes a lot of sense, i used Om. But since you have mentioned would get rid of it and try again to see how much size it sheds. Thanks!


#16

I could be wrong but my sense was that the less code the interpreter needs to read the faster the faster your program would be interpreted. The less code it needs to keep in memory the faster it will lookup functions that we invoke.


#17

The whole premise of Closure is to only leave you with the code you actually use. The result is optimal and will not get much better (certainly not with webpack). Yes, there are some things even Closure won’t remove (specs were mentioned) but if you pay attention the result will be pretty darn good.

Sure a CLJS build will be bigger than plain JS builds. You do however get immutable data structures and other nifty things. If you use comparable JS libs (eg. immutable-js) the end result will quickly become much larger.


#18

Take a look a the commit graph for the Closure Compiler https://github.com/google/closure-compiler/graphs/contributors

There appears to be a lot of activity and it appears to be growing. Nothing lasts forever, but…


#19

Spec is alright, i dont think many people use spec in production and specially not in cljs. So that isnt a problem. But i understand your point may be i should really do some tests to test my theory. Thanks!


#20

Believe me you’re wrong here. goog.obj is officially recommended over Cljs’ aget for JS object interop. The go-to library for doing Ajax in the browser is just a functional wrapper over various goog.xhrio etc namespaces. Google Closure Library maybe heavily OO oriented but it’s quite useful. I do use several stuff in a big CLJS project and I’m happy not having to rely on npm libs.