Virtual DOM in Elm
elm-lang.org
elm-lang.org
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
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.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!)
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.
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.
It doesn't look like they are using the PureRenderMixin for the benchmarks. Would be curious to see how they compare then..
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.