Three Types of Data
Author here: this is one of those ideas that&#x27;s been stewing in my head for quite some time and I&#x27;m only about 80% happy with how it came out as words. Let me know if I can provide further examples or elaboration.<p>----------------------<p>Edit: I wrote this example in response to a comment which has since been deleted, so I&#x27;ll post it here instead<p>Let&#x27;s say your program stores the positions of two entities that can change arbitrarily over time:<p><pre><code>  let pos1 = { x: 0, y: 1, z: 2 };
  let pos2 = { x: 1, y: 3, z: 0 };
</code></pre>
And you also want to work with the distance between them:<p><pre><code>  let distance = Math.sqrt(
    (pos2.x - pos1.x) * (pos2.x - pos1.x) +
    (pos2.y - pos1.y) * (pos2.y - pos1.y) +
    (pos2.z - pos1.z) * (pos2.z - pos1.z));
</code></pre>
When do you do this computation?<p>If &quot;distance&quot; is thought of like any other state, it&#x27;s unclear, and it&#x27;s easy for it to get out of sync with the values it&#x27;s derived from. Maybe you have some sort of core update or rendering phase and you re-compute it there. Maybe you try and re-compute it every time one of the two values gets modified, either by constraining their modification within methods or by somehow observing their changes. Maybe you have a data structure that allows you to easily compare them to the values the previous computation came from. Deciding which of these strategies to take is non-trivial, but you can simplify the question a little bit by seeing &quot;distance&quot; as not being a normal part of state.<p>If you pull it out into a pure function:<p><pre><code>  function getDistance(a, b) {
    return Math.sqrt(
      (pos2.x - pos1.x) * (pos2.x - pos1.x) +
      (pos2.y - pos1.y) * (pos2.y - pos1.y) +
      (pos2.z - pos1.z) * (pos2.z - pos1.z));
  }
</code></pre>
then &quot;updating&quot; it becomes a singular, clear action:<p><pre><code>  let distance;
  function updateDistance() {
    distance = getDistance(pos1, pos2);
  }
</code></pre>
And then <i>when it gets computed</i> becomes an independent question from <i>how it gets computed</i>. You can update it eagerly, or lazily, or implicitly. You can use comparisons, or observables, or whatever.<p>The benefit becomes more clear when the value isn&#x27;t a simple number, but a whole object or object graph. By making it immutable, you have much more leeway when it comes to &quot;refreshing&quot; it, because you can guarantee you won&#x27;t be losing any meaningful information.<p>None of these ideas are especially novel or profound, but as a mental framework they&#x27;ve shed a whole lot of clarity for me in my work over the last year or two.