3 ms·
In order to understand the frame of reference for Om, you really need to watch some Rich Hickey presentations [1][2] (or have a good understanding of functional
by grayrest 13y ago
In order to understand the frame of reference for Om, you really need to watch some Rich Hickey presentations [1][2] (or have a good understanding of functional programming). The first one is more relevant to your questions here, the second is just because Clojure programmers have very specific definitions of "simple" and "easy" and because it's a good talk.
[1] http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...
[2] http://www.infoq.com/presentations/Simple-Made-Easy http://www.infoq.com/presentations/Simple-Made-Easy
That said, on to answering your questions:
> If data changes, it needs to mutate, right? ...
Data doesn't change in this model (see [1]). Incoming events (keyup, network request, page load) occur and your program responds to those events by producing a new, immutable set of data that you're going to use going forward. Om apps keep one reference to the root of the data tree–Om examples use app-state as the name–which represents the official current state of the data. You can reasonably argue that swapping out app-state is changing data except that anything that had a reference to the previous root(s) still has that reference and you have to go dereference app-state to get the current value instead of having it changed out from under you.
> If that's the way, how can you efficiently do updates on relatively large chunks of data? ... Or am I missing something and is it really not that bad?
[3] http://eclipsesource.com/blogs/wp-content/uploads/2009/12/clojure-trees.png http://eclipsesource.com/blogs/wp-content/uploads/2009/12/cl...
Clojure(script)'s data structures use structural sharing. The above picture shows inserting a single node into the middle of the structure. The red outlined nodes are the parents which need to be copy+updated, as shown on the right with all the dotted lines being shared references. The most misleading thing about the picture is that the actual cljs trees have 32 branches at each node instead of 2 or 3 so the lookup time is log32 N (basically constant [4], impl in a systems language vs classic datastructures for comparison). In your Gmail example you'd have to make ~3 new nodes.
[4] https://github.com/michaelwoerister/rs-persistent-datastructures https://github.com/michaelwoerister/rs-persistent-datastruct...
> In general, doesn't this make model code much much more complicated?
It requires a different mindset and generally some helper code. In Clojure using Om it's pretty straightforward once you're over the initial hurdle. In javascript using Mori [5] it looks a lot like awkward Backbone with very heavy Underscore use. I've poked around at it and if I were going to try to adopt Mori+React for a real project I'd want to do some quality of life tweaks on Mori. Mostly setting a prototype on the Mori objects to get the feel closer to Backbone+Underscore and trying to get the data structure console output to be more useful.
[5] https://github.com/swannodette/mori https://github.com/swannodette/mori
- skrebbel 13y agoThanks a lot for the detailed explanation. I'll watch the videos (saw the Simple/Easy one already, they're good definitions of the words and it would be great if they'd be adopted more broadly outside the Clojure community too). I think I'm catching the drift here. This app-state variable was the concept I was missing. That, and how smart the Clojure(Script) data structures really are. Mori looks pretty damn nice, actually. Would consider using it in practice.