Hacker News new | ask | show | jobs
by joncampbelldev 3230 days ago
If the author wishes to continue with js/react/redux then he needs to pick up a library like immutable.js to cut down that immutabiilty helper crap.

However, there is a better way ... lein new figwheel my-app, clojurescript+reframe gives you all the benefits of redux with an order of magnitude less boilerplate (also hot reloading and immutability by default without no extra setup or ceremony)

3 comments

Immutable.js is just another complication with another 60k size penalty with a few new negative drawbacks that he would need more complexity to solve. Author is already arguing against this approach.
Yep.

I've been working with React for years now, over several large projects. I still feel like I'm not used to it, and I still hate it. That's not normal.

We need to either figure out how to do this shit with mutable data structures, or we need a new language that's immutable by default.

ImmutableJS blows chunks. Yeah it "saves" code until you start doing the data transformation dance trying to figure out when and where to convert between plain JS objects and Immutable ones. Then you end up with some real ugly shit that'll trip up every new hire you walk through it (we use a higher order component that converts a component's Immutable props to regular objects, which incidentally is another import that like 800 unrelated files depend on...)

God help you if you don't use well commented code or Hungarian notation to differentiate between Immutable objects and regular ones. We all know how long good commenting practices last without thorough code reviews, and we all know how long those last in fast-moving environments, which is where React is most useful.

I guess a typed language would solve that. No, Flow and Typescript don't count.

Did you say "immutable by default"?

fanfare, fireworks, etc

CLOJURESCRIPT!!

sorry I just get really excited when I can mention it ... I'll go now

Why don't Flow or Typescript count? Our team uses TypeScript, mostly C# devs, it's been great. The main issue getting definitions for some less common libraries.

We haven't been using immutability.js because of the back and forth overhead between regular JS and immutable objects. Instead we use mutation checking of the Redux store during development you can make sure nobody is stomping on it by accident.

> The main issue getting definitions for some less common libraries.

That's one problem. The other is discipline. It's just way too easy to opt out of the type system. It shouldn't be a problem, but in the world of deadlines where every single front-end dev is intimately familiar with writing plain old Javascript, it is. All it takes is one manager that's a bit pushy, or one urgent production bug, and your codebase is on it's way to turning into a pile of shit.

I do love type systems, but IMO they have to be part of the language, it just doesn't work as an optional addon.

60k is hardly an issue, most hi-res images would be larger than that.

Plus due to the google closure compiler code can be minified with an aggression unknown to the typical js minifiers.

Add to that tree-shaking (removing unused code) and the long term size of your app is looking good.

I find clojurescript and specifically figwheel reduces language annoyanes and tooling problems. No more do i have to jump through hoops to get a project setup, or pick the latest and greatest build tool (grunt->gulp->webpack->jspm)

60k is a big issue if your users are on older smartphones. I'm tired of people equating the time it takes to download an image in the background with the render blocking cpu-crunching parsing that javascript requires.
Word. Such a stupid comparison.

You can add JIT too :) More JS, more time needed to reach decent runtime speed post JIT. React's first render is very slow.

A one-off event for a single-page-app which is likely to be used for more than a few minutes, and if performance of old mobile users matters then a native app is necessary, period.

If you're talking about a webpage then yes that would be awful.

Like the 966k of JS on your homepage? ;)

There are several things to consider with download time:

- is this a website? why on earth do you need react or anything for a website?

- is this a single page web application? then to develop with a medium sized team and an increasing feature set its nice to pick a language and library/framework that enable that.

- do you really care about mobile users performance and bandwidth? then you need a native app

This is all unrelated to the article, which is merely an uninformed rant about someone who doesn't understand the point of immutability and its use within functional programming as opposed to shoe-horning it into imperative code.

Your point about the need for a native app is going to raise hackles on web devs who want to "do mobile development" without paying their dues by learning the platform.
I was trying to get into ClojureScript a few months ago, intrigued by the tree-shaking of the Closure Compiler. I was thoroughly disappointed when my compiled hello-world yielded compiled code in the neighborhood of 70k. Surely I configured something poorly or didn't install the right leinegen packages, but coming from webpack this is a pretty discouraging out-of-the-box experience.

It seems there's some minimum (think Greenspun) JavaScript necessary to have a working SPA that handles DOM manipulation, network communication, state management, module management, events, et cetera, somewhere between 50k and 100k. I would love to be proven wrong about this. Maybe as native ES6 (or WebAssembly) becomes the norm this will be less the case.

There certainly is a minimum, especially when bringing in another language entirely. The point of the google closure compiler, with advanced opts, tree shaking etc etc is that the size will grow slowly as you add hundreds of your own source files and dozens of 3rd party libraries.

Choosing libraries shouldn't require careful examination of their output file size, especially if you only want half the functionality.

Are you implying then that the Closure Compiler mitigates or even eliminates the need to carefully examine the output sizes because of its optimization capabilities? If so, that's great, but I do remain skeptical about this, based partly on my experience described above. I don't mean this in a sarcastic or dismissive way but I was expecting to see something along the lines of:

console.log("Hello world!")

I realize this is a silly example for such a powerful tool but I just wanted to quickly get a feel for what the compiler is capable of before I committed a whole lot of time to learning the language. All I got out of the exercise was that the compiler creates a much larger minimum package size than I'd hoped. I'd appreciate any suggestions on a better way of proving its value for the cautiously curious. The language itself seems great, as does the community.

Perhaps it's just a different paradigm from npm/webpack, e.g. utilizing a rich built-in library rather than, yeah, carefully grocery-shopping for only the components you need? I'm not saying one is necessarily better than the other but it does intuitively seem that choosy shopping will tend to yield a smaller package size, at least for small-to-medium applications.

Clojurescript's bundle size for real world apps is decent, especially given the power it provides. If all you're doing is a 3 line JavaScript, Clojurescript won't benefit you. But if you're writing a complex application,it will beat or match your typical JS stack in terms of code size.

I suggest watching this:

https://m.youtube.com/watch?v=gsffg5xxFQI

https://github.com/rtfeldman/seamless-immutable is easier to use with 7kb minified size.
Yeah, if you're going through the trouble of using a transpiler, it's not clear why you'd stick with JS. Especially since Clojure gives you the option of using the same language on the frontend and backend, same as a JS frontend + Node.
I was just going to say this. Clojurescript+re-frame+figwheel is brilliant. It even has a good way to handle ajax and other async operations.