
Virtual DOM in Elm - bahador
http://elm-lang.org/blog/Blazing-Fast-Html.elm
======
mysterymachine
It's great to see Elm crediting Om for some of its ideas. The cross
pollination between the Elm and Clojurescript community is great. Looking into
Zelkova
([https://github.com/jamesmacaulay/zelkova](https://github.com/jamesmacaulay/zelkova)),
an Elm style signal library for Clojure, right now. It's a great time to be a
fan of stuff like this.

~~~
escherize
Another Elm inspired approach is re-frame ([https://github.com/Day8/re-
frame](https://github.com/Day8/re-frame)) which is a framework for writing
SPAs in Reagent ([http://reagent-project.github.io](http://reagent-
project.github.io)).

re-frame doesn't get enough love so here's an overview. re-frame encourages
you to keep the state of your app in one map and treat it like a database. re-
frame has 4 main parts:

\- DB: where your global, shared state is stored. If that sounds scary and you
use databases often, that's logically inconsistent. The DB is usually a map in
an atom. (so it is mutable via transactions).

\- Views: Reagent components. for an aweosome live example checkout
[http://reagent-project.github.io](http://reagent-project.github.io)

There are 2 ways for views to interact with the db - via dispatching handlers
and subscribing to subscriptions.

\- Handlers: analogous to stored procedures on the database. Handlers are pure
functions that act on the database. The value returned by the handler is the
new value of the DB. The handler gets registered and can be used as a high
level declarative function from the views. Here's an example from our current
app:

    
    
        (register-handler
         :cart-order-failed
         (fn [db [_]]
             (assoc db :cart-order-failure true)))
    
    

\- Subscriptions: analogous to materialized views on the database. Allows you
to watch a specific part of the state-map, do some computation, and rerun only
when that specific part is updated. Here's another example:

    
    
        (register-sub
         :user-info
         (fn [db [_]]
             (reaction (->
                        ;; never give out the password if it's there
                        (get @db :user)
                        (dissoc :password)
                        (dissoc :pass2)))))
    
    

So the data flows like this:

    
    
          DB -> Subscription
           ^             |
           |             v
        Handler   <-   View
    

The view also turns into a react.js component and is rendered to the vdom
using immutable data structures, but that's Reagent not re-frame.

~~~
dkersten
_re-frame doesn 't get enough love_

Sure it does, it was pretty much the only thing talked about on the cljs
mailing list for about two weeks solid. It is a fantastic library though (I'm
using it right now!)

------
graffitici
The benchmarks are very interesting. I wonder what React's performance would
look like when using immutable data structures, such as those by Immutable.js
(another FB project). It seems to me that you would again get the benefit of
immutable data in the diffing algorithm; namely that the one can check if any
data has changed just be checking shallow equality.

I really admire Elm for being a trailblazer for pushing techniques such as
reactive programming, but it seems to be that it's unlikely to be very
mainstream. This is why I'd love to see the performance benefits using more
mainstream solutions with JS.

~~~
mbrock
Semi-tangential note: React comes with the helpful `React.addons.update`,
which implements "immutable data structures" in an extremely simple way.

I'm working on a medium-sized React application where all application state
changes go through this function—there's one big state object with all
substate, and we don't do any mutation inside of it. We haven't needed to
benchmark anything yet, nor do we have any extreme performance requirements.

Since all our state updates work like this, we can use `PureRenderMixin` on
all components, which gives us the kind of shallow equality behavior you
describe.

~~~
graffitici
I see, so there's no need to even use an external library.

It doesn't look like they are using the PureRenderMixin for the benchmarks.
Would be curious to see how they compare then..

~~~
mbrock
They do implement `shouldComponentUpdate` on the todo items in a way that
should give about the same performance boost. (All the pure render mixin does
is implement that method using shallow equality.)

------
phamilton
I love seeing real world consequences of pure functions. They are often
praised for simplicity in development but this is a great example of
leveraging constraints to build more performant solutions.

------
danielnaab
This was also discussed last year:
[https://news.ycombinator.com/item?id=8063870](https://news.ycombinator.com/item?id=8063870)

------
dcre
Great post, as usual. I wish these posts had dates on them.

~~~
walrus
According to the git history, it was posted June 16, 2014 (1136ce4).

------
Lambdanaut
I used Elm in a personal project. It's a joy to play with but the standard
library has some bugs that made it impossible for me to continue development.

~~~
brown-dragon
Could you give some examples of the bugs you found? I would like to contribute
to elm and this looks like a good place to do it.

~~~
Lambdanaut
Some strange bugs in the forms library. One being:

[https://github.com/elm-lang/core/issues/227](https://github.com/elm-
lang/core/issues/227)

This was a major blocker for me. I know of workarounds but I haven't gotten
around to implementing them and I'd rather the core library just work.

------
eccstartup
Why?

