
The Case for React.js and ClojureScript - mpereira
http://murilopereira.com/the-case-for-reactjs-and-clojurescript
======
chao-
Almost everything I've seen about React makes me happy. However there are some
parts for which I do not understand everyone else's excitement. This
presentation contains a great example on slide 53 when it says:

"No Templates!"

With an exclamation mark, even! What it doesn't tell me, is what is wrong with
templates in the first place? I happen to like them versus the feeling the
alternative gives: Awkwardly-mixed-paradigms and using string concatenation
while attempting to represent one language within another.

Can someone who dislikes templates explain? Or maybe explain what a template
means to you, as perhaps we're not all thinking about the same thing when
someone says "No Templates!"

~~~
zoomerang
I agree very strongly, but I can understand the opposite viewpoint.

For me, I like to write HTML in HTML. While I'm primarily a backend programmer
these days, I've spend a considerable portion of my career writing HTML, so
I'm very familiar and fluent in it.

As such, to me, writing HTML as HTML with annotations for data bindings and
loop is a much better approach. Anything else just gets in the way of my
workflow. AngularJS is the only tool I've used so far that really nails this
properly. (At least since Zope)

However a lot of developers aren't HTML guys. They think in code, and to them
HTML == DOM == a Tree structure. So it makes sense for them to be returning a
tree.

I quite religiously think the latter is the wrong approach and results in less
maintainable code. Instead of having a single template with the entire page
clearly laid out, you end up with small snippets of HTML rendered all over the
place.

This becomes even more jarring when you're working with designers that aren't
coders. I manage a team of 7, and Using HTML-based templates means that my
designer can write fluent AngularJS templates without developers having to do
a thing. The alternative is for the designer to mock something up, and then
for developers to cut it up into tiny little pieces and rewrite it in whatever
DOM abstraction is the flavour of the month. Try reskinning a site made up of
hundreds of small snippets of DOM vs a few complete HTML templates - the
latter is far easier.

Some developers like to write Dom in Javascript because they know Javascript
and don't want to learn another language.

To me, the idea that templates are bad because somebody doesn't want to learn
another language just reeks of anti intellectual bullshit. Angular template
aren't difficult.

I'll finish off this post by adding that I _much_ prefer reactive code over
imperative observables or dirty-checking, but Angular templates work so
ridiculously well it'd feel like a step backwards moving to another framework
that didn't have them. My dream toolchain would use something similar to
Angular templates, with FRP code behind the scenes.

tl;dr To somebody used to writing HTML, building a page by emitting snippets
of DOM inside Javascript is about as annoying as trying to write Javascript by
emitting snippets of code in XML.

~~~
joshma
Have you looked at JSX[1] yet? Because I feel it was invented exactly to
address your tl;dr - you're writing something that is very close to HTML
inside your Javascript, so it definitely seems easier than writing JS snippets
in XML.

Also, although I've found that ReactJS tends to encourage a more modular
component structure (which I'm personally a fan of), there's nothing stopping
you from laying out large chunks of a template instead of small snippets.

[1] [http://facebook.github.io/react/jsx-
compiler.html](http://facebook.github.io/react/jsx-compiler.html)

~~~
zoomerang
Yep - JSX solves many of those complaints. (My post was more of a reaction to
the 'templates are bad' tone than React itself). I'm not a fan of JSX as a
templating language, but it's good enough.

I still feel that React encourages a style of development that pushes small
snippets of HTML rather than full-page templates. Depending on your
development style and the type of application your building, this may or may
not be desirable. (If you're building something that's inherently component
based, then it's good. If you're building something that's not, then it just
adds boilerplate).

I'm working on a pretty large Angular project at the moment - it's been
utterly fantastic, although it does have its warts. (Primarily around
maintaining state ). React.JS claims to solve many of these issues, although
I'm not entirely sure it solves them in the right way. (I'd prefer to aim for
a more FRP approach personally).

~~~
Myrmornis
_I still feel that React encourages a style of development that pushes small
snippets of HTML rather than full-page templates._

I work with Django currently. For dynamic content, in order to avoid
repetition, we use includes and template inheritance. So that goes in the
direction of _small snippets_ rather than _full-page templates_. Do you not
have to do anything similar with your angular templates?

~~~
ludwigvan
Don't forget inclusion_tags. They are really poorly named though, they would
have been much more popular had they been called "components".

The primary difference between an inclusion_tag and an include is that with an
inclusion_tag, you can define the interface of your component with much more
granularity. By default, each inclusion_tag is passed an empty context,
whereas an include accesses all the data in the current context. This way, an
inclusion_tag provides a much better isolation.

One other advantage is, this way, if you need to include some Python logic,
you don't need to do all in a single view function. So, assume that your view
function responds with a page with 5 components in it. If you follow the
include path, all the data preparation goes into the view. With inclusion_tag,
you can basically drop to Python at any level. For example, let's say you are
viewing a list of questions and answers. Views do not allow you to attach
Python code at the question or answer level. You can do it, but you have to
traverse inside the data for the whole feed. With an inclusion tag, you can
"attach" to the processing at the question or answer level.

For Angular folks, an inclusion_tag is very much similar to an angular
controller. The primary difference there is again by default, Angular
components inherit all the scope (similar to JS scope or Django's include
scope), whereas react by default does not pass any variables, you need to pass
them _explicitly_ as props to the children (in angular, you need to add some
information at the "directive" level to achieve this level of isolation).

One alternative for keeping the scope clean while using include is to use the
"only" flag though, so if you are not going to do any data processing, that is
easier.

That said, the use of inclusion_tags is a bit cumbersome, and I'm not making
much use of it lately since I have switched to react.js and basically building
my components in JS instead.

------
numbsafari
Decent presentation.

Something that would be really helpful for me, as a consumer of these slides,
would be to have a better setup between the slides with just code. I get the
impression that, with some of those slides, you would be saying something
while that slide was up. But without your audio, I have no idea what that is
and so the slides are confusing at that point.

So, if you are giving a presentation that goes best with audio, it'd be
awesome to have the audio. If you are giving a presentation with the goal that
it can be consumed without the audio, would it be possible to have your
speaker notes show up on the slides where you are showing something and
talking?

All that said... I'm very interested in looking at react.js. I don't know that
it would work with the team that I am working with now, mostly because the
team that does the front-end work doesn't do JS programming so much as they
format HTML and CSS.

Does anyone know of something that mixes react.js with templates? Any
success/failures in that regard?

~~~
dustingetz
I am the lead guy of a React library: [https://github.com/wingspan/wingspan-
forms](https://github.com/wingspan/wingspan-forms)

All the design work was done by an actual designer who maintained the JSX
directly. He knows enough javascript to get around but basically he just
pretended it was HTML. JSX is awesome because it means designers can commit
directly without involving engineering.

~~~
ryanjshaw
As a developer I'm interested enough to try React.js on my next project.
However, it seems like designers will still need to write Javascript to
implement repeating structures (tables, lists, etc.)? Just like designers
don't want me fiddling with their HTML and CSS, I don't want them fiddling
with my code -- but React.js's model seems to make such a separation of
concerns impossible?

~~~
dustingetz
You can of course continue to have designers handoff markup/CSS for
integration by engineering. But if your designer can handle basic javascript,
you needn't involve engineering at all. In practice it doesn't really matter
if the individual views are sloppy javascript since React separates concerns
so well.

------
baddox
I think I get it. Can anyone let me know if this description of my
understanding is close to correct?

React lets us program reactively by rerunning the entire JavaScript
description of a component every time its data changes. This lets us use
"normal" JavaScript code to describe our component (as opposed to explicitly
attaching Ember dependencies or using Angular ng-* attributes). This normal
JavaScript code will describe the component at all points in time, not because
there is two-way binding, but because any change in the state of the component
will cause the entire JavaScript function to re-execute.

React's virtual DOM, then, doesn't have anything to do with reactive
programming per se. It's just the way that rerunning JavaScript code for every
single data change can be made performant.

~~~
hcarvalhoalves
Have you ever programmed graphics?

To make a paralell, usually in graphics your main loop reacts to events (user
input) and you change some internal state in some object(s). Finally, you get
all those objects that know how to render themselves, see what's relevant and
render the whole scene. You don't have to care about pixels, you just react to
events and blit a representation of the entire state.

React.js is the same, the difference being your components "render" themselves
to the DOM, and because it's a tree, it's naturally composable. It's still a
pipeline taking state and outputing a representation though.

~~~
seanmcdirmid
That is retained rendering with scene graphs. Immediate-mode rendering is
obviously very different.

------
the_watcher
The simple v. easy section was interesting. Those words are probably used too
often as synonyms. In reality, we should think of them differently - something
easy is something that a lot of people should be able to replicate without
much expertise, whereas something simple, a lot of people should be able to
understand (what it does, the purpose, how to use what was built), but not
necessarily replicate themselves. I think that is probably the right
distinction, although it is a very fine one.

~~~
KingMob
If you haven't seen it before, check out Rich Hickey's talk on the topic:
[http://www.infoq.com/presentations/Simple-Made-
Easy](http://www.infoq.com/presentations/Simple-Made-Easy)

~~~
the_watcher
Thanks! Never had seen it, really interesting.

~~~
ludwigvan
You're off for a retreat if this is the first time you are seeing this talk!

~~~
lgas
And in case you missed any of the others, this is a great list:

[http://thechangelog.com/rich-hickeys-greatest-
hits/](http://thechangelog.com/rich-hickeys-greatest-hits/)

------
haberman
> Immutable data structures make React's diffing algorithm really smart.

I was very intrigued when I heard this claimed in a blog article a while back.
So I investigated this claim deeply and was not entirely convinced. For
example, the immutable approach to tree diffing actually requires more work in
some cases, since you always have to diff from the root.

I wrote more about this here: [http://blog.reverberate.org/2014/02/on-future-
of-javascript-...](http://blog.reverberate.org/2014/02/on-future-of-
javascript-mvc-frameworks.html)

~~~
swannodette
This actually isn't true anymore that you always have to render from the root
in Om. We've already changed component local state to avoid this, and likely
in the near future this will be true in the props case as well.

~~~
haberman
Thanks for the update -- could you explain how this works? Do you figure out
internally-to-Om which subtrees have actually changed and call setState()
and/or forceUpdate() on them?

The original article said that Om doesn't use setState() at all -- has this
changed?

------
coolsunglasses
I'd rather use a typed language which is why I'm following the development of
PureScript ReactJS bindings.

[http://www.purescript.org/](http://www.purescript.org/)

[http://tryps.functorial.com/](http://tryps.functorial.com/)

------
juliangamble
David Nolen (@swannodette) has been doing some great work in Om with
ClojureScript and React. In addition to the links posted - this is a link on
why ClojureScript's data structures (functional with structual sharing) make
implementing undo trival in Om [http://swannodette.github.io/2013/12/31/time-
travel/](http://swannodette.github.io/2013/12/31/time-travel/) and this is a
link on data binding in Om with :instrument
[http://swannodette.github.io/2014/02/27/taking-off-the-
blind...](http://swannodette.github.io/2014/02/27/taking-off-the-blindfold/)

------
programminggeek
Um, a lot of what I see in React.js reminds me of Knockout.js but without the
data binding on the view side. I know there's a lot more to it than that, but
the simple example seems like something Knockout's MVVM model could handle in
similar or less complexity.

So why use React.js when Knockout.js works perfectly fine?

~~~
dustingetz
Maybe it's easier to see by example. Knockout doesn't do so well when the
state isn't trivial. Build these in Knockout, I dare you to try. (Once upon a
time, I tried, and failed, and now I use React)

[http://wingspan.github.io/wingspan-forms/examples/form-
twins...](http://wingspan.github.io/wingspan-forms/examples/form-twins/)
[http://wingspan.github.io/wingspan-forms/examples/faceted-
se...](http://wingspan.github.io/wingspan-forms/examples/faceted-search/)

~~~
candl
These seem to be React wrappers around KendoUI. There are wrappers in Knockout
for the same library as well. [http://kendo-labs.github.io/knockout-
kendo/index.html](http://kendo-labs.github.io/knockout-kendo/index.html)
Writing custom bindings in Knockout is quite easy. I also do not understand
the appeal of React. Performance is often cited because of the virtual DOM
implementation, but for example in this benchmark Knockout is three times
faster than React in my browser. [http://vuejs.org/perf/todomvc-
benchmark/](http://vuejs.org/perf/todomvc-benchmark/) The only criticism that
can be made against Knockout is the syntax when using observables in bindings
(the ugly and error prone parentheses) and lack of reusable components. The
first is solvable by using the Knockout-ES5 plugin if we are willing to drop
IE6 to IE8 support. As for the second, components are finally comming to
Knockout:
[https://github.com/knockout/knockout/pull/1396](https://github.com/knockout/knockout/pull/1396)

~~~
dustingetz
For the record (for anyone who is following the discussion), I have used the
KendoUI/Knockout bindings and am comparing Knockout and React on equal ground.
Nothing about the programming model would change if you just used straight
HTML <input>s.

The main issue with Knockout here, is that the state of these apps (the JSON
blob that changes as you click around) is not nice and rectangular and doesn't
fit nicely into ko.observable and ko.observableArray. particularly the faceted
search demo has tension where the lefthand facet checkboxes are grouped and
have counts, but the top facet list is not grouped and don't have counts. In
react, those are backed by the same state data, and the data is just regular
nested javascript objects and arrays, you don't need to access the data
through observables. You just use underscore to transform the data as you see
fit.

------
mossity
This seems slightly cribbed from "Rethinking Best Practices" by Pete Hunt
[https://www.youtube.com/watch?v=x7cQ3mrcKaY](https://www.youtube.com/watch?v=x7cQ3mrcKaY)

~~~
Confusion
Pete Hunt is quoted on one of the slides, so that sounds likely :)

------
marknutter
function renderApplication(tweets) { return(document.dom.ul( { class: 'tweets'
}, tweets .sort(compareTweetsByScore) .slice(0, 5) .map(function(tweet) {
return(document.dom.li({ class: 'tweet' }, tweet.text); }) )); }

What I like best about Ember and Angular.js is that you don't have any hint of
the DOM in your controllers. I don't like how the above example mixes
concerns.

~~~
antris
Its concern is mapping the tweets (data) into a view (another form of data).
That is one concern. If you like, you can split it into smaller functions
(since everything is referentially transparent, unlike in MVC), but that would
be overkill considering the given example.

~~~
camus2
the point i think is scope injection makes controllers clueless about any view
responsability. That's a powerfull idea. Well they are not totally clueless
because one still needs to "force update the view" sometimes in Angular
($scope.$apply),but this can be avoided by using Angular promise api.

------
morkbot
Anyone knows more about "doing the rendering in web workers" part?

Is it really possible?

Someone doing it already?

Any real benefits of that (web workers have their own overhead)?

------
thrush
It would be useful to see side by side benchmarking and comparisons of typical
Javascript vs React.js. I've just finished reading High Performance Browser
Networking, and it appears to me that most client side code is slowed down
much more by the network than the language. Am I missing something here? Is
Javascript really that bad on its own?

~~~
dangoor
In my experience, JavaScript is quite fast in most browsers. Communication
between the DOM and JavaScript is much slower and causing lots of layout
invalidation and repaints absolutely kills an app's perceived performance.
React's approach is simple for the programmer but takes advantage of the fact
that JS is fast and minimizes those slow bits.

------
whatthemick
I like the idea of React.js and immutable data. But i'm not a fan of the lisp
syntax, am i missing something?

~~~
axle_512
I used to have an issue with lisp syntax until someone pointed it out to me
like this.

In c and java like languages, you invoke a function like this: f(x)

In lisp, just move the paren before the function name. What's the big deal? (f
x)

Similarly, f(g(x)) becomes (f (g x)). All we did was move the paren before the
function name.

The syntax is extremely consistent and it makes the lisp syntax trivial to
learn. In nearly everything you do, the function name comes first the
arguments come next. (+ 1 2) Here + is a function, and you are giving it 2
arguments. There are no special operators or syntax to learn. Just functions!

The mind blowing part comes when you realize that this consistent syntax
combined with the fact that the code is really just written in lisp
datastructures, is what makes lisp macros so powerful.

~~~
whatthemick
Interesting, that does provide a highly consistent base as you say. I might
just have to try out Closure with Om/React for my next project.

------
civilian
Is the presentation available anywhere? The slides just don't cut it for some
of this.

------
camus2
Why isnt clojurescript compiler written in clojurescript? i cant run java on
my machine.

~~~
juliangamble
You can read more about the ClojureScript compiler here:
[http://swannodette.github.io/2014/01/14/clojurescript-
analys...](http://swannodette.github.io/2014/01/14/clojurescript-analysis--
compilation/)

------
tylermauthe
Okay, I'm sold!

------
mantrax5
Just the slides aren't enough to sell me here, I'm sure the missing video to
go with this fills in the holes.

Buuut. "Problem - UI is complex - because DOM not Reactive - what if it was
reactive - random code sample", is just non-sequitur out of context.

DOM programming is inherently "reactive" \- it's event based.

Furthermore, I think it's nice that tools like React.JS exist that "free the
developer from manually programming the DOM", but that's exactly what
Angular.JS offered too. Automatic binding and updating yada yada. Why is this
author flaming Angular.JS? Was it because its leaky abstraction turned out
ugly over time? Well the same fate is awaiting React.JS and its "minimally
leaky abstraction".

Leaky abstractions never remain "minimally leaky" over time. The fact they're
leaky from the very start shows the model was flawed to begin with.

Angular.JS does manual compare between two large model objects to detect
changes and emit model update events.

React.JS does manual compare between virtual DOM and real DOM and emits DOM
update events.

They both try to solve the hardship of having to update your DOM, via an
abstraction that only works well in specific circumstances and incurs
irreducible runtime overhead when behind the scenes structures have to be
compared over and over and emit update/change events.

Sometimes the problem is in the platform. But even more often a bad developer
blames the platform for their own inability to architect their app cleanly and
thinks leaky abstractions are the answer.

~~~
peterhunt
The reason UI programming isn't reactive is because reactive systems are
immediate mode (describe the whole state at any point in time) and the Dom
(hell, most UI toolkits) is retained mode (stateful). So you need to abstract
that away somehow and that abstraction is guaranteed to be leaky to some
degree.

The thing that separates react from the rest (disclaimer: I work on react) is
that these leaks are pushed to the edge of your system (that is, you need an
external signal to re render) rather than threaded throughout your system
(like requiring everything to go through $scope for one). We have seen massive
dev efficiency gains because this removes many limitations for not much
downside.

~~~
mantrax5
Hello, Peter.

Incidentally I was just watching one of your presentations on YouTube to
understand the reasons behind React's design choices.

The thing I still can't understand is why we need to model the UI around
emulation of immediate mode.

Two big reasons:

1\. The fact is when you want to create a meaningful animation between one
state and another, you need to be aware and in control (as a developer) of
what exactly the change is. Diffing may produce one _possible_ valid state
change delta for the developer to work with, but no guarantee it'll be the
correct one. So what does that mean for animated transitions? Is immediate
mode dooming them to either not be used, or to be semi-arbitrary depending on
what the diff engine decides?

2\. Fact is that the browser usually has no access to the full server-backed
state of the widget that it's rendering. Instead, the communication with the
backend that powers said widget (say a chat box) is in the form of delta state
changes. You don't get the full chat log from the server every time someone
sends you a chat message, you get the change only: new message from x.

So if we need to be "state aware" and communicate with "state change events"
so to speak with the server anyway, why suddenly drop that knowledge and
pretend all the state is local by emulating immediate mode rendering?

It doesn't feel like less work. It feels like more work, and less
possibilities (said animations in point 1).

~~~
peterhunt
Thumbing this from my phone so can't go into as much depth as normal.

1\. The diff algorithm is deterministic and accepts that some widgets are
stateful. You can tell the system which items to preserve and which ones to
destroy by providing an identifier. This is essential complexity in the
current world we live in (global dom state tied to element instances like
focus). If we were to throw out the Dom spec and rebuild it we would not need
to do so much.

So you can animate by tweeting a value and rerendering/diffing every frame.
Facebook look back video editor works this way.

2\. Yes, but delta updates are imperative mutations over time and humans are
really bad at keeping track of them so we should try to isolate them as much
as possible. We have a separate system that coalesces these deltas into
consistent views of the world which are then passed to react. This is also the
role of systems like rx.

One way to think about it is like rest. People like rest because it is
predictable: URL refers to the same resource always and refreshing the page
always works consistently and you never need to think about deltas.

~~~
mantrax5
I tend to model and see all communication (at all levels) as message passing
and not as resource/state snapshot passing, but the web has worked fine with
the latter concept so far. So React's architecture certainly provides value in
such situations.

Thanks for answering my questions.

~~~
peterhunt
Totally get you on that. I think that message passing is valuable because it
forces you to decouple systems in a way that reduces shared state. But for
complex apps this means that you will probably have to introduce some sort of
coordination system, which is where things start to get complicated. If you
can pull "time" out of the equation (ie look at complete state snapshots
rather than messages over time) it can make things a lot easier. Obviously not
appropriate for everything, but has worked well for us when building UIs.

No problem btw, fire away if you have any more questions!

