<story><title>Three Types of Data</title><url>https://www.brandons.me/blog/three-types-of-data</url></story><parent_chain></parent_chain><comment><author>typon</author><text>Out of the tar pit paper: &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;papers-we-love&amp;#x2F;papers-we-love&amp;#x2F;blob&amp;#x2F;master&amp;#x2F;design&amp;#x2F;out-of-the-tar-pit.pdf&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;papers-we-love&amp;#x2F;papers-we-love&amp;#x2F;blob&amp;#x2F;master...&lt;/a&gt;&lt;p&gt;It describes these categories in a lot more detail and the equivalents are:&lt;p&gt;Constants =&amp;gt; User specifications&lt;p&gt;State =&amp;gt; Essential state&lt;p&gt;Cached values =&amp;gt; Accidental state</text></comment>
<story><title>Three Types of Data</title><url>https://www.brandons.me/blog/three-types-of-data</url></story><parent_chain></parent_chain><comment><author>brundolf</author><text>Author here: this is one of those ideas that&amp;#x27;s been stewing in my head for quite some time and I&amp;#x27;m only about 80% happy with how it came out as words. Let me know if I can provide further examples or elaboration.&lt;p&gt;----------------------&lt;p&gt;Edit: I wrote this example in response to a comment which has since been deleted, so I&amp;#x27;ll post it here instead&lt;p&gt;Let&amp;#x27;s say your program stores the positions of two entities that can change arbitrarily over time:&lt;p&gt;&lt;pre&gt;&lt;code&gt;  let pos1 = { x: 0, y: 1, z: 2 };
  let pos2 = { x: 1, y: 3, z: 0 };
&lt;/code&gt;&lt;/pre&gt;
And you also want to work with the distance between them:&lt;p&gt;&lt;pre&gt;&lt;code&gt;  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));
&lt;/code&gt;&lt;/pre&gt;
When do you do this computation?&lt;p&gt;If &amp;quot;distance&amp;quot; is thought of like any other state, it&amp;#x27;s unclear, and it&amp;#x27;s easy for it to get out of sync with the values it&amp;#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 &amp;quot;distance&amp;quot; as not being a normal part of state.&lt;p&gt;If you pull it out into a pure function:&lt;p&gt;&lt;pre&gt;&lt;code&gt;  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));
  }
&lt;/code&gt;&lt;/pre&gt;
then &amp;quot;updating&amp;quot; it becomes a singular, clear action:&lt;p&gt;&lt;pre&gt;&lt;code&gt;  let distance;
  function updateDistance() {
    distance = getDistance(pos1, pos2);
  }
&lt;/code&gt;&lt;/pre&gt;
And then &lt;i&gt;when it gets computed&lt;/i&gt; becomes an independent question from &lt;i&gt;how it gets computed&lt;/i&gt;. You can update it eagerly, or lazily, or implicitly. You can use comparisons, or observables, or whatever.&lt;p&gt;The benefit becomes more clear when the value isn&amp;#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 &amp;quot;refreshing&amp;quot; it, because you can guarantee you won&amp;#x27;t be losing any meaningful information.&lt;p&gt;None of these ideas are especially novel or profound, but as a mental framework they&amp;#x27;ve shed a whole lot of clarity for me in my work over the last year or two.</text></comment>