Every single concept they hacked on to JS (immutable types, atom, declarative DSL, etc.) is a first class concept in CLJS - and it works beautifully even when building on top of their JS implementation - I feel sad they didn't just go "all in" on something like CLJS - they have more than enough resources to fix any implementation issues (ie. they have the resources to create a compiler that would generate code you would hand write with immutable.js and JSX - after all they are funding stuff like Flux and babel).
I understand why they didn't do it but it still feels so bad to see a hack in a place where a beautiful solution was just a step away.
(it's a joke)
Plumatic Schema [1] goes a long way towards narrowing that gap though and I cannot recommend it enough. Whether it goes far enough in terms of safety is certainly a matter of project type/size and personal preference, but to me, for my kind of work so far it does and they'll take away my ClojureScript when they pry it from my cold, dead hands. :)
Also (and slightly off-topic) the combination of clairvoyant + re-frame-tracer [2][3] (+[4] for some minor, so far mostly React Native-relevant additions) should be way more popular than it seems to be. It's definitely one of the most important tools in my toolbox and completely changed the way I approach debugging.
[1]: https://github.com/plumatic/schema [2]: https://clojars.org/day8/re-frame-tracer [3]: https://clojars.org/gnl/re-frame-tracer [4]: https://clojars.org/gnl/clairvoyant
At least for backend stuff, this is no worse than Clojure.
Give it a try :) Ping me if you have any questions.
For a deep dive you'll want to read resources about parsing. To name one article that came up recently on HN, take a look at "Why Parsing Tools are Hard" [0].
[0]: http://blog.reverberate.org/2013/09/ll-and-lr-in-context-why...
Please take a look at the draft JSX spec [0] for details.
Here is some of my Coffeescript render function, it is much more elegant than the equivalent JSX.
render: -> div className: "btn-group" role: "group" style: width: '100%'
for option in @props.options
label
key: option.value
className: @buttonClass @state.selected == option.value, option.bsColor
style:
minWidth: (100 / @props.options.length) + '%'
input
type: 'radio'
required: true
name: @props.name
value: option.value
checked: @state.selected == option.value
readOnly: false
onClick: @handleClick
"data-key": option.value
option.labelAnd the best parts are already here in es2015.
So as soon as a developer realizes that it's just sugar over JS, they are in a world of trouble, invariably trying to stick an if-else into it. If everyone had enough grounding in language theory to tell them: "JSX is just a JS primary" all would be well, but alas, that's putting the cart before the horse.