| >I love writing Clojure(Script) code, but I hate reading it. It fits perfectly with the way I think (when I'm writing code), but horribly with the way I try to understand code I wrote months ago. I've used Clojure for 2 years - I feel the same way. It's a wonderfull language that exposed me to great ideas and showed me that simple things can be simple but boy does it get nasty when things don't fit the provided primitives and actually start getting complex - the language has no tools to deal with complexity it can't simplify. Also a - for CLJS from me is that they haven't abstracted out the (do ...) macro from channels (ironic with all those talks harping on how simplicity is about disentangling things). The biggest pain in JS/DOM ecosystem is shitty semantics, poor standard library and callback stacks. ClojureScript fixes first two really well and does a half-assed job at fixing the last - channels are too much overhead for such task (from both performance and conceptual POV - putting a queue in front of every callback is silly in a single threaded model). I feel like Elm is a language designed to explore an idea not to be practical, this is why I haven't tried using it for anything serious. TypeScript has potential in theory to bring ES6 + type safety to avoid semantic pitfalls - but in practice it's supposedly biggest strength of leveraging the existing JS ecosystem is also it's greatest weakness in that you're still left there with shitty JS ecosystem with zero consistency, most libraries deal with JS pitfalls in their own unique way which doesn't mesh well with other approaches or with TS, fragmented build, packing, dependency management, module loading tools - all trying to solve the same problem in different and incompatible ways - it's just a pile of junk that wastes more time trying to reuse stuff than it takes to build anything - which is probably why most of it is in the state it is - and very few things are actually maintained so the argument that reinventing something means you need to maintain it yourself is not really convincing. Dart has a built in package manager, has had tools for dealing with async code for a while now (both async/await and streams), it's familiar to the Java/C# devs but it's surprisingly concise (quite a few nice touches like constructor property-parameter mapping or => getter syntax for tedious stuff), the standard library is great and avoids all the JS pitfalls. The downside is that you still need JS interop because there's no way around it (for eg. emscripten) - and talking to JS from Dart is still nasty - much more involved than CLJS or TS. Having used all 3 mentioned for non trivial work I like Dart the most and the new JS interop could make it even better. |
The only unpractical part I'd noticed was its perspective on reusing components, as seen in this overview under 'Nesting' [1]. That bit of explicit routing aside, may I ask what dissuaded you from using the language seriously?
[1]: https://gist.github.com/evancz/2b2ba366cae1887fe621#nesting