Hacker News new | ask | show | jobs
by hellofunk 2853 days ago
> If you have ever tried to use ADVANCED_OPTIMIZATIONS in Google Closure Compiler, you know that this is extremely difficult even when you write all the code yourself

Perhaps, but it’s quite nice when you use languages that were built to support Google Closure from the beginning, like Clojurescript. Then it is painless and built into the build process automatically, and you get to benefit from all the other great advantages of advanced optimizations in Google Closure that this article does not mention, and which Elm still cannot support or offer an alternative for, like automatic loop unrolling and other notable performance improvements.

4 comments

Leveraging what is already in Closure Compiler was (and is) such a brilliant maneuver by ClojureScript - over the last few years I've seen various current tools gradually gain optimizations that were already in the box with ClojureScript when I built some things with it "forever ago".

The big surprise though, is how few other new library/framework/platform/languages/whatever have followed this path.

Google Closure Compiler doesn't get any use because Google has entirely neglected it for a decade. They could have been where TypeScript is today, but instead they entirely ignored external users, hardly staffed the project, and now have an inconsistent mess with a non-coherent super-buggy type system and no users. It's a disaster, and if you try to do anything non-trivial it will fall to dust.

Good riddance to that abandoned pile of rubbish, and fuck Google management for letting it get so bad. They had a five-year lead on the rest of the industry in serious JavaScript development, and now they're ten years behind.

10 years behind? There might be competitors (perhaps) but the Closure compiler does quite a lot of impressive engineering -- not just the tree shaking and identifier renaming that Elm is trying finally to do, but also automatic function inlining, loop unrolling, numerous other performance tweaks. And it all works fantastically, very reliable. I've been using it for 4 years on a huge codebase and I've not once had a problem that was due to the Closure compiler. It's robust and stable.
This is false. It's not abandoned. There are many commits per day and that wouldn't happen without a dedicated team [1]. There are frequent releases with impressive-looking changes [2].

But this does look like a team that's focused on the needs of Google's internal customers? An external-focused project would have better docs and do more outreach.

[1] https://github.com/google/closure-compiler/commits/master

[2] https://github.com/google/closure-compiler/wiki/Releases

CLJS is awesome too! For what it's worth, Elm 0.19 likely also works with Closure Compiler in Advanced Mode - it did in a quick proof of concept I tried, but obviously that's something you want to be really confident in before suggesting people use it!
Did Elm change how it uses strings as a fundamental part of certain language constructs? That would break the advanced optimizations. According to the github issues tracker as well as mailing list comments from last year, these were not likely going to change in the language and therefore advanced optimizations are very fragile and likely to break on code in subtle ways.

Note that Elm has always appeared to work on the surface with advanced optimizations, but the bugs would creep in and show up eventually, and the official advice has always been not to use those optimizations.

Just glanced through the code for 0.19 (I originally wrote an issue about the advanced opts incompatabilities for 0.18) and the things which caused problems before are gone.

That's not to say that there are not other issues, though.

The "problem" with ClojureScript's integration is that you have to be careful when integrating other javascript libraries (which ClojureScript encourage you to do to save code size) as they might not be compatible with advanced mode. You could also write code in cljs which isn't compatible with advanced mode. Elm doesn't have this problem.

Elm also outputs smaller assets than cljs+closure.

That being said, I do love cljs, having used it on numerous projects myself :)

This is almost never a problem since you simply use normal externs file for whatever library you are using. You never take an external library and run it through the closure compilation process, only your clojurescript code is put through those optimizations.
> This is almost never a problem since you simply use normal externs file for whatever library you are using.

"almost never" and "simply use externs file (which you may or may not need to write yourself)" does underpin my point that you have to take care. I'm not saying it is necessarily difficult or takes a long time to get right, but it does require that someone makes sure everything survives the advanced opts compilation.

This has burned me on a past cljs project, it's not even a concern on my Elm projects.

I guess it all boils down to how you want to spend your time. Elm typically requires at least 4x the lines of code and at least 10x the time of dealing compilation issues compared to Clojurescript. So ultimately I think this is just a question of a desired workflow in one language vs. another. Any time spent on Closure-related issues (which have never personally bit me on any project -- I just use the library itself as an extern file and everything has always worked with no effort), is made up for with the fast development cycle on Clojure projects. Even including the increased runtime debugging in Clojurescript vs. Elm, Clojurescript has always provided me a significant productivity advantage over every other JS-family toolkit.
Your whole reason for replying to the submission seems to be "heh, ClojureScript already had this, but better ;)" but I'll chime in to say that the differences between Clojure and Elm, having used both extensively, especially become apparent when it comes time to refactor.

I would say that Elm lets me refactor front-end code fearlessly. I can confidently rewrite abstractions that are so fundamental that I'd be stuck with them forever in a dynamically-typed language because the rewrite would be so much more costly.

It reminds me of when people say that Mongo is better than Postgres for prototyping because it doesn't have a schema. In my experience, the very concept of having explicit schema transformation as the schema changes is why I'd consider Postgres to be better for prototyping: it's precisely the time when your schema is changing the most.

Of course, if we could unanimously agree on these trade-offs, then we would all be using the same stack and there would be no dynamic vs static typing debates.

I agree there are valid tradeoffs. In my experience, because Clojure code is so concise and tiny by comparison to Elm or most other language's, refactoring is usually replaced by actual re-writing, since the small amount of code is just as easy to architect again, maybe just saving particular functions, rewriting others.
Your experience is different than mine, but I don't believe externs inference was in last time I built a cljs web app.

I still use Clojure as a backend language (I'll never give up Datomic) and while writing code in Clojure is usually faster, I spend much, much more time in debugging, often because of type errors, and especially after re-factoring. In Elm I spend more time up front, but less time overall.

I've been writing Clojure for six years now, Elm for three. There are definitely usecases where I'd pick Clojure(Script) over Elm, but for those usecases where it doesn't matter which of those you pick, I'd choose Elm any day of the week.

This is not to say Clojure(Script) is bad. In my opinion, Clojure and Elm are the best languages around.

Yes everything I write in Clojurescript gets ADVANCED_OPTIMIZATIONS and works fine. Also I have found that I get a lot more gain without having the language get in my way with functional programming vs strong static typing. Especially when you want to interact with the rest of the JavaScript ecosystem. The development story in Clojurescript is amazing too with figwheel.