<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Łukasz Makuch]]></title><description><![CDATA[Thoughts on programming.]]></description><link>https://coder.earth</link><generator>RSS for Node</generator><lastBuildDate>Wed, 21 Feb 2024 18:05:56 GMT</lastBuildDate><item><title><![CDATA[What are portals in frameworks like React and Vue?]]></title><link>https://coder.earth/post/what-are-portals-in-react-and-vue</link><guid isPermaLink="false">https://coder.earth/post/what-are-portals-in-react-and-vue</guid><pubDate>Sat, 17 Feb 2024 15:37:20 GMT</pubDate><content:encoded>&lt;p&gt;After working with different incarnations of the concept of portals in React and Vue I came to understand them as a way to differentiate the tree of UI components from the tree of logic components.&lt;/p&gt;
&lt;p&gt;I know this definition may sound cryptic, but I promise you that it&apos;ll click if you read this post.&lt;/p&gt;
&lt;p&gt;You see, components are a neat way to keep our code coherent. They encourage the delivery of &lt;a href=&quot;https://en.wikipedia.org/wiki/Vertical_slice&quot;&gt;vertical slices&lt;/a&gt; by grouping those pieces of state, logic, styles, and UI controls that work and change together.&lt;/p&gt;
&lt;p&gt;That&apos;s why there&apos;s often a direct, one-to-one correlation between framework components and DOM nodes:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/one-to-one-937dafd4c3b5824aa831ab0fbd73f158-af11f.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 645px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 62.63565891472867%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEF/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAL/2gAMAwEAAhADEAAAAdurID//xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAEFAl//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAY/Al//xAAYEAACAwAAAAAAAAAAAAAAAAAAARARMf/aAAgBAQABPyHGXDV7CP/aAAwDAQACAAMAAAAQ6z//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAcEAEAAwACAwAAAAAAAAAAAAABABEhEDFRYYH/2gAIAQEAAT8QFoXuWdpD3xiV14yI1lfSCip//9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;one-to-one&quot;
        title=&quot;&quot;
        src=&quot;/static/one-to-one-937dafd4c3b5824aa831ab0fbd73f158-9fa2b.jpeg&quot;
        srcset=&quot;/static/one-to-one-937dafd4c3b5824aa831ab0fbd73f158-6ae22.jpeg 300w,
/static/one-to-one-937dafd4c3b5824aa831ab0fbd73f158-2c64e.jpeg 600w,
/static/one-to-one-937dafd4c3b5824aa831ab0fbd73f158-9fa2b.jpeg 1200w,
/static/one-to-one-937dafd4c3b5824aa831ab0fbd73f158-af11f.jpeg 1290w&quot;
        sizes=&quot;(max-width: 645px) 100vw, 645px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;However, sometimes that&apos;s not what we want. The way we layout UI elements doesn&apos;t always align with the way how ownership, data and behavior are grouped.&lt;/p&gt;
&lt;p&gt;Let me provide an example that illustrates this well. It&apos;s an example which we&apos;ve all seen. It&apos;s a widget that opens a modal.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/modal-a81854245f5f95da77c6346f4bfaadc8-456c8.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 564px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 72.96099290780141%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIDBAX/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAv/aAAwDAQACEAMQAAAB7TZ4SqKH/8QAGBAAAwEBAAAAAAAAAAAAAAAAAAECEjL/2gAIAQEAAQUCyjKK62yndM//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAZEAACAwEAAAAAAAAAAAAAAAAQMQAREiH/2gAIAQEABj8CUR7WR//EABgQAQEBAQEAAAAAAAAAAAAAAAEAEWGB/9oACAEBAAE/ITAnHDEF1sH5FGXb/9oADAMBAAIAAwAAABAb7//EABURAQEAAAAAAAAAAAAAAAAAAAEQ/9oACAEDAQE/EGf/xAAWEQEBAQAAAAAAAAAAAAAAAAABEBH/2gAIAQIBAT8QDZ//xAAbEAEAAgMBAQAAAAAAAAAAAAABABEhMWFRgf/aAAgBAQABPxB6c+Zgmy+EIJQOCBgAxyDnrbLrjiRFbuf/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;modal&quot;
        title=&quot;&quot;
        src=&quot;/static/modal-a81854245f5f95da77c6346f4bfaadc8-456c8.jpeg&quot;
        srcset=&quot;/static/modal-a81854245f5f95da77c6346f4bfaadc8-64158.jpeg 300w,
/static/modal-a81854245f5f95da77c6346f4bfaadc8-f7853.jpeg 600w,
/static/modal-a81854245f5f95da77c6346f4bfaadc8-456c8.jpeg 1128w&quot;
        sizes=&quot;(max-width: 564px) 100vw, 564px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;And yes, I am aware there are both third-party and built-in solutions that allow us to achieve something like that without thinking about it too much. I consider it to be a good example exactly because it&apos;s so common. We&apos;re all familiar with the end result, and that makes it easier to think about what&apos;s actually going on under the hood.&lt;/p&gt;
&lt;p&gt;As far as ownership is concerned, the widget &quot;owns&quot; that modal. It decides when to show it and the modal doesn&apos;t have any other reason to exist than to serve the widget. Yet, the modal renders above everything else. It&apos;s one of those situations when the tree of components that render things on the screen doesn&apos;t align with the tree of components that define data and behavior. &lt;/p&gt;
&lt;p&gt;So how can we code it?&lt;/p&gt;
&lt;p&gt;We could reverse the invert hierarchy. The modal could become the parent of the widget. The modal would live in the root node of the entire application, and it&apos;d pass the widget that opens it down. It could work, but it&apos;d obscure what&apos;s more important - the widget - by placing some detail - the modal - above everything else. It&apos;d also become harder for the widget to change what&apos;s inside of the modal.&lt;/p&gt;
&lt;p&gt;What we&apos;re wrangling with here is that we clearly want the modal to render outside of the widget, yet the logical hierarchy should be such that the widget is the more important component that controls its modal.&lt;/p&gt;
&lt;p&gt;That&apos;s exactly what portals are for! They enable us to decouple the DOM tree from the component tree. With portals we can teleport things from one place to another. Have a look:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/different-trees-7d5ac12000ce691ff903005108256a77-93793.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 704px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 67.51954513148543%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAOABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAECBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAC/9oADAMBAAIQAxAAAAHuRqUUf//EABcQAAMBAAAAAAAAAAAAAAAAAAABEBH/2gAIAQEAAQUCiGtv/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAIP/aAAgBAQAGPwJf/8QAGxABAAICAwAAAAAAAAAAAAAAAQAREHExUfD/2gAIAQEAAT8hI2nWoKOV3PBz/9oADAMBAAIAAwAAABBoL//EABURAQEAAAAAAAAAAAAAAAAAAAAB/9oACAEDAQE/EEf/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAbEAEAAwADAQAAAAAAAAAAAAABABEhMUFxUf/aAAgBAQABPxDDXRA4fCtmB6FswXwfETawgqaVP//Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;different trees&quot;
        title=&quot;&quot;
        src=&quot;/static/different-trees-7d5ac12000ce691ff903005108256a77-9c8a7.jpeg&quot;
        srcset=&quot;/static/different-trees-7d5ac12000ce691ff903005108256a77-4e72d.jpeg 300w,
/static/different-trees-7d5ac12000ce691ff903005108256a77-6054d.jpeg 600w,
/static/different-trees-7d5ac12000ce691ff903005108256a77-9c8a7.jpeg 1200w,
/static/different-trees-7d5ac12000ce691ff903005108256a77-93793.jpeg 1407w&quot;
        sizes=&quot;(max-width: 704px) 100vw, 704px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;Widget&lt;/code&gt; can still own and control the &lt;code class=&quot;language-text&quot;&gt;Modal&lt;/code&gt;, but through the means of &lt;em&gt;portals&lt;/em&gt; the &lt;code class=&quot;language-text&quot;&gt;Modal&lt;/code&gt; renders outside of the &lt;code class=&quot;language-text&quot;&gt;Widget&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Portals allow us to have the cake and eat it too. We can keep the hierarchy of components as readable and as predictable as possible, while still rendering UI elements that don&apos;t necessarily correspond to it one-to-one.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What are some differences between various portal implementations?]]></title><link>https://coder.earth/post/what-are-some-differences-between-various-portal-implementations</link><guid isPermaLink="false">https://coder.earth/post/what-are-some-differences-between-various-portal-implementations</guid><pubDate>Sat, 17 Feb 2024 15:37:20 GMT</pubDate><content:encoded>&lt;p&gt;In the &lt;a href=&quot;https://coder.earth/post/what-are-portals-in-react-and-vue&quot;&gt;previous post on portals&lt;/a&gt; we&apos;ve covered what portals are in general. But did you know there are some important differences between various implementations of portals? Those differences can significantly change the way how you use portals to develop software!&lt;/p&gt;
&lt;p&gt;While all portal engines provide a way to move some piece of some tree somewhere else, they go about it in different ways. In today&apos;s entry we&apos;ll focus on what&apos;s actually being teleported and what does it mean for the developers.&lt;/p&gt;
&lt;p&gt;Some portals, like the &lt;a href=&quot;https://react.dev/reference/react-dom/createPortal&quot;&gt;portals from React&lt;/a&gt;, work by moving DOM nodes:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/moving-dom-nodes-e9e6b93de169ee971613499f7dc05c4a-ea6cc.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 664px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 45.70783132530121%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAJABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEF/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAL/2gAMAwEAAhADEAAAAdwSoP/EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEAAQUCX//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEABj8CX//EABcQAAMBAAAAAAAAAAAAAAAAAAEQQQD/2gAIAQEAAT8hYupX/9oADAMBAAIAAwAAABD8P//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABwQAAMAAgMBAAAAAAAAAAAAAAABETFBIVFhcf/aAAgBAQABPxCxzehXlReOiqXZl9CBYP/Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;moving dom nodes&quot;
        title=&quot;&quot;
        src=&quot;/static/moving-dom-nodes-e9e6b93de169ee971613499f7dc05c4a-5c7d0.jpeg&quot;
        srcset=&quot;/static/moving-dom-nodes-e9e6b93de169ee971613499f7dc05c4a-99389.jpeg 300w,
/static/moving-dom-nodes-e9e6b93de169ee971613499f7dc05c4a-15a93.jpeg 600w,
/static/moving-dom-nodes-e9e6b93de169ee971613499f7dc05c4a-5c7d0.jpeg 1200w,
/static/moving-dom-nodes-e9e6b93de169ee971613499f7dc05c4a-ea6cc.jpeg 1328w&quot;
        sizes=&quot;(max-width: 664px) 100vw, 664px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;From the framework&apos;s perspective, components don&apos;t move at all. It&apos;s just the DOM that moves.&lt;/p&gt;
&lt;p&gt;If we recall that at Facebook React was used to augument server-side PHP applications it&apos;s easy to understand why React portals work that way. They can be used to render components controlled by React even outside of the root node of any particular React app!&lt;/p&gt;
&lt;p&gt;Other libraries, like &lt;a href=&quot;https://v2.portal-vue.linusb.org/&quot;&gt;PortalVue&lt;/a&gt;, teleport components even before they become DOM nodes:

  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 664px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 47.3644578313253%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAJABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEF/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAL/2gAMAwEAAhADEAAAAdxUgP/EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEAAQUCX//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEABj8CX//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEAAT8hX//aAAwDAQACAAMAAAAQzD//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAaEAEAAwEBAQAAAAAAAAAAAAABABExUSHB/9oACAEBAAE/ELpreQEX2/kLDsNYawyf/9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;moving framework components&quot;
        title=&quot;&quot;
        src=&quot;/static/moving-framework-components-22c2408c221be3100386098a0fae7eb6-5c7d0.jpeg&quot;
        srcset=&quot;/static/moving-framework-components-22c2408c221be3100386098a0fae7eb6-99389.jpeg 300w,
/static/moving-framework-components-22c2408c221be3100386098a0fae7eb6-15a93.jpeg 600w,
/static/moving-framework-components-22c2408c221be3100386098a0fae7eb6-5c7d0.jpeg 1200w,
/static/moving-framework-components-22c2408c221be3100386098a0fae7eb6-ea6cc.jpeg 1328w&quot;
        sizes=&quot;(max-width: 664px) 100vw, 664px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  &lt;/p&gt;
&lt;p&gt;This library was born in the userland before Vue had built-in portals. Maybe that&apos;s why it&apos;s so unique.&lt;/p&gt;
&lt;p&gt;But why does it matter, you may ask?&lt;/p&gt;
&lt;p&gt;In both React and Vue there are tools for working with component subtrees instead of just individual components, such as &lt;a href=&quot;https://vuejs.org/guide/components/provide-inject&quot;&gt;Dependency Injection in Vue&lt;/a&gt; and its React counterpart - &lt;a href=&quot;https://react.dev/learn/passing-data-deeply-with-context&quot;&gt;Context&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If we move only DOM nodes, dependency injection won&apos;t be affected. But if we move framework components, the teleported components will be injected with different values, potentially altering the behavior of the app, not just its appearance.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That&apos;s why it&apos;s important to know the details of the portal engine you&apos;re using. This applies even to folks who&apos;ve already worked with portals because there&apos;re significant differences in what do portals actually do, even between different versions of the same framework, such as between Vue 2 and 3.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The 14 reasons why engineers write automated tests]]></title><link>https://coder.earth/post/the-14-reasons-why-engineers-write-automated-tests</link><guid isPermaLink="false">https://coder.earth/post/the-14-reasons-why-engineers-write-automated-tests</guid><pubDate>Sun, 11 Feb 2024 15:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/testing-56a9618d1df2be60704cae2191f4b2e2-8805c.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.77083333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAMEBf/EABUBAQEAAAAAAAAAAAAAAAAAAAIB/9oADAMBAAIQAxAAAAHUkStDeJyL/8QAGxAAAgIDAQAAAAAAAAAAAAAAAQIAAwQREjL/2gAIAQEAAQUCfzQ7dzMsZILWKA7H/8QAFxEBAAMAAAAAAAAAAAAAAAAAARARIf/aAAgBAwEBPwFa2P/EABYRAAMAAAAAAAAAAAAAAAAAAAABEf/aAAgBAgEBPwFKkP/EABwQAAICAgMAAAAAAAAAAAAAAAERAAIQISJBYf/aAAgBAQAGPwLRXqnKzCxUDuC2sf/EABwQAQACAQUAAAAAAAAAAAAAAAEAESExQVFhcf/aAAgBAQABPyFt8n0l+bexBshDcXs5iRdVUEUHqf/aAAwDAQACAAMAAAAQrB//xAAWEQEBAQAAAAAAAAAAAAAAAAARAAH/2gAIAQMBAT8QKsm//8QAFREBAQAAAAAAAAAAAAAAAAAAERD/2gAIAQIBAT8QYR//xAAbEAEBAQACAwAAAAAAAAAAAAABEQAhcUFRYf/aAAgBAQABPxDw27HCdYbxaaxWnsuKmLWMGKRJqQjGGAH3WvKGHW//2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A person performing testing&quot;
        title=&quot;&quot;
        src=&quot;/static/testing-56a9618d1df2be60704cae2191f4b2e2-19371.jpg&quot;
        srcset=&quot;/static/testing-56a9618d1df2be60704cae2191f4b2e2-c766d.jpg 300w,
/static/testing-56a9618d1df2be60704cae2191f4b2e2-f0d1c.jpg 600w,
/static/testing-56a9618d1df2be60704cae2191f4b2e2-19371.jpg 1200w,
/static/testing-56a9618d1df2be60704cae2191f4b2e2-228e2.jpg 1800w,
/static/testing-56a9618d1df2be60704cae2191f4b2e2-8805c.jpg 1920w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;If you&apos;ve ever asked yourself the question &quot;Why did they write these tests?&quot; then this blog post is for you. Over the last decade, I&apos;ve observed a multitude of reasons as to why IT professionals automate tests. Some of them are purely technical, and some are rather social. Some bring a lot of value to the company, while others benefit only individual engineers. Revealing them here will ruffle some feathers, but it can also serve as a nudge to abandon some practices while doubling down on others. &lt;/p&gt;
&lt;h2&gt;The 14 reasons to automate tests&lt;/h2&gt;
&lt;h3&gt;1. Spotting regression as soon as possible&lt;/h3&gt;
&lt;p&gt;One of the most common reasons to automate tests is to spot regression. Once a system grows big, making sure everything still works as expected requires a lot of manual work. Hiring manual testers is also expensive, and even an entire team of manual testers may still need a significant amount of time to thoroughly test a big system. This is the reason why testing tickets pile up before releases. That&apos;s also why developers become hesitant to introduce changes that would pay off in the future but could introduce bugs the QA wouldn&apos;t find. Such decisions provide short-term stability and faster release cycles but lead to the accumulation of technical debt, which slows the development process down in the long run. Cheap and fast automated tests enable teams to release more often and stay away from technical debt. Also, the whole process feels much calmer without all that fear about breaking who knows what without even knowing about it.&lt;/p&gt;
&lt;h3&gt;2. Verifying properties, broadly speaking, not just some cases&lt;/h3&gt;
&lt;p&gt;Imagine we&apos;re creating an algorithm that should output a number between 0 and 1. If it produces a result beyond that range, it means there&apos;s an error. How do we go about testing this? An easy way to increase our confidence in this algorithm is to use &lt;a href=&quot;https://en.wikipedia.org/wiki/Software_testing#Property_testing&quot;&gt;property testing&lt;/a&gt;. While it&apos;s oftentimes not feasible to manually create thousands or millions of inputs, computers can do it just fine. It means that instead of writing a scenario like &quot;Given 42 and 7, it returns 0.3&quot;, we can write a scenario like &quot;Given 2 numbers, it returns a number between 0 and 1&quot; and the computer will generate and run tons of concrete test cases to ensure that&apos;s true. &lt;/p&gt;
&lt;h3&gt;3. Testing what&apos;s hard to test manually&lt;/h3&gt;
&lt;p&gt;It&apos;s relatively straightforward to manually test happy path scenarios. However, testing becomes increasingly more challenging if we need to check if the system works as expected when something goes wrong. Think a dependency service being down or concurrent processes executing in an unusual order. Fortunately, in a scripted test environment we can have total control over all the moving pieces and it becomes easy to simulate all the edge cases.&lt;/p&gt;
&lt;h3&gt;4. Testing what nobody wants to test manually&lt;/h3&gt;
&lt;p&gt;Some things are worth keeping in check, but it&apos;s really mundane to manually enforce them. Examples of such things include the right letter capitalization or the right number of spaces. While a human can certainly look for white space violations, there are probably better ways for them to make good use of their time. Automating this aspect of product development frees people to do things that are more valuable for the business.&lt;/p&gt;
&lt;h3&gt;5. Meeting contractual obligations&lt;/h3&gt;
&lt;p&gt;Many kinds of tests, when done right, prove invaluable in increasing the confidence we can have in our products, which leads to faster time to market. That&apos;s why a requirement to have automated tests may be found in various contracts, for example, when a company is looking for investors. Such contractual obligations may even serve as the primary incentive for teams to embrace automated testing.&lt;/p&gt;
&lt;h3&gt;6. Social pressure&lt;/h3&gt;
&lt;p&gt;Contrary to what some may believe, engineers are social creatures too, and that makes them susceptible to social pressure. So even if an individual contributor doesn&apos;t find the practice of test automation beneficial, they may still be tempted to automate them in an environment that favours those who do. Being accepted by one&apos;s peers or getting that life-changing promotion is worth doing things that seem pointless. &lt;/p&gt;
&lt;h3&gt;7. Learning how to automate tests&lt;/h3&gt;
&lt;p&gt;To err is human, but humans also learn by doing. So even if we don&apos;t know how to effectively automate tests, it may still be a good idea to at least try to do it. There&apos;s a chance that after enough attempts we&apos;ll start seeing a return on investment.&lt;/p&gt;
&lt;h3&gt;8. Spotting security vulnerabilities before the bad actors do&lt;/h3&gt;
&lt;p&gt;Nowadays, it&apos;s rare for any big product to be built entirely from scratch. Most of the time, there are countless prefabricated components, such as libraries, compilers, and even operating systems. It means that even if the code of our product is perfectly secure, it may still be compromised if a security vulnerability is discovered in one of its underpinning technologies. That&apos;s why it&apos;s important to continuously monitor the codebase for known security issues. An automatic security check can be scheduled to run on weekends and during the night just fine. That way, we can react to threats faster. And because a human is alerted only if needed, it helps to keep the cost low.&lt;/p&gt;
&lt;h3&gt;9. Measuring performance&lt;/h3&gt;
&lt;p&gt;Modern multi-tenant web apps are no stangers to handling tens of thousands of requests per second. Let&apos;s say we&apos;re about to launch a new feature. How can we measure its performance, so that we have at least some idea about how much the infrastructure will cost? If you&apos;ve ever tried clicking very fast to see how an app perfroms under heavy load, you know that it may be quite a challenge! That&apos;s where automated stress testing comes into play. Being able to repeadetly generate the same amount of traffic and measure various parameters such as CPU load and memory usage proves invaluable in making fact-driven decisions.&lt;/p&gt;
&lt;h3&gt;10. Seeing how different variants perform&lt;/h3&gt;
&lt;p&gt;Let&apos;s say there are two variants of the same thing in our product: variant A and variant B. Will our users like the variant A more than the variant B? It may be hard to predict. Instead of trying to predict it, we can deploy both variants, measure their key performance indicators, and automatically switch to the variant that performs better.&lt;/p&gt;
&lt;h3&gt;11. Making use of the byproducts of design to speed up the development process&lt;/h3&gt;
&lt;p&gt;While in many ways it&apos;s true that building software is like building a plane in the air, some products or pieces of thereof are still designed upfront. It may help us if we ask ourselves the question &quot;So what is it supposed to do, again?&quot;. The outcome of answering it may be a set of precise preconditions, actions and expectations, akin to the components of an automated test suite. If these descriptions are so precise, then we&apos;re just one step away from automating the process of verifying them. And if we can easily shave off hours, if not days, of mundane manual labour, why not do that?&lt;/p&gt;
&lt;h3&gt;12. Recreating scenarios&lt;/h3&gt;
&lt;p&gt;Automated tests often consist of 3 phases, namely arranging, acting, and asserting. Even if we want to manually test some scenario, we may not be keen on arranging all the test data and navigating through the app to reach the testing point. In such situation, a hybrid approach may emerge, where the first phase - arranging - is automated, while the 2 remaining ones are done manually. &lt;/p&gt;
&lt;h3&gt;13. Fostering communication&lt;/h3&gt;
&lt;p&gt;Sometimes it&apos;s easier to talk about a product through the lens of its tests. A language like &lt;a href=&quot;https://cucumber.io/docs/gherkin/reference/&quot;&gt;Gherkin&lt;/a&gt; encourages the formulation of human-readable yet specific and actionable examples. Even failed tests can help us communicate with others, especially when using &lt;a href=&quot;https://github.com/lukaszmakuch/frontend-testing-tools&quot;&gt;frontend-testing-tools&lt;/a&gt;. In such tools, each failed test generates a before-and-after picture, visually highlighting the difference between the reference image and the current state of the app.&lt;/p&gt;
&lt;h3&gt;14. Supporting individuals with disabilities&lt;/h3&gt;
&lt;p&gt;There are many reasons why the selectors from Testing Library took the community by storm. One of them is the fact that they are accessible by default. For many people, it&apos;s enough for a rectangle to appear on the screen to be considered a button. However, others may benefit from that rectangle having a specific button role, properly attached label text, and support for keyboard-driven interactions. Although the selectors provided by today&apos;s state-of-the-art libraries still don&apos;t give us a guarantee that the app is fully inclusive, they&apos;re certainly a step in the right direction that can eliminate the most common barriers troubling people who rely on accessible web applications.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;In an industry where new ways to develop software emerge more often than new ways to test that software, testing is a delicate topic. There&apos;s still a lot to learn and invent. I believe that what&apos;s even more important than learning particular tools is to understand the real outcomes of introducing some testing regimes, as well as being honest about our motivation. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to mock POST requests using Nock in JavaScript]]></title><link>https://coder.earth/post/how-to-mock-post-requests-using-nock-in-javascript</link><guid isPermaLink="false">https://coder.earth/post/how-to-mock-post-requests-using-nock-in-javascript</guid><pubDate>Wed, 07 Feb 2024 17:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a-person-using-a-laptop-960e2638256191894258f2643c85fdf8-8805c.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAEFA//EABUBAQEAAAAAAAAAAAAAAAAAAAEC/9oADAMBAAIQAxAAAAHZQENUlDP/xAAaEAADAQADAAAAAAAAAAAAAAAAAQISAwQT/9oACAEBAAEFAvaeOF2NF3s2OkaR/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGhABAQACAwAAAAAAAAAAAAAAAQAhMhExof/aAAgBAQAGPwI5tUhBsF1m19v/xAAcEAEAAwACAwAAAAAAAAAAAAABABEhEEExUXH/2gAIAQEAAT8hTe3bB2EmzdMR+AVM3R9divXs3xn/2gAMAwEAAgADAAAAEFvf/8QAFxEBAQEBAAAAAAAAAAAAAAAAAQARQf/aAAgBAwEBPxBDjZf/xAAWEQADAAAAAAAAAAAAAAAAAAABEBH/2gAIAQIBAT8QFX//xAAdEAEAAwACAwEAAAAAAAAAAAABABEhMUFRocHx/9oACAEBAAE/EEEcANLb4hmvOQbt9fsbKDZKul2KYEvYqEiJGwy+aOpp9pn/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;a person using a laptop&quot;
        title=&quot;&quot;
        src=&quot;/static/a-person-using-a-laptop-960e2638256191894258f2643c85fdf8-19371.jpg&quot;
        srcset=&quot;/static/a-person-using-a-laptop-960e2638256191894258f2643c85fdf8-c766d.jpg 300w,
/static/a-person-using-a-laptop-960e2638256191894258f2643c85fdf8-f0d1c.jpg 600w,
/static/a-person-using-a-laptop-960e2638256191894258f2643c85fdf8-19371.jpg 1200w,
/static/a-person-using-a-laptop-960e2638256191894258f2643c85fdf8-228e2.jpg 1800w,
/static/a-person-using-a-laptop-960e2638256191894258f2643c85fdf8-8805c.jpg 1920w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/nock/nock&quot;&gt;Nock&lt;/a&gt; is a popular JavaScript library used for server mocking.&lt;/p&gt;
&lt;p&gt;Getting started with Nock is as easy as it gets. Do you want to mock a GET request? Simply write&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;nock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://example.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It couldn&apos;t be easier to mock a GET request.&lt;/p&gt;
&lt;p&gt;You can even mock multiple endpoints:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;nock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://example.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/surname&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Doe&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Where it gets more tricky is mocking requests that are supposed to alter the state of the server, such as POST requests. It&apos;s very tempting, and in fact very common, to write a mock like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;nock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://example.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Johnny&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Johnny&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At the first glance, evertyhing works as expected:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// John&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Johnny&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 200&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Johnny&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, if we take a closer look, we may notice some discrepancies between our mock and how a real endpoint would behave. For instance, we&apos;ll get the updated name even if we don&apos;t actually update it!&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// John&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// No POST request whatsoever&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Johnny&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;It&apos;s because Nock doesn&apos;t have the notion of state. I&apos;d even go as far as saying that Nock doesn&apos;t have a built-in support for POST requests. I know it may sound wrong, but hear me out.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When we register 3 mocks like that:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;nock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://example.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Johnny&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Johnny&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;there are two unique requests: &lt;code class=&quot;language-text&quot;&gt;GET /name&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;POST /name&lt;/code&gt;. There are two responses associated with the &lt;code class=&quot;language-text&quot;&gt;GET /name&lt;/code&gt; request. They form a kind of First In First Out queue. And this queue is completely separate from the queue of &lt;code class=&quot;language-text&quot;&gt;POST /name&lt;/code&gt;!. It means that POST requests don&apos;t have any impact on what&apos;s returned in response to GET requests.
The mock currently behaves in the same was as if we wrote it like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;nock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://example.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Johnny&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// queue A&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// queue B&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Johnny&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// queue B &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or like that:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;nock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://example.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// queue B&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Johnny&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// queue B&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Johnny&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// queue A&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If we focus on just the GET request, there are 2 and only 2 responses queued for it: &quot;John&quot; and &quot;Johnny&quot;. That&apos;s why calling this mocked GET endpoint 3 times will give us consecutively: &quot;John&quot;, &quot;Johnny&quot;, and an error. That&apos;s unlike a real API, which in the same circumstances would return &quot;John&quot; three times.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It may let bugs slip in, if the system under test refetches the data before it updates it. Tests will pass, but only because the mock naively returns the updated data, even if it hasn&apos;t been updated. It will also make tests more fragile, as a relatively harmless superfluous GET request will significantly change the mocked data by shifting the queue associated with it.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Is all hope lost and we can forget about mocking POST requests in Nock? Fortunately, there IS a way to make Nock mimic a real server, so that we can write more reliable and robust tests! It can be accomplished through the means of functions:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Define the state of the mocked server.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// In this example it&apos;s a name.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;John&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;persist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// In response to GET, return the name.&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// When we get a POST request&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uri&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Change the state of the &quot;server&quot; &lt;/span&gt;
        name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Return 200.&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you&apos;re familiar with express, it&apos;s kinda like writing mini express apps. And what advantages does it have over the naive solution with queues?&lt;/p&gt;
&lt;p&gt;If we just call GET multiple times, we&apos;ll always get the same result:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// John&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// John&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// John&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But as soon as we fire up a POST request, the name changes:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// John&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// John&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// John&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Johnny&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Johnny&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Johnny&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Writing mocks in a way that closely resembles real APIs helps to catch bugs that could otherwise go unnoticed, i.e. if some component refetches data too early. It&apos;s also a pragmatic choice, because even if the component under test fires up some redundant requests, the tests won&apos;t fail as long as the observed behavior of the app is correct.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;And if you&apos;re anything like me and you find this imperative style rather primitive and you&apos;re yearning for a more elegant solution, then have a look at HTTP mocking libraries with first-class support for state, such as &lt;a href=&quot;https://wiremock.org/docs/stateful-behaviour/&quot;&gt;WireMock&lt;/a&gt; or &lt;a href=&quot;https://endpoint-imposter.js.org/doc.html#-scenarios&quot;&gt;Endpoint Imposter&lt;/a&gt;.  &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Scoped styles don't get applied to functional components in Vue 2]]></title><link>https://coder.earth/post/scoped-styles-dont-get-applied-to-functional-components-in-vue-2</link><guid isPermaLink="false">https://coder.earth/post/scoped-styles-dont-get-applied-to-functional-components-in-vue-2</guid><pubDate>Fri, 02 Feb 2024 17:37:20 GMT</pubDate><content:encoded>&lt;p&gt;Having your CSS scoped to the component it applies to helps in maintaining encapsulation. That&apos;s exactly what &lt;a href=&quot;https://vue-loader.vuejs.org/guide/scoped-css.html&quot;&gt;Scoped CSS&lt;/a&gt; was designed for. It&apos;s pretty straightforward most of the time, but there are some controversial edge cases. One of them is the fact that these scoped styles defined by the parent component don&apos;t get applied to the root node of functional child components the same way they get applied to stateful child components. Here&apos;s an example of a parent component with scoped styles and a stateful child:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;vue&quot;&gt;&lt;pre class=&quot;language-vue&quot;&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;lt;template&amp;gt;
  &amp;lt;div class=&amp;quot;layout&amp;quot;&amp;gt;
    &amp;lt;Stateful class=&amp;quot;child&amp;quot; /&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;
&amp;lt;script&amp;gt;
import Stateful from &amp;quot;./components/SomeStatefulComponent.vue&amp;quot;;

export default {
  components: { Stateful },
};
&amp;lt;/script&amp;gt;
&amp;lt;style scoped&amp;gt;
.layout {
  display: grid;
  grid-template:
    &amp;quot;. ...... .&amp;quot; 40px
    &amp;quot;. center .&amp;quot; 40px
    &amp;quot;. ...... .&amp;quot; 40px / 1fr 1fr 1fr;
  border: 1px solid black;
}

.child {
  grid-area: center;
}
&amp;lt;/style&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It works as expected - the child is placed in the center of the layout:

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/stateful-works-39bf485147fbb08411f0ddea48ff95f5-b3493.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 727px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 17.825189263592566%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAiUlEQVQY03WPQQvCMAyF9/9/ybDNPCo76p+oBz3svoFIm5aufUuRglr3ko9HIC+QjpnhnEPxSpljiIB0gweyz+89/s4VOvwoSxXdngZqOoAeGsM0QN0VjuJne8LVXZCk/mn3oGGDfulBswYtGnpW4gR6EUY77h+sL35inUXggORTw8orIscmU9kATVExQR5zHzcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;a stateful component gets styled&quot;
        title=&quot;&quot;
        src=&quot;/static/stateful-works-39bf485147fbb08411f0ddea48ff95f5-c1048.png&quot;
        srcset=&quot;/static/stateful-works-39bf485147fbb08411f0ddea48ff95f5-38d02.png 300w,
/static/stateful-works-39bf485147fbb08411f0ddea48ff95f5-01396.png 600w,
/static/stateful-works-39bf485147fbb08411f0ddea48ff95f5-c1048.png 1200w,
/static/stateful-works-39bf485147fbb08411f0ddea48ff95f5-b3493.png 1453w&quot;
        sizes=&quot;(max-width: 727px) 100vw, 727px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;However, it breaks as soon as we make the child component a functional component:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;vue&quot;&gt;&lt;pre class=&quot;language-vue&quot;&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;lt;template&amp;gt;
  &amp;lt;div class=&amp;quot;layout&amp;quot;&amp;gt;
    &amp;lt;Functional class=&amp;quot;child&amp;quot; /&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now the child component doesn&apos;t get the styles from its parent:

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/functional-breaks-e59719b5e1a5148c9788a50e89a071b6-755da.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 726px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 18.181818181818183%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAaUlEQVQY05WPMQqDQBREt7WySPDkElY7PVV0IwT2Bon+v0XwGbRQLGR34DHFwMAz3uYMjztve1vb1wXSZuizQX+g8kVVowghYHAWXLXzqqEv4dOxZSYl5npOO1sPg4zI9Nc6I1O06lF5AfyrLwdhJVKpAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;a functional component doesn&apos;t get the right styles&quot;
        title=&quot;&quot;
        src=&quot;/static/functional-breaks-e59719b5e1a5148c9788a50e89a071b6-1b609.png&quot;
        srcset=&quot;/static/functional-breaks-e59719b5e1a5148c9788a50e89a071b6-8836e.png 300w,
/static/functional-breaks-e59719b5e1a5148c9788a50e89a071b6-f7349.png 600w,
/static/functional-breaks-e59719b5e1a5148c9788a50e89a071b6-1b609.png 1200w,
/static/functional-breaks-e59719b5e1a5148c9788a50e89a071b6-755da.png 1452w&quot;
        sizes=&quot;(max-width: 726px) 100vw, 726px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h2&gt;Why don&apos;t scoped styles apply to a functional child component?&lt;/h2&gt;
&lt;p&gt;If you&apos;ve ever inspected the actual CSS of a component which uses scoped styles, you&apos;ve probably noticed an attribute like &lt;code class=&quot;language-text&quot;&gt;data-v-80d8c89c&lt;/code&gt;. It&apos;s there to limit the scope of CSS selectors. &lt;/p&gt;
&lt;p&gt;When styles are unscoped, there isn&apos;t much going on.
We write templates like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;vue&quot;&gt;&lt;pre class=&quot;language-vue&quot;&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;lt;Stateful class=&amp;quot;child&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and styles like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.child&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;grid-area&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; center&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The generated DOM looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;stateful&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;I am a stateful component!&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and the CSS stays exactly how we wrote it.&lt;/p&gt;
&lt;p&gt;However, as soon as we make the styles scoped by changing &lt;code class=&quot;language-text&quot;&gt;&amp;lt;style&amp;gt;&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;&amp;lt;style scoped&amp;gt;&lt;/code&gt;, something happens.
The generated HTML looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;data-v-7ba5bd90&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;stateful&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;I am a stateful component!&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and the styles have an extra &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors&quot;&gt;attribute selector&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.child[data-v-7ba5bd90]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;grid-area&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; center&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&apos;s how the scope of the stylesheet is narrowed down so that it doesn&apos;t get applied to all &lt;code class=&quot;language-text&quot;&gt;.child&lt;/code&gt; nodes all over the app.&lt;/p&gt;
&lt;p&gt;While this mechanism aims to scope all kinds of styles, what we&apos;re doing here is precisely &lt;a href=&quot;https://vue-loader.vuejs.org/guide/scoped-css.html#child-component-root-elements&quot;&gt;styling child component root elements&lt;/a&gt;. It&apos;s this one special scenario in which scoped CSS is actually applied to some other components - the children. According to the documentation it should be used sparingly - just for layout purposes. Maybe that&apos;s why issues living in the junction of styling child component root elements and functional components don&apos;t arise too often - because as long as we keep our code idiomatic, it simply doesn&apos;t occur that often.&lt;/p&gt;
&lt;p&gt;So, why does it break break when we make the child functional?&lt;/p&gt;
&lt;p&gt;The CSS stays the same, that is scoped:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.child[data-v-7ba5bd90]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;grid-area&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; center&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, if the child has its own scoped stylesheet, it doesn&apos;t inherit the &lt;code class=&quot;language-text&quot;&gt;data-v&lt;/code&gt; attribute from its parent. In fact, it doesn&apos;t even accept the class the parent passes to it!&lt;/p&gt;
&lt;p&gt;If the parent has &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;data-v-7ba5bd90&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and tries to render &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;vue&quot;&gt;&lt;pre class=&quot;language-vue&quot;&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;lt;Functional class=&amp;quot;child&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;, we get:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;data-v-064b6fca&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;functional&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice the different &lt;code class=&quot;language-text&quot;&gt;data-v&lt;/code&gt; and no &lt;code class=&quot;language-text&quot;&gt;&amp;quot;child&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;How to style functional child components the same way stateful child components are styled?&lt;/h2&gt;
&lt;p&gt;The most straightforward way to address this issue would be to make this functional component behave the same way stateful components behave. We can bring back all the familiar bindings with 2 lines of code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;vue&quot;&gt;&lt;pre class=&quot;language-vue&quot;&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;lt;template functional&amp;gt;
  &amp;lt;div
    class=&amp;quot;functional&amp;quot;
    :class=&amp;quot;[data.staticClass, data.class]&amp;quot;
    v-bind:[parent.$options._scopeId]=&amp;quot;&amp;#39;&amp;#39;&amp;quot;
  &amp;gt;
    I am a functional component!
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It works as expected - the child is centered:

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/functional-component-working-8414c39f75d6c729908d14b042cea374-755da.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 726px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 17.90633608815427%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAlUlEQVQY03WQSwrCQBBEczxBwU1UchLB2+gRQrJzMd5AV65cCn62ztdknhOHiBqm4NE0TTVdnRljUEqhtf6glMQ8wQKux8eqW1Bhpgee2Gf8y7fv8jiuuZcjLtWca5Vzq3PO5Qy3HcN+SUrJhc1pE8wT7K7AigUuYESBF1M4rNIL+3N/kBJtY7xvTBe3CYTs3VsGvsALvz0tanjIZlYAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;the functional component get the right styles&quot;
        title=&quot;&quot;
        src=&quot;/static/functional-component-working-8414c39f75d6c729908d14b042cea374-1b609.png&quot;
        srcset=&quot;/static/functional-component-working-8414c39f75d6c729908d14b042cea374-8836e.png 300w,
/static/functional-component-working-8414c39f75d6c729908d14b042cea374-f7349.png 600w,
/static/functional-component-working-8414c39f75d6c729908d14b042cea374-1b609.png 1200w,
/static/functional-component-working-8414c39f75d6c729908d14b042cea374-755da.png 1452w&quot;
        sizes=&quot;(max-width: 726px) 100vw, 726px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h2&gt;But is it a good scoped styles apply to child components?&lt;/h2&gt;
&lt;p&gt;This is a good moment to stop and think about the wise words of Dr. Ian Malcolm:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dr. Ian Malcolm : Yeah, yeah, but your scientists were so preoccupied with whether or not they could that they didn&apos;t stop to think if they should.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If scoped styles are meant to be limited to the component they are defined in, is the fact that they are also applied to roots of children helpful or confusing? I believe it&apos;s the latter. &lt;strong&gt;Judging from my experience, most often than not this capability is used in a non-idiomatic way, for instance to style borders.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;What are some alternative ways to style children components?&lt;/h2&gt;
&lt;p&gt;The most obvious way to style a child component is to use props. Props define a clear, obvious API.&lt;/p&gt;
&lt;p&gt;And when we&apos;re actually defining a layout, pure CSS may be more than enough. For instance, a CSS grid container may define the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/align-items&quot;&gt;align-items property&lt;/a&gt; which, according to MDN, &lt;em&gt;sets the align-self value on all direct children&lt;/em&gt;. And if we need more control over how the direct children are styled, the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Child_combinator&quot;&gt;child combinator &lt;code class=&quot;language-text&quot;&gt;&amp;gt;&lt;/code&gt;&lt;/a&gt; comes in handy:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;vue&quot;&gt;&lt;pre class=&quot;language-vue&quot;&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;lt;style scoped&amp;gt;
.layout /deep/ &amp;gt; * {
  align-self: flex-end;
}
&amp;lt;/style&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note the usage of a &lt;a href=&quot;https://vue-loader.vuejs.org/guide/scoped-css.html#deep-selectors&quot;&gt;deep selector&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;The resulting CSS is:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.layout[data-v-7ba5bd90] &gt; *&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The deep selector disables scoping for this rule and that&apos;s why it&apos;s important that we narrow the selector down to the direct children of &lt;code class=&quot;language-text&quot;&gt;.layout&lt;/code&gt; ourselves throught he means of the child combinator &lt;code class=&quot;language-text&quot;&gt;&amp;gt;&lt;/code&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Portals in Vue 2 don't work with Slot Props from Scoped Slots]]></title><link>https://coder.earth/post/portals-in-vue2-dont-work-with-slots-props-from-scoped-slots</link><guid isPermaLink="false">https://coder.earth/post/portals-in-vue2-dont-work-with-slots-props-from-scoped-slots</guid><pubDate>Sat, 27 Jan 2024 17:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/portal-b2dc5c73a74485c53d0f71d5032fd511-8805c.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 56.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAMFAQT/xAAUAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAGN2zcFgoT/xAAYEAEAAwEAAAAAAAAAAAAAAAACARAhE//aAAgBAQABBQIRqA4rZv8A/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGBAAAgMAAAAAAAAAAAAAAAAAABEgMUL/2gAIAQEABj8CHplQ/8QAGxABAQEAAgMAAAAAAAAAAAAAAREAEEFRYZH/2gAIAQEAAT8hCKXA+beshUB6NXV88f/aAAwDAQACAAMAAAAQHO//xAAWEQADAAAAAAAAAAAAAAAAAAAQESH/2gAIAQMBAT8QcH//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAcEAACAQUBAAAAAAAAAAAAAAABEQAhMUFRYXH/2gAIAQEAAT8QcFnY5lAwgAcBdPVBVE4EBOxh3Izuf//Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A portal&quot;
        title=&quot;&quot;
        src=&quot;/static/portal-b2dc5c73a74485c53d0f71d5032fd511-19371.jpg&quot;
        srcset=&quot;/static/portal-b2dc5c73a74485c53d0f71d5032fd511-c766d.jpg 300w,
/static/portal-b2dc5c73a74485c53d0f71d5032fd511-f0d1c.jpg 600w,
/static/portal-b2dc5c73a74485c53d0f71d5032fd511-19371.jpg 1200w,
/static/portal-b2dc5c73a74485c53d0f71d5032fd511-228e2.jpg 1800w,
/static/portal-b2dc5c73a74485c53d0f71d5032fd511-8805c.jpg 1920w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;There&apos;s a caveat worth keeping in mind when using portals through the means of &lt;a href=&quot;https://v2.portal-vue.linusb.org/&quot;&gt;portal-vue&lt;/a&gt; in Vue 2. &lt;strong&gt;You may notice that adding slot props prevents the view from updating, even if you don&apos;t actually use them.&lt;/strong&gt;  If there&apos;s a &lt;code class=&quot;language-text&quot;&gt;v-slot&lt;/code&gt;, the template doesn&apos;t refresh.&lt;/p&gt;
&lt;h2&gt;✅ How to make sure the teleported content reacts to changes?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;I believe that the only way to guarantee components update properly when they are sent through &lt;code class=&quot;language-text&quot;&gt;&amp;lt;portal&amp;gt;&lt;/code&gt; in Vue 2 is to use render functions instead of templates.&lt;/strong&gt; To simplify writing render functions, consider enabling &lt;a href=&quot;https://v2.vuejs.org/v2/guide/render-function#JSX&quot;&gt;JSX&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You might have seen &lt;a href=&quot;https://github.com/LinusBorg/portal-vue/issues/222#issuecomment-494352448&quot;&gt;this comment by Thorsten Lünborg&lt;/a&gt; (the author of portal-vue) in which he proposes a couple of interesting workarounds. Sadly, none of them worked reliably in my testing.&lt;/p&gt;
&lt;h2&gt;❌ What won&apos;t work?&lt;/h2&gt;
&lt;p&gt;There are steps that, when taken, may trick us into thinking we&apos;ve solved the bug. However, in reality the bug is still there and may reoccurr in any time. The following steps do not guarantee that that the problem will be solved once for good:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;adding &lt;code class=&quot;language-text&quot;&gt;v-if=&amp;quot;true&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;adding keys&lt;/li&gt;
&lt;li&gt;extracting more components&lt;/li&gt;
&lt;li&gt;using different scoped slots syntax in templates&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;But why do slot props break portals in Vue 2 in the first place?&lt;/h2&gt;
&lt;p&gt;Vue 2 doesn&apos;t have native portals; instead, they&apos;re provided by a third party library called portal-vue. In a nutshell, it works by sending a piece of the render function from one component to another.&lt;/p&gt;
&lt;p&gt;Vue 2.6 &lt;a href=&quot;https://github.com/vuejs/vue/pull/9371&quot;&gt;introduced a performance optimization&lt;/a&gt; of scoped slots. That&apos;s why &lt;a href=&quot;https://v2.vuejs.org/v2/api/#slot-scope-deprecated&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;slot-scope&lt;/code&gt; has been deprecated&lt;/a&gt;. But implementing this optimization &lt;a href=&quot;https://github.com/vuejs/vue/issues/9534&quot;&gt;proved to be a challenging task&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;What we can observe is that as soon as we go from this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;vue&quot;&gt;&lt;pre class=&quot;language-vue&quot;&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;lt;portal to=&amp;quot;destination&amp;quot;&amp;gt;
    &amp;lt;with-slot-props&amp;gt;
      hello world
    &amp;lt;/with-slot-props&amp;gt;
&amp;lt;/portal&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;to this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;vue&quot;&gt;&lt;pre class=&quot;language-vue&quot;&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;lt;portal to=&amp;quot;destination&amp;quot;&amp;gt;
    &amp;lt;with-slot-props v-slot=&amp;quot;props&amp;quot;&amp;gt;
      hello world
    &amp;lt;/with-slot-props&amp;gt;
&amp;lt;/portal&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;it breaks.&lt;/p&gt;
&lt;p&gt;Why?&lt;/p&gt;
&lt;p&gt;I found &lt;a href=&quot;https://github.com/Magiccwl/vue-compiler-online&quot;&gt;vue-compiler-online&lt;/a&gt; by Jack Chi extremely helpful in understanding what exactly happened. &lt;/p&gt;
&lt;p&gt;This is the actual render function created by the template compiler when we don&apos;t use slot props:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;_c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;portal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    attrs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;to&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;destination&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;_c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;with-slot-props&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;_v&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;hello world&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It changes quite drastically as soon as we add &lt;code class=&quot;language-text&quot;&gt;v-slot&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;slot-scope&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;_c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;portal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    attrs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;to&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;destination&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;_c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;with-slot-props&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// a mysterious _u function&lt;/span&gt;
    scopedSlots&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;_u&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        key&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// a new function&lt;/span&gt;
        fn&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;_v&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;hello world&quot;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There&apos;s a new function and it&apos;s not your &lt;a href=&quot;https://v2.vuejs.org/v2/guide/render-function#Slots&quot;&gt;typical scopedSlots function&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;_u&lt;/code&gt; stands for &lt;a href=&quot;https://github.com/vuejs/vue/blob/bed04a77e575d6c4c1d903f60087dca874f7213e/src/core/instance/render-helpers/resolve-scoped-slots.ts#L4&quot;&gt;resolveScopedSlots&lt;/a&gt; and when called like this, it produces a result with &lt;code class=&quot;language-text&quot;&gt;{ $stable: true }&lt;/code&gt;, which caches the output and thus prevents it from being re-rendered in portals.&lt;/p&gt;
&lt;h2&gt;How does writing the render function ourselves fix the problem?&lt;/h2&gt;
&lt;p&gt;If we write this render function ourselves, it won&apos;t be incorrectly cached by &lt;code class=&quot;language-text&quot;&gt;resolveScopedSlots&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;portal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; attrs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; to&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;destination&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;with-slot-props&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    scopedSlots&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; props &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;div&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;hello world&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;How to write render functions and not go crazy?&lt;/h2&gt;
&lt;p&gt;I don&apos;t know about you, but I don&apos;t usually write my HTML in raw render functions, and because I&apos;m not exposed to them, I don&apos;t find them readable. Fortunately, JSX can &lt;a href=&quot;https://github.com/vuejs/jsx-vue2?tab=readme-ov-file#slots&quot;&gt;make render functions with scoped slots prettier&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;portal&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;destination&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;with-slot-props&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;scopedSlots&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt; hello world &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;portal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Back to the familiar syntax, yay!&lt;/p&gt;
&lt;p&gt;If you want, you can play with JSX more in the &lt;a href=&quot;https://jsx-vue2-playground.netlify.app/&quot;&gt;JSX-Vue2 Playground&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Why don&apos;t workarounds like &lt;code class=&quot;language-text&quot;&gt;v-if=&amp;quot;true&amp;quot;&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;key&lt;/code&gt;, and &lt;code class=&quot;language-text&quot;&gt;slot-scope&lt;/code&gt; work?&lt;/h2&gt;
&lt;p&gt;Using the old &lt;code class=&quot;language-text&quot;&gt;slot-scope&lt;/code&gt; syntax compiles to exactly the same output as using &lt;code class=&quot;language-text&quot;&gt;v-slot&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Adding unique keys is possible only when we can predict what will end up in the portal upfront.&lt;/p&gt;
&lt;p&gt;Exctacting the content of the portal into a separate component works only when all the props we pass to it are the slot props. Other values, like props from the parent component, will become stale.&lt;/p&gt;
&lt;p&gt;Assigning &lt;code class=&quot;language-text&quot;&gt;v-if=&amp;quot;true&amp;quot;&lt;/code&gt; is the most interesting trap. This is what it compiles to:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;_c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;portal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  attrs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;to&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;destination&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;_c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;base-layout&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  scopedSlots&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;_u&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      key&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      fn&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;_c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;div&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;_v&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
              &lt;span class=&quot;token string&quot;&gt;&quot;hello world&quot;&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                   &lt;span class=&quot;token comment&quot;&gt;// A mysterious hash&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2480752568&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;_e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now the result is still cached, but this time under the &lt;code class=&quot;language-text&quot;&gt;2480752568&lt;/code&gt; key. It&apos;s derived from the template inside of the scoped slot. So if we change &lt;code class=&quot;language-text&quot;&gt;&amp;quot;hello world&amp;quot;&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;&amp;quot;hello code&amp;quot;&lt;/code&gt;, it becomes &lt;code class=&quot;language-text&quot;&gt;212219543&lt;/code&gt; instead of &lt;code class=&quot;language-text&quot;&gt;2480752568&lt;/code&gt;. The good news is that it &lt;em&gt;often&lt;/em&gt; prevents the template from going stale! The bad news is that it ignores variables. So if we have the following template:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;hello &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and we swap it for an identical template with a different &lt;code class=&quot;language-text&quot;&gt;name&lt;/code&gt; value, it won&apos;t refresh. &lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;I know that some people choose Vue solely because they are not big fans of JSX. However, JSX in render functions is the closest to reliable templates we have if we want to use Vue 2, portal-vue and slot props.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[(React) Old state when the user navigates back]]></title><link>https://coder.earth/post/react-old-state-when-the-user-navigates-back</link><guid isPermaLink="false">https://coder.earth/post/react-old-state-when-the-user-navigates-back</guid><pubDate>Thu, 04 Aug 2022 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/clocks-3fb04883014e4763f6ab208b2e527973-2fca5.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.79245283018868%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAwAE/8QAFgEBAQEAAAAAAAAAAAAAAAAAAQAC/9oADAMBAAIQAxAAAAHAoNbwyy//xAAYEAADAQEAAAAAAAAAAAAAAAAAAQIhA//aAAgBAQABBQKGzpTpE4PJcn//xAAVEQEBAAAAAAAAAAAAAAAAAAAAEf/aAAgBAwEBPwGI/8QAFREBAQAAAAAAAAAAAAAAAAAAABH/2gAIAQIBAT8BV//EABgQAAMBAQAAAAAAAAAAAAAAAAAQEQEh/9oACAEBAAY/AjeqlX//xAAaEAADAQEBAQAAAAAAAAAAAAAAAREhQTGB/9oACAEBAAE/IX8qcXUXGlkG9GmPbDa28Nvh/9oADAMBAAIAAwAAABAID//EABcRAAMBAAAAAAAAAAAAAAAAAAABESH/2gAIAQMBAT8QWqWf/8QAFhEBAQEAAAAAAAAAAAAAAAAAAAER/9oACAECAQE/ENSH/8QAGxABAQADAAMAAAAAAAAAAAAAAREAIUExUWH/2gAIAQEAAT8QR0vu4dhjUxA0mqYqq5VDZ18mJhElctOuACpseCZ//9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Clocks&quot;
        title=&quot;&quot;
        src=&quot;/static/clocks-3fb04883014e4763f6ab208b2e527973-19371.jpg&quot;
        srcset=&quot;/static/clocks-3fb04883014e4763f6ab208b2e527973-c766d.jpg 300w,
/static/clocks-3fb04883014e4763f6ab208b2e527973-f0d1c.jpg 600w,
/static/clocks-3fb04883014e4763f6ab208b2e527973-19371.jpg 1200w,
/static/clocks-3fb04883014e4763f6ab208b2e527973-228e2.jpg 1800w,
/static/clocks-3fb04883014e4763f6ab208b2e527973-c1f63.jpg 2400w,
/static/clocks-3fb04883014e4763f6ab208b2e527973-1e45c.jpg 3600w,
/static/clocks-3fb04883014e4763f6ab208b2e527973-2fca5.jpg 4240w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Let&apos;s say you&apos;re developing a React app that consists of a component that has some side effects. Perhaps it does something very important when it&apos;s mounted. Perhaps it matters that on the initial render it&apos;s in the right state.&lt;/p&gt;
&lt;p&gt;It all works well in the development mode, but the production build renders stale components when the user navigates back to the app after leaving it for another web page. In other words, when the user clicks the //back// button, the functions passed to &lt;code class=&quot;language-text&quot;&gt;useEffect&lt;/code&gt; don&apos;t run. After navigating back to the app, React doesn&apos;t notice the component being mounted. Moreover, it holds the old state that was there before the page was left! And it happens only in production builds! It never happens in the development mode. So, what exactly happens?&lt;/p&gt;
&lt;p&gt;It&apos;s the doing of a mechanism known as bfcache (or Back-Forward Cache). It&apos;s a cache that sometimes holds your entire page in memory. It even includes the state of your JavaScript app. When the user navigates back, it&apos;s as if they never left the page. What&apos;s good is that it&apos;s a tremendous boost in performance. What&apos;s bad is that it may lead to some unexpected behavior and it happens just sometimes, not all the time.&lt;/p&gt;
&lt;p&gt;You may expect your React app to be re-mounted when the user navigates back to it, but it won&apos;t happen. Instead, they will land on a page which is in the very same state it was the moment they left it.&lt;/p&gt;
&lt;p&gt;What makes it even more tricky is that if you use Create React App you may never observe such behavior in the the development mode, because in this mode bfcache doesn&apos;t really work.&lt;/p&gt;
&lt;p&gt;The good news is that you can register an event listener and be notified when the page is restored from the cache! Here&apos;s how you can use JavaScript to notice that the page is restored from the Back-Forward Cache:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pageshow&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; event &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;persisted&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;restored&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Equipped with that information, you can decide to re-render your component or restore the desired state in some other way.&lt;/p&gt;
&lt;p&gt;Alternatively, if you&apos;d like to prevent the pages from being cached in the first place, for instance because they contain some sensitive information you would prefer not to leak, you may deliver the SPA with the following header:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;cache-control: no-store&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.chrome.com/blog/page-lifecycle-api/&quot;&gt;Page Lifecycle API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/bfcache/&quot;&gt;bfcache&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Sure, I can start working on it right now! But is it a wise thing to do?]]></title><link>https://coder.earth/post/i-can-start-working-on-it-but-is-it-a-wise-thing-to-do</link><guid isPermaLink="false">https://coder.earth/post/i-can-start-working-on-it-but-is-it-a-wise-thing-to-do</guid><pubDate>Sat, 21 May 2022 16:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/foundry-c037fc13975219f3a542dea6ca2edb52-ef898.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAIBAwX/xAAVAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAABz6kJWJE//8QAGRABAAIDAAAAAAAAAAAAAAAAAgABEEFC/9oACAEBAAEFAmST1jVT/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGBAAAgMAAAAAAAAAAAAAAAAAAhEBIEH/2gAIAQEABj8CFSy23//EABkQAAMBAQEAAAAAAAAAAAAAAAABESExQf/aAAgBAQABPyFqL8K0q1g+jIFqP//aAAwDAQACAAMAAAAQyB//xAAWEQADAAAAAAAAAAAAAAAAAAAAESH/2gAIAQMBAT8Qdgz/xAAWEQEBAQAAAAAAAAAAAAAAAAAAEVH/2gAIAQIBAT8Qmo//xAAcEAEAAgIDAQAAAAAAAAAAAAABABEhMUFhcaH/2gAIAQEAAT8Qr2VsUHinUWYsX7UQLP2HeWIS6YNqC9k//9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A foundry&quot;
        title=&quot;&quot;
        src=&quot;/static/foundry-c037fc13975219f3a542dea6ca2edb52-19371.jpg&quot;
        srcset=&quot;/static/foundry-c037fc13975219f3a542dea6ca2edb52-c766d.jpg 300w,
/static/foundry-c037fc13975219f3a542dea6ca2edb52-f0d1c.jpg 600w,
/static/foundry-c037fc13975219f3a542dea6ca2edb52-19371.jpg 1200w,
/static/foundry-c037fc13975219f3a542dea6ca2edb52-ef898.jpg 1500w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;At some point I realized I had way too many pairs of flip-flops, so I proceeded to build software to solve this problem for good. I’m a software developer, after all, building software is what I do. &lt;/p&gt;
&lt;p&gt;Wait, what? Let’s start from the beginning.&lt;/p&gt;
&lt;p&gt;I love traveling and whenever I can, I travel lightly. It feels great to be able to leave the airport carrying just a backpack instead of a big suitcase which I’d have to lug around.&lt;/p&gt;
&lt;p&gt;Even though one-bagging has a lot of benefits, there are also some drawbacks. One of them is this minimalistic, additive packing model. Because of the fairly limited volume of a single backpack, I have to deliberately choose what to take with me instead of deciding what to leave at home. When there’s no room for any just in case items, it’s easy to forget about some useful yet not absolutely necessary stuff. For instance, for some reason I used to forget about flip-flops and ended up buying multiple extra pairs. Had I traveled with all my worldly possessions, I wouldn’t have to worry about it. But as you can guess, that’s not a feasible solution. Whenever possible, I want to be able to quickly pack all I need into a single bag, so that I can travel lightly without depriving myself.&lt;/p&gt;
&lt;p&gt;I tried making packing lists in Apple Notes, but they didn’t cut it. Depending on the nature of my trip, the list had to vary, so I found myself creating an entirely new list before each trip, what was time-consuming and error-prone.&lt;/p&gt;
&lt;p&gt;Then I searched for an app that would enable me to create custom, reusable packing lists.&lt;/p&gt;
&lt;p&gt;It turned out there wasn’t any app that’d satisfy my requirements. It seemed that I found a niche. So the obvious next step was to build an app to serve it, right? I’m a software engineer, I can do it.&lt;/p&gt;
&lt;p&gt;Fortunately, before diving deep into coding I asked myself a very important question - “Do I really need to build a custom app for that?”. &lt;/p&gt;
&lt;p&gt;I knew what kind of experience I wanted. I wanted to feel prepared for my trips. I wanted to feel calm while packing. And I wanted all that to be quick and hassle-free.&lt;/p&gt;
&lt;p&gt;Nowhere on my list was “I wanted that to be provided by a custom app”.&lt;/p&gt;
&lt;p&gt;So I created a Google Sheets spreadsheet. If you’re interested, you can watch &lt;a href=&quot;https://www.youtube.com/watch?v=cVWT3SX3reA&quot;&gt;a video introduction to my Reusable Packing List on YouTube&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Does it mean I overlooked the User Experience? By no means! I carefully designed, prototyped, and tested it. And how did it go? Better than I’d have imagined! Below are some of the things people said about it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“That spreadsheet is a work of art!”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;“It’s insanely amazing.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;“Awesome! It is quite beautiful!”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;“I love the spreadsheet!”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;“What a fantastic spreadsheet!”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;“I’d like to marry that spreadsheet.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It turns out people love it a ton. And building it didn’t cost a ton.&lt;/p&gt;
&lt;p&gt;Just because I was able to get myself busy with building a custom piece of software didn’t mean it was a wise thing to do. It could even be detrimental! It’d mean slower prototyping, slower testing, much later release and a greater risk of abandonment. Or, as Timothy Ferriss writes it in his book titled The 4-Hour Work Week:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Doing something unimportant well does not make it important.”&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Your XML security library is sabotaging your work. Here's what you can do about it.]]></title><link>https://coder.earth/post/your-xml-lib-is-sabotaging-your-work</link><guid isPermaLink="false">https://coder.earth/post/your-xml-lib-is-sabotaging-your-work</guid><pubDate>Sun, 12 Dec 2021 10:30:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a-person-doing-work-c48e949a7dc5ac90b7b87cc5c89756b8-8805c.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAECBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHITmJAr//EABgQAAMBAQAAAAAAAAAAAAAAAAECERAA/9oACAEBAAEFAlF6YjlGuf/EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABYQAQEBAAAAAAAAAAAAAAAAABABEf/aAAgBAQAGPwJ2P//EABgQAQEAAwAAAAAAAAAAAAAAAAERABBR/9oACAEBAAE/Ib4YxoFKncWidbr/2gAMAwEAAgADAAAAEA8P/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFREBAQAAAAAAAAAAAAAAAAAAEBH/2gAIAQIBAT8Qh//EABsQAQEBAAIDAAAAAAAAAAAAABEBACExUWFx/9oACAEBAAE/EOBGiazZSUffjXvSLpgM1YAn7nf/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A person doing work&quot;
        title=&quot;&quot;
        src=&quot;/static/a-person-doing-work-c48e949a7dc5ac90b7b87cc5c89756b8-19371.jpg&quot;
        srcset=&quot;/static/a-person-doing-work-c48e949a7dc5ac90b7b87cc5c89756b8-c766d.jpg 300w,
/static/a-person-doing-work-c48e949a7dc5ac90b7b87cc5c89756b8-f0d1c.jpg 600w,
/static/a-person-doing-work-c48e949a7dc5ac90b7b87cc5c89756b8-19371.jpg 1200w,
/static/a-person-doing-work-c48e949a7dc5ac90b7b87cc5c89756b8-228e2.jpg 1800w,
/static/a-person-doing-work-c48e949a7dc5ac90b7b87cc5c89756b8-8805c.jpg 1920w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Dear developer,&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Have you ever had the need to verify the signature of an XML document? Yes? Then I have bad news for you - the library you used to accomplish that task is sabotaging your work!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Doing all that cryptography is hard, and that&apos;s why you&apos;re offloading it to a library. It&apos;s a wise move! Sadly, that library is not helping you.&lt;/p&gt;
&lt;p&gt;Just look at its documentation! The examples span across tens of lines, and the README (hopefully) mentions at least a couple of things like this:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&quot;If you want to be sure that the data you&apos;re consuming has been signed, don&apos;t forget to call the method that validates the reference.&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&quot;If you want to be sure that the data you&apos;re consuming has been signed, don&apos;t forget to make sure that the node you&apos;re consuming equals the referenced node.&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&quot;If you want to be sure that the data you&apos;re consuming has been signed, don&apos;t forget to call the method that validates the signature.&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&quot;If you want to be sure that the data you&apos;re consuming has been signed, don&apos;t use the method we for some reason provide and which reads the public key from the payload.&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&quot;If you want to be sure that the data you&apos;re consuming has been signed, make sure your XPath queries are not reaching nodes that were removed in the canonicalization phase just before the digest was calculated.&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Whoa! 😱 What?! 🤯&lt;/p&gt;
&lt;p&gt;If you&apos;re like me when I first stumbled upon XML signatures years ago, you may be asking yourself questions along the lines of:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&quot;Isn&apos;t checking the signature enough? Why do I have to additionally check the validity some reference?&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&quot;How do I compare some node to the referenced node?&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&quot;What does reference even mean in this context?&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&quot;So you&apos;re giving me some method and then telling me it&apos;s not safe to call it?&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&quot;Canonica... What? What digest? Where? What should I do with it? Why do I even have to think about it myself?! Wasn&apos;t this library supposed to help me?&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Not only are the examples convoluted, but they&apos;re incomplete and can make your app vulnerable!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You. Deserve. Better!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You don’t have to simply accept the fact that the library you’re using is working against you.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Just imagine how much easier your life as a developer would be if you could simply write:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getTheOnlySignedNodeOrNull&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xml&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; publicKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Imagine &lt;em&gt;node&lt;/em&gt; being either null or an XML node that&apos;s for sure entirely signed with the given public key.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Imagine not worrying anymore about things like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Are both the reference and signature validated?&lt;/li&gt;
&lt;li&gt;Is this what was referenced?&lt;/li&gt;
&lt;li&gt;Is this part of the signed node actually signed, or is this something that&apos;s been stripped in the canonicalization phase?&lt;/li&gt;
&lt;li&gt;Is the public key trusted, or was it supplied by the attacker?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&apos;d be so much easier! So much safer!&lt;/p&gt;
&lt;p&gt;And if you needed to read a couple of signed nodes, you could simply call:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;nodesArray &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getSignedNodes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xml&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; publicKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I know, your library doesn&apos;t like look like that. But you can do something to fix it, even if you’re not a security expert yourself! &lt;strong&gt;If it’s on GitHub, simply open an issue describing the problem and propose adding the safer API described above.&lt;/strong&gt; Feel free to link to this blog post.&lt;/p&gt;
&lt;p&gt;You don’t have to invest too much time to get the discussion going. And once people are talking about it, someone will implement the fix. Maybe it will even be you!&lt;/p&gt;
&lt;p&gt;Let’s make the internet more secure!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Are XML Signatures secure?]]></title><link>https://coder.earth/post/are-xml-signatures-secure</link><guid isPermaLink="false">https://coder.earth/post/are-xml-signatures-secure</guid><pubDate>Fri, 17 Sep 2021 13:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/sealed-envelope-dd8beab252548d1e5df918932fabf2db-8805c.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAEDBP/EABcBAAMBAAAAAAAAAAAAAAAAAAABAgP/2gAMAwEAAhADEAAAAVu2d86h/wD/xAAZEAEBAQADAAAAAAAAAAAAAAACAREAEiH/2gAIAQEAAQUCBus2ynheTvsS9//EABURAQEAAAAAAAAAAAAAAAAAABAh/9oACAEDAQE/Aaf/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAZEAADAAMAAAAAAAAAAAAAAAAAEDEiUWH/2gAIAQEABj8C4Y7UIv/EABsQAQACAgMAAAAAAAAAAAAAAAEAESExQXGx/9oACAEBAAE/IU4HaAi3BalblixFR9S7Sf/aAAwDAQACAAMAAAAQRM//xAAXEQEBAQEAAAAAAAAAAAAAAAABABFh/9oACAEDAQE/EHmFy//EABYRAQEBAAAAAAAAAAAAAAAAAAARAf/aAAgBAgEBPxDIj//EABoQAQADAQEBAAAAAAAAAAAAAAEAETFRcfD/2gAIAQEAAT8QHBhdO+EQS7gKItYLXIIKNHdl4Vs+ZFF47P/Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A sealed envelope&quot;
        title=&quot;&quot;
        src=&quot;/static/sealed-envelope-dd8beab252548d1e5df918932fabf2db-19371.jpg&quot;
        srcset=&quot;/static/sealed-envelope-dd8beab252548d1e5df918932fabf2db-c766d.jpg 300w,
/static/sealed-envelope-dd8beab252548d1e5df918932fabf2db-f0d1c.jpg 600w,
/static/sealed-envelope-dd8beab252548d1e5df918932fabf2db-19371.jpg 1200w,
/static/sealed-envelope-dd8beab252548d1e5df918932fabf2db-228e2.jpg 1800w,
/static/sealed-envelope-dd8beab252548d1e5df918932fabf2db-8805c.jpg 1920w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The short answer is that in practice XML signatures are insecure and shouldn&apos;t be relied upon.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now, I know that&apos;s quite a statement, but please hear me out.&lt;/p&gt;
&lt;h2&gt;What are digital signatures, again?&lt;/h2&gt;
&lt;p&gt;Digital signatures are a way to ensure that a piece of data has been released by a particular party and that it hasn&apos;t been modified by a third party.&lt;/p&gt;
&lt;p&gt;The premise is simple: if we have the public key of the sender, we can check if some data has been signed by that sender. To sign data, you need to be in possession of the private key and that&apos;s why only the legitimate sender can sign documents.&lt;/p&gt;
&lt;p&gt;It&apos;s a wonderfully simple concept.&lt;/p&gt;
&lt;p&gt;For example, you can sign a document and pass it from one system to another through some front channel, such as a web browser, and if the data is correctly signed, you can be sure that no malicious actor modified it.&lt;/p&gt;
&lt;h2&gt;What makes signing XML tricky?&lt;/h2&gt;
&lt;p&gt;As I mentioned earlier, signatures are simple. But add XML to the equation and you get an incredibly complex, tricky and practically insecure mechanism.&lt;/p&gt;
&lt;p&gt;Just have a look at this XML document describing a classic pizza:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;pizza&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;_0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Margherita&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;details&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ingredients&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;mozzarella&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;tomatoes&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;basil&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ingredients&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;details&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Signature&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;xmlns&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2000/09/xmldsig#&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;SignedInfo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;CanonicalizationMethod&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Algorithm&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2001/10/xml-exc-c14n#&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;SignatureMethod&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Algorithm&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2000/09/xmldsig#rsa-sha1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Reference&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;#_0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Transforms&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Transform&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Algorithm&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2000/09/xmldsig#enveloped-signature&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Transforms&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;DigestMethod&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Algorithm&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2000/09/xmldsig#sha1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;DigestValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;IaSUjZiQc6CtB9EjeSS6R96bIWo=&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;DigestValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Reference&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;SignedInfo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;SignatureValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;ReJkW/mCaIbX+UZBoZRl+uoqXFQeN7/Tm4gGG9tpqVtvIHTkZTFk7/K/EG9IS6dmqM46qCNRq+yymm8MvLJu2/Iey4A0ZGyZ5etY4jHiIju2L5gfF/orHjfXkhbpT7qbJ3+5rtKed/p3hrX1wdY8gikCC6XgNC3LKsi9C1NhkQ4YhyFnGrnXKoGeEkBFsyaJWiRY7CFVm5aMDzSF+bO7WrdF0wtuayIBR0+fz6bbt7PVWWypEPhOzu8DsZnSXocy51ASY7LW2f7HyPVhsui9XMMcdTT4mGIJnGJeM8wVmCi40QWrQuIEXtAfISDjFz2U7eiP2jLKPQg88Wxhao0ymQ==&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;SignatureValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Signature&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;pizza&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The goal of the code consuming this document is simple: verify the signature and read the list of ingredients.&lt;/p&gt;
&lt;p&gt;I decided to use JavaScript to illustrate the examples just because it&apos;s popular, but judging from my experience in the security industry you can run into such errors in any language.&lt;/p&gt;
&lt;p&gt;Here&apos;s an implementation based on the documentation of the library used to verify the signature:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Imports:&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; select &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;xml-crypto&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xpath
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; dom &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;@xmldom/xmldom&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;DOMParser&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; SignedXml &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;xml-crypto&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SignedXml&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; FileKeyInfo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;xml-crypto&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;FileKeyInfo&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;fs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Loading data:&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; xml &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; fs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;readFileSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;signed.xml&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; doc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;dom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseFromString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xml&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; signature &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;//*[local-name(.)=&apos;Signature&apos; and namespace-uri(.)=&apos;http://www.w3.org/2000/09/xmldsig#&apos;]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; sig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SignedXml&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
sig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;keyInfoProvider &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FileKeyInfo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;cert.pem&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
sig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;loadSignature&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signature&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Verifying the signature:&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; correctlySigned &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;checkSignature&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xml&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;correctlySigned&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Making sure the element we work with is signed. Based on the docs.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pizza &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/pizza&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; uri &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;references&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;uri&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uri&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;#&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; uri&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;substring&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; uri&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pizza&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAttribute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;ID&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; id &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; pizza&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAttribute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; id &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; pizza&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAttribute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;id&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;the interesting element was not the one verified by the signature&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Reading ingredients:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ingredients &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pizza&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;//ingredient&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;node &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;textContent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ingredients&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;validationErrors&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is what we get if we run it:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;➜  node read.js
[ &amp;#39;mozzarella&amp;#39;, &amp;#39;tomatoes&amp;#39;, &amp;#39;basil&amp;#39; ]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let&apos;s see what happens when we change &lt;em&gt;basil&lt;/em&gt; to &lt;em&gt;oregano&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;pizza&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;_0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Margherita&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;details&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ingredients&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;mozzarella&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;tomatoes&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;oregano&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ingredients&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;details&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Signature&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;xmlns&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2000/09/xmldsig#&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;SignedInfo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;CanonicalizationMethod&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Algorithm&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2001/10/xml-exc-c14n#&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;SignatureMethod&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Algorithm&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2000/09/xmldsig#rsa-sha1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Reference&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;#_0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Transforms&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Transform&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Algorithm&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2000/09/xmldsig#enveloped-signature&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Transforms&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;DigestMethod&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Algorithm&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2000/09/xmldsig#sha1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;DigestValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;IaSUjZiQc6CtB9EjeSS6R96bIWo=&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;DigestValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Reference&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;SignedInfo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;SignatureValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;ReJkW/mCaIbX+UZBoZRl+uoqXFQeN7/Tm4gGG9tpqVtvIHTkZTFk7/K/EG9IS6dmqM46qCNRq+yymm8MvLJu2/Iey4A0ZGyZ5etY4jHiIju2L5gfF/orHjfXkhbpT7qbJ3+5rtKed/p3hrX1wdY8gikCC6XgNC3LKsi9C1NhkQ4YhyFnGrnXKoGeEkBFsyaJWiRY7CFVm5aMDzSF+bO7WrdF0wtuayIBR0+fz6bbt7PVWWypEPhOzu8DsZnSXocy51ASY7LW2f7HyPVhsui9XMMcdTT4mGIJnGJeM8wVmCi40QWrQuIEXtAfISDjFz2U7eiP2jLKPQg88Wxhao0ymQ==&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;SignatureValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Signature&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;pizza&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;➜  node read.js
[ &amp;#39;invalid signature: for uri #_0 calculated digest is kK2GwWhLPYK/zAa8MoEJ3FPIkGk= but the xml to validate supplies digest IaSUjZiQc6CtB9EjeSS6R96bIWo=&amp;#39; ]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We&apos;ve got a validation error. That&apos;s good, right? Right! It means nobody can manipulate this data, right? Wrong!&lt;/p&gt;
&lt;p&gt;You see, there are so many complex operations going on that it&apos;s really hard to fully understand it. The underlying signing algorithm is solid and libraries make it easy to use. It takes the data, the signature, and the key and tells us whether this key was used to generate this signature for this data. But our case is inherently more complex! We have an XML document which is a tree structure. The signature isn&apos;t provided as a separate argument, but is placed inside the signed document instead. And in order to read data, we use a query language (XPath) to query for &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ingredient /&amp;gt;&lt;/code&gt; nodes. Moreover, we don&apos;t even query the same document that has been signed! More on that below.&lt;/p&gt;
&lt;p&gt;When the document was being signed, it didn&apos;t have a signature. The signature is derived from the unsigned document and only then placed inside it. That&apos;s why before verifying it, the document is reverted to its initial form. It means removing the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Signature /&amp;gt;&lt;/code&gt; node from the tree. That&apos;s what the &lt;code class=&quot;language-text&quot;&gt;http://www.w3.org/2000/09/xmldsig#enveloped-signature&lt;/code&gt; transformation does. There are also other operations going on, like canonicalization, which helps to ignore the differences between things like &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Node /&amp;gt;&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Node&amp;gt;&amp;lt;/Node&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;That&apos;s why even thought we&apos;re loading something like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;pizza&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;field&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;field&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Signature&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;xmlns&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2000/09/xmldsig#&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;...&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Signature&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;pizza&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;we may be calculating the signature of something more like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;pizza&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;field&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;pizza&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The fact that a huge chunk of the tree disappears is interesting from an attacker&apos;s perspective and terrifying from a developer&apos;s perspective.&lt;/p&gt;
&lt;p&gt;When we&apos;re looking for &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ingredient /&amp;gt;&lt;/code&gt; nodes, we&apos;re querying the signed document. It means that in it still has the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Signature /&amp;gt;&lt;/code&gt; subtree in it. But because the signature itself isn&apos;t signed, we can add there anything we want, even another &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ingredient /&amp;gt;&lt;/code&gt; node:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;pizza&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;_0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Margherita&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;details&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ingredients&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;mozzarella&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;tomatoes&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;basil&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ingredients&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;details&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Signature&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;xmlns&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2000/09/xmldsig#&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ingredient&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;xmlns&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;pineapple&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ingredient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;SignedInfo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;CanonicalizationMethod&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Algorithm&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2001/10/xml-exc-c14n#&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;SignatureMethod&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Algorithm&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2000/09/xmldsig#rsa-sha1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Reference&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;#_0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Transforms&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Transform&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Algorithm&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2000/09/xmldsig#enveloped-signature&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Transforms&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;DigestMethod&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;Algorithm&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2000/09/xmldsig#sha1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;DigestValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;IaSUjZiQc6CtB9EjeSS6R96bIWo=&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;DigestValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Reference&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;SignedInfo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;SignatureValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;ReJkW/mCaIbX+UZBoZRl+uoqXFQeN7/Tm4gGG9tpqVtvIHTkZTFk7/K/EG9IS6dmqM46qCNRq+yymm8MvLJu2/Iey4A0ZGyZ5etY4jHiIju2L5gfF/orHjfXkhbpT7qbJ3+5rtKed/p3hrX1wdY8gikCC6XgNC3LKsi9C1NhkQ4YhyFnGrnXKoGeEkBFsyaJWiRY7CFVm5aMDzSF+bO7WrdF0wtuayIBR0+fz6bbt7PVWWypEPhOzu8DsZnSXocy51ASY7LW2f7HyPVhsui9XMMcdTT4mGIJnGJeM8wVmCi40QWrQuIEXtAfISDjFz2U7eiP2jLKPQg88Wxhao0ymQ==&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;SignatureValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Signature&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;pizza&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Even though we weren&apos;t able to forge the signature, when we run the code again, we get a little surprise:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;➜ node read.js
[ &amp;#39;mozzarella&amp;#39;, &amp;#39;tomatoes&amp;#39;, &amp;#39;basil&amp;#39;, &amp;#39;pineapple&amp;#39; ]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We&apos;ve got pineapple on our pizza!&lt;/p&gt;
&lt;p&gt;What happened is that even though the data was properly signed, this signed data was just a subset of the queried data. &lt;strong&gt;The malicious payload was placed in the unsigned yet queried portion of the document, which is the surprisingly hard to avoid root cause of attacks aimed at XML signatures.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;How to make XML signatures more secure?&lt;/h2&gt;
&lt;p&gt;Does this mean it&apos;s impossible to properly validate an XML signature? No, it&apos;s technically possible. Some of the steps that may be taken in order to increase the trust in XML signatures include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Applying strict &lt;a href=&quot;https://en.wikipedia.org/wiki/XML_schema&quot;&gt;XML schemas&lt;/a&gt;, even for the signature node.&lt;/li&gt;
&lt;li&gt;Avoiding enveloped signatures by placing signatures outside the signed node.&lt;/li&gt;
&lt;li&gt;Using precise selectors such as &lt;code class=&quot;language-text&quot;&gt;/pizza/details/ingredients/ingredient&lt;/code&gt; instead of relaxed queries like &lt;code class=&quot;language-text&quot;&gt;//ingredient&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Considering the library used to work with XML documents high-risk and always, and I mean always, keeping it up to date.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Should you rely on XML signatures?&lt;/h2&gt;
&lt;p&gt;In reality, thought, it&apos;s very hard to expect all these criteria to be met as it requires niche knowledge. And even if you have great specialists, they may still make mistakes, as did &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2016-0132&quot;&gt;people at Microsoft&lt;/a&gt; and &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-37843&quot;&gt;Atlassian&lt;/a&gt;. Similar issues were found in popular &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-5407&quot;&gt;Java&lt;/a&gt; and &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-7644&quot;&gt;PHP&lt;/a&gt; libraries.&lt;/p&gt;
&lt;p&gt;I must say that when I first worked with XML signatures a couple of years ago it was a humbling experience. I don&apos;t know how big my ego would have to be for me to think that I can certainly get it right even though so many smart people got it wrong.&lt;/p&gt;
&lt;p&gt;Even some protocols that started as dependent on XML signatures, such as SAML 2.0, later introduced solutions that don&apos;t require pristine signature validation. For example, SAML used to rely on signed XMLs being transmitted via the browser from one server to another but now it uses a kind of server to server communication (&lt;a href=&quot;https://en.wikipedia.org/wiki/SAML_2.0#HTTP_Artifact_Binding&quot;&gt;HTTP Artifact binding&lt;/a&gt;) where the sensitive data is sent in the response to the server and not in the request. Doing it this way significantly reduces the attack surface.&lt;/p&gt;
&lt;p&gt;That&apos;s why even though in theory it&apos;s possible to securely verify an XML signature, I believe it&apos;s worth keeping in mind that the risk of failing to do so is very high.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to merge the composer.lock file?]]></title><link>https://coder.earth/post/how-to-merge-composer-lock</link><guid isPermaLink="false">https://coder.earth/post/how-to-merge-composer-lock</guid><pubDate>Fri, 14 May 2021 18:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/galaxy-574532eb4e2d97cf7779856a8ecf0874-989cc.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 71.75999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAOABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAQBAgMF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAB5LqcGZQP/8QAGxAAAwACAwAAAAAAAAAAAAAAAAECAxESEyH/2gAIAQEAAQUCU7OlTLXsZOJWV0bP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGRAAAgMBAAAAAAAAAAAAAAAAEBEAAQIx/9oACAEBAAY/Aqj0OM//xAAbEAADAAIDAAAAAAAAAAAAAAAAATEQESFRgf/aAAgBAQABPyFvgLtSCoHquGk2W5h//9oADAMBAAIAAwAAABCb7//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABkQAAMBAQEAAAAAAAAAAAAAAAABEVExIf/aAAgBAQABPxDKXwJvi0tdZa4WCffRwG0aYG1Z/9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A galaxy&quot;
        title=&quot;&quot;
        src=&quot;/static/galaxy-574532eb4e2d97cf7779856a8ecf0874-19371.jpg&quot;
        srcset=&quot;/static/galaxy-574532eb4e2d97cf7779856a8ecf0874-c766d.jpg 300w,
/static/galaxy-574532eb4e2d97cf7779856a8ecf0874-f0d1c.jpg 600w,
/static/galaxy-574532eb4e2d97cf7779856a8ecf0874-19371.jpg 1200w,
/static/galaxy-574532eb4e2d97cf7779856a8ecf0874-228e2.jpg 1800w,
/static/galaxy-574532eb4e2d97cf7779856a8ecf0874-c1f63.jpg 2400w,
/static/galaxy-574532eb4e2d97cf7779856a8ecf0874-989cc.jpg 2500w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;So you&apos;re working on a PHP project using Composer and a merge conflict occurs on the composer.lock file. How do you merge it? Well, it may sound a bit strange, but the short answer is: You don&apos;t.&lt;/p&gt;
&lt;p&gt;The composer.lock file is meant to be generated by Composer. It must not be modified in any other way, or it&apos;ll become corrupted, and you&apos;ll end up installing random stuff. Sometimes. On some machines. Yeah, I know, it sounds horrible, doesn&apos;t it? &lt;/p&gt;
&lt;p&gt;Composer should be the only tool used to change the composer.lock file. It means it cannot be altered in PhpStorm or Sublime Text. Moreover, even Git should not be used to merge changes into it! Even though it looks like yet another text file, Composer relies on its integrity. And to Git it&apos;s, well, just another collection of lines. That&apos;s why it makes sense to mark it as a binary file in Git&apos;s .gitattributes file:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;composer.lock binary&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But then what do you do when a conflict does occur? There are two ways to tackle that.&lt;/p&gt;
&lt;p&gt;Assuming that you have amazing tests you can completely rely on, then your first option is to accept the changes to the composer.json file, completely remove the composer.lock file, and regenerate it from scratch by running the &lt;code class=&quot;language-text&quot;&gt;composer install&lt;/code&gt; command. It&apos;ll &quot;work&quot;, but frankly, that&apos;s not why we have the lock file in the first place. It&apos;ll result in all the dependencies being updated. And I mean all of them. Of course, they&apos;ll be updated only within the constraints set by the composer.json file, but still.&lt;/p&gt;
&lt;p&gt;The more down-to-earth approach is to look at what changed in the commit you want to merge and reapply those changes by running commands such as &lt;code class=&quot;language-text&quot;&gt;composer require&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;composer remove&lt;/code&gt;. It&apos;ll give Composer a chance to protect the integrity of the dependencies and it won&apos;t automatically bump the version of everything else.&lt;/p&gt;
&lt;p&gt;To sum it up: treat the composer.lock file as if it were an image. You wouldn&apos;t use a line-based merging tool to merge different images. And you wouldn&apos;t manually edit them in a text editor either (unless you&apos;re a 10x developer, of course 😉).&lt;/p&gt;
&lt;p&gt;If you&apos;d like to read more about it, there&apos;s &lt;a href=&quot;https://getcomposer.org/doc/articles/resolving-merge-conflicts.md&quot;&gt;a great chapter of the docs that touches upon the topic of resolving merge conflicts&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[React hooks... Oops! Part 4 - API responses get out of sync with the state]]></title><link>https://coder.earth/post/react-hooks-oops-part-4-api-responses-get-out-of-sync-with-the-state</link><guid isPermaLink="false">https://coder.earth/post/react-hooks-oops-part-4-api-responses-get-out-of-sync-with-the-state</guid><pubDate>Sun, 28 Mar 2021 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a-man-in-front-of-a-monitor-6fd21762645c3359cd23623aa2df54b0-8805c.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 80%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAQABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAgADBf/EABYBAQEBAAAAAAAAAAAAAAAAAAEAAv/aAAwDAQACEAMQAAAB5+CMGVs//8QAGhAAAgMBAQAAAAAAAAAAAAAAAAECERIhMf/aAAgBAQABBQKWc0mqPEpKJw//xAAVEQEBAAAAAAAAAAAAAAAAAAAAEf/aAAgBAwEBPwGq/8QAFhEBAQEAAAAAAAAAAAAAAAAAABES/9oACAECAQE/Aco//8QAGRAAAgMBAAAAAAAAAAAAAAAAEDEAASGB/9oACAEBAAY/Asovgc//xAAaEAEAAwEBAQAAAAAAAAAAAAABABEhQYGx/9oACAEBAAE/ITdV5DEN7EkGtA/EYvsbbH//2gAMAwEAAgADAAAAEIwf/8QAGBEBAQADAAAAAAAAAAAAAAAAAQARIaH/2gAIAQMBAT8QaDG3l//EABgRAQADAQAAAAAAAAAAAAAAAAEAESGh/9oACAECAQE/EBVE3h2f/8QAHBABAQADAAMBAAAAAAAAAAAAAREAITFBYXGB/9oACAEBAAE/EGrowa3ggcJPJxeNX7M1li8cc7+4tNS0ZQyoVKb1z1n/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A man in front of a monitor&quot;
        title=&quot;&quot;
        src=&quot;/static/a-man-in-front-of-a-monitor-6fd21762645c3359cd23623aa2df54b0-19371.jpg&quot;
        srcset=&quot;/static/a-man-in-front-of-a-monitor-6fd21762645c3359cd23623aa2df54b0-c766d.jpg 300w,
/static/a-man-in-front-of-a-monitor-6fd21762645c3359cd23623aa2df54b0-f0d1c.jpg 600w,
/static/a-man-in-front-of-a-monitor-6fd21762645c3359cd23623aa2df54b0-19371.jpg 1200w,
/static/a-man-in-front-of-a-monitor-6fd21762645c3359cd23623aa2df54b0-228e2.jpg 1800w,
/static/a-man-in-front-of-a-monitor-6fd21762645c3359cd23623aa2df54b0-8805c.jpg 1920w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;In the previous post from &lt;a href=&quot;https://coder.earth/post/react-hooks-oops-part-1-introduction&quot;&gt;the React hooks... Oops! series&lt;/a&gt; we made it clear that &lt;a href=&quot;https://coder.earth/post/react-hooks-oops-part-3-an-effect-does-not-run-again-when-its-dependencies-change&quot;&gt;placing values in the dependency list of &lt;code class=&quot;language-text&quot;&gt;useEffect&lt;/code&gt; doesn&apos;t turn them into observables&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Today we&apos;ll examine why the state may get out of sync.&lt;/p&gt;
&lt;p&gt;React made working with the DOM API a breeze! Thanks to its simple, declarative nature, it is no longer a challenge to correctly synchronize the DOM with the state of the application. It simply works, and that&apos;s awesome! 🎉&lt;/p&gt;
&lt;p&gt;But the DOM API is not the only API there is. In fact, many React apps end up fetching data from some other APIs, like a REST API. React itself doesn&apos;t provide us with any tools designed specifically for data fetching. But hey! It&apos;s nothing new! So it shouldn&apos;t be a problem, right? 🤔 &lt;strong&gt;Sadly, if we&apos;re not careful enough, API responses may get out of sync with the state of the app!&lt;/strong&gt; 😨&lt;/p&gt;
&lt;p&gt;Let&apos;s maybe have a look at a concrete example. This is the app we&apos;re building.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/react-app-fetching-data-08c84e10647a9638a123f9cfb3ebc679.gif&quot; alt=&quot;A simple react app fetching data from the backend&quot;&gt;&lt;/p&gt;
&lt;p&gt;There are tabs representing different characters. Clicking a tab fetches the surname of the selected character from a backend API.&lt;/p&gt;
&lt;p&gt;This is the code of the card component:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;CharacterCard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; characterId &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;character&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setCharacter&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;fetchCharacter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;characterId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;setCharacter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;characterId&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; character &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;article&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        It&apos;s &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;character&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstname&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;character&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastname&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;article&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You might have already seen plenty of examples like that. &lt;code class=&quot;language-text&quot;&gt;useEffect&lt;/code&gt; is responsible for actually calling the &lt;code class=&quot;language-text&quot;&gt;fetchCharacter&lt;/code&gt; function and then &lt;code class=&quot;language-text&quot;&gt;useState&lt;/code&gt; holds the received data.&lt;/p&gt;
&lt;p&gt;The good news is that it works most of the times. The bad news is that it works only most of the times.&lt;/p&gt;
&lt;p&gt;This is what happens when the network connectivity is unstable and the user clicks quickly.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/react-state-getting-out-of-sync-f313b2f624d103489167381cfa433698.gif&quot; alt=&quot;React state getting out of sync&quot;&gt;&lt;/p&gt;
&lt;p&gt;The selected tab is the one for Murl, but the user sees Milan&apos;s data. It&apos;s buggy! 🐛 Why?&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;useEffect&lt;/code&gt;&apos;s dependency array makes it possible to synchronize triggering the effect with some state. In our example, every time the &lt;code class=&quot;language-text&quot;&gt;characterId&lt;/code&gt; changes (and the component re-renders), it calls &lt;code class=&quot;language-text&quot;&gt;fetchCharacter&lt;/code&gt;. What happens next happens outside of React. &lt;strong&gt;The results of async functions triggered inside &lt;code class=&quot;language-text&quot;&gt;useEffect&lt;/code&gt; are not synchronized with the effect&apos;s dependency array.&lt;/strong&gt; For us it means that React will call &lt;code class=&quot;language-text&quot;&gt;fetchCharacter&lt;/code&gt; and then receive the data through &lt;code class=&quot;language-text&quot;&gt;setCharacter&lt;/code&gt;, but when and in what order it happens depends on the network. &lt;/p&gt;
&lt;p&gt;The app is buggy because even though the user first clicked the tab for Milan and only then the one for Murl, the HTTP response for Milan came after the one for Murl. The effects are triggered in the right order, but the results come in an unpredictable order. And because we simply update the state of the card when we get a response, making the wrong assumption that it&apos;ll be in sync with the state of the tab, there&apos;s a bug in the app.&lt;/p&gt;
&lt;p&gt;How to fix it?&lt;/p&gt;
&lt;p&gt;One way would be to use the &lt;code class=&quot;language-text&quot;&gt;useRef&lt;/code&gt; hook and place the current &lt;code class=&quot;language-text&quot;&gt;characterId&lt;/code&gt; in that ref, so that in the &lt;code class=&quot;language-text&quot;&gt;.then&lt;/code&gt; callback of the Promise returned by the &lt;code class=&quot;language-text&quot;&gt;fetchCharacter&lt;/code&gt; function we can check if we&apos;re still interested in the response for that particular character. So many moving pieces! 🤯 &lt;/p&gt;
&lt;p&gt;Lucky us, there&apos;s a better way. It&apos;s true making API requests is nothing new and that it shouldn&apos;t be hard. It&apos;s just that the built-in hooks are low-level building blocks, designed to build on top of them, and not something optimized for specific use cases. That&apos;s why if we want to query the backend, we&apos;re better off using hooks designed specifically for that. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://react-query.tanstack.com/&quot;&gt;React query&lt;/a&gt; is a library that makes this and many other problems go away.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The same component refactored to use a high-level hook designed specifically for working with APIs looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;CharacterCard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; characterId &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; character &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;character&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; characterId&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fetchCharacter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;article&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        It&apos;s &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;character&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstname&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;character&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastname&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;article&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;One hook. One line. Zero bugs.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/react-query-enables-fetching-data-without-bugs-0acbf84b082002f2f4bf95bded6803b7.gif&quot; alt=&quot;React query enables fetching data without bugs.gif&quot;&gt;&lt;/p&gt;
&lt;p&gt;Judging from my professional experience, react query dramatically decreases the amount of code you have to write, makes apps less buggy and even faster!&lt;/p&gt;
&lt;p&gt;A friend of mine once put it that way:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Where has this been my whole life?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I hope you&apos;ll give react query a go!&lt;/p&gt;
&lt;p&gt;Stay tuned for the next post!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[It's 2020. Why is testing front-end applications so hard?]]></title><link>https://coder.earth/post/testing-front-end-in-2020</link><guid isPermaLink="false">https://coder.earth/post/testing-front-end-in-2020</guid><pubDate>Fri, 15 May 2020 08:37:20 GMT</pubDate><content:encoded>&lt;p&gt;In his book &quot;Thinking, Fast and Slow&quot;, the Nobel Prize-winning psychologist Daniel Kahneman writes about the idea of substitution. It&apos;s a mechanism that enables us to quickly answer difficult questions by replacing them with similar, but easier questions. For example, when asked if it makes sense to invest in Apple stock, we may say whether we like Apple products, without even noticing that we didn&apos;t answer the original question. Recently it occurred to me that this phenomenon may be observed in testing front-end applications as well.&lt;/p&gt;
&lt;p&gt;The front-end world is evolving rapidly. We can see people from various backgrounds getting into it. Some of them, including myself, used to be back-end developers. When facing a serious challenge, such as &quot;How do I test this application?&quot;, having some experience in a similar field puts us at risk of  unconsciously answering a different question, like &quot;Which parts of this application do I know how to test?&quot;.&lt;/p&gt;
&lt;p&gt;If we know how to test a method returning an integer, we may try to interact with a front-end application as if it were an object with a method returning an integer. For example, we may count the number of table row nodes in the DOM, without even checking that they are rendered one after another instead of on top of each other. Or if we are no strangers to string comparison, we may settle for checking if the value of a DOM Text node matches our expectations, without verifying that the font is readable.&lt;/p&gt;
&lt;p&gt;Does that make the tests we write useless? Not necessarily. They may be testing something after all. When in doubt, I ask myself whether I&apos;d still write similar assertions even if the code I think I&apos;m testing didn&apos;t run in a browser. Looking from 30 000 feet, would the tests still look the same, even if the app was a command-line utility or a REST API? If yes, then I may be testing everything but the very front end of my front end. And if that question doesn&apos;t help, I use &lt;a href=&quot;https://coder.earth/post/font-weight-testing&quot;&gt;the font-weight benchmark for front-end tests&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What does the font-weight property tell us about automated testing in the front-end world?]]></title><link>https://coder.earth/post/font-weight-testing</link><guid isPermaLink="false">https://coder.earth/post/font-weight-testing</guid><pubDate>Mon, 09 Mar 2020 08:37:20 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve been lucky enough to start my career as a software developer in the era when automated testing was already a thing. If not always the reality, then at least a thing people talked about. And that&apos;s why since my very first year as a professional developer, inspired by Kent Beck&apos;s and Uncle Bob&apos;s books, I&apos;ve been trying to automate testing the systems I worked on, with varying degrees of success.&lt;/p&gt;
&lt;p&gt;After a couple of years of working as a back-end developer, I often knew which testing strategies would pay off, and which ones would bite me. I didn&apos;t feel overwhelmed or lost on a daily basis anymore. Actually, I felt pretty proficient at my job. I knew how to leverage automated tests to fill me with confidence that the software I was building actually did what I expected it to do. But then I grew interested in front-end web development, with all its quirks and wonders. The period when I handed a ThinkPad back, got a Mac, and tasted the famous Starbucks coffee marked the beginning of me as a professional front-end developer.&lt;/p&gt;
&lt;p&gt;But something wasn&apos;t right. I didn&apos;t feel as safe as I used to. Initially, I blamed it on various non-technical aspects of my new job, such as joining a new company or moving to a new country. Or maybe it was the coffee? However, soon I realized that the real issue was an industry-wide lack of a quality safety net. And by the industry, I mean the front-end industry. We are the people tasked with getting some data, presenting it to the user, responding to their input and possibly sending some data back to the back end. Yet, the most popular testing approaches closely resemble what we developed to test back-end systems, with just a hint of the front end.&lt;/p&gt;
&lt;p&gt;To help me differentiate front-end testing tools from some sort of back-end testing tools or half-baked front-end testing tools, I developed a little benchmark, and I think you may find it helpful as well. Before I reveal it to you, I&apos;d really like to highlight the fact that it relies on the assumption that the purpose of automated tests is to tell us when the behavior of the system changes and in the same time let us change the implementation, as long as the behavior stays intact, without any need of touching the tests.&lt;/p&gt;
&lt;p&gt;Here comes the font-weight benchmark for front-end testing tooling.&lt;/p&gt;
&lt;p&gt;Imagine that as part of your job you wrote the following CSS code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;font-weight: bold;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What would happen if you refactored it to use a number instead of a word?&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;font-weight: 700;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&apos;s good if your tests still pass. It proves that they are not tightly coupled to the implementation details. In the end, both &lt;code class=&quot;language-text&quot;&gt;bold&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;700&lt;/code&gt; lead to the same behavior of your app.
But if your tests fail, then it means they are tightly coupled to the implementation and will, in fact, make any refactoring harder.&lt;/p&gt;
&lt;p&gt;Finally, what would happen if you made a mistake when refactoring the code above and instead wrote this?&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;font-weight: 800;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&apos;s good if your tests fail now. It means they are actually testing what the front-end development is all about, which is rendering the right pixels in the right order and at the right time.
But if they keep passing, then it is a sign that the front end of your front end may have 0% test coverage.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The new CSS Grid will change the way you think about layouts. Here's why.]]></title><link>https://coder.earth/post/new-css-grid</link><guid isPermaLink="false">https://coder.earth/post/new-css-grid</guid><pubDate>Tue, 21 Jan 2020 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;The first CSS Grid Layout made it possible to divide the area of an element with horizontal and vertical lines. These lines dictated the size and position of its children.&lt;/p&gt;
&lt;p&gt;But this is going to change.&lt;/p&gt;
&lt;p&gt;To understand why, and most importantly, how, let&apos;s recap the way things worked in the first version of the grid.&lt;/p&gt;
&lt;p&gt;For instance, this card could be one grid:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/card1-927d4aa50ff782c764f48aeaf4a068be-8685f.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 180px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.55555555555556%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABjUlEQVQoz6VT2WoCQRDcn8oHhXyQ+BjQF98UfVFBQTxQA6K4ILq63gquGhGP4HqtWtlqY2IIkquhGaa7qamqmVHa7TZarRZqtRoKhQLC4TDcbjecTiccDse3yTmXy4VgMIh8Pg+FYL1eD+PxGMPhEP1+Hzyk0Wj8KHVdF6BisYhqtQqFxcVigf8EyVAhySnNZhPL5fKjezq9LZ/X62Dtuj6ZTIQplSkNG3D18oLp/gB1toR1PGK33eJwOGC/38u6tfe73Q6bzQaWZb0DmqYpgKPRCJVK5Qyo1+s42UOPoTDu7h9gTKfQymWkMxkEAgF4PB74fD7xiMaz5vV6kUwm4ff70e12xftcLgeqFQ/N9RrPhoGnREIkz2YzGPae3nJ4Pp8LM14Y66xR5mq1EgX0LxaLoW6T++Lh6ReXcfGxVCohFAqJj8KQDBg87S+hqiqi0eiZIa+60+mIlMFgIJ7QYHqSTqeRSqVuJvvZbFbA+BYF8PJTKJ1sNU2TZsL2k4ORSORmsh+Px+WH8VET4xWp+RWPX2o+6QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The first card&quot;
        title=&quot;&quot;
        src=&quot;/static/card1-927d4aa50ff782c764f48aeaf4a068be-8685f.png&quot;
        srcset=&quot;/static/card1-927d4aa50ff782c764f48aeaf4a068be-378f8.png 300w,
/static/card1-927d4aa50ff782c764f48aeaf4a068be-8685f.png 360w&quot;
        sizes=&quot;(max-width: 180px) 100vw, 180px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The HTML code looks simple. It&apos;s just one parent with two children:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;card&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;avatar&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://picsum.photos/id/10/200/200&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h2&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;card__text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Lorem Ipsum&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The CSS code makes the parent element a grid:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.card&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; grid&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;grid-template-columns&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; max-content 1fr&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;grid-gap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;align-items&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; center&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The grid lines are as follows:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/card1-grid-7cb89fb6ab397a0e8fa103d791af7bf3-6bb58.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 194px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 50%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABvklEQVQoz42STW/aQBCG+Zv9Qb1XvfWQc0iq3iABFNKC7dgIY2IDwYANAYdCxGfEZxqHJ2sb2rRS1Fh65d3Z0bMz72zMdV0cx6HVatG06+jFAunzM759PeU0fszJGzqcxeNxEokEmqZRr9eJOY6LK4CT6ZTRfMVwuow0WTD4j8L84T2WZWHbdlhUrCVg3ds2880zvTn0F9B9gMESxmsY7TVe/72fCN2J3MnSp9tpE3CCbiOgCMxWPiMftsD6iXd92524eP5Ix22F1UVAsfC6HYYPWz58PuLou0JvMKZkVlFVFa1Q4CKbpVqrISsK+bzEtWmhKjIXcpGfsy21qhX6twc69ETLE1Hhx09fyEoqg9kKrViiYpnYIrFcNuj3++h6ESmfxzRNrg2dSvMWb7xEkXJhLBjubw8DYNDuo9B0A/47Wl6IJE+YmT5PopdKUYUBtdN2WW2fWPyCjR95c7Bx9w9k9yr2LDRbrDlLJjGMclTh4R16Xo/74YD+nYcjfC0bBldXCrIsIUvSn/+rdUFTyeV+kL285EZ4HAKd/biD4TQaDW6EZ4aA5YVXmUyGVCr1ptLiXJJkKpUKzWYzBL4A2MTMtODL5cUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The first card&apos;s grid&quot;
        title=&quot;&quot;
        src=&quot;/static/card1-grid-7cb89fb6ab397a0e8fa103d791af7bf3-6bb58.png&quot;
        srcset=&quot;/static/card1-grid-7cb89fb6ab397a0e8fa103d791af7bf3-375e7.png 300w,
/static/card1-grid-7cb89fb6ab397a0e8fa103d791af7bf3-6bb58.png 388w&quot;
        sizes=&quot;(max-width: 194px) 100vw, 194px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Another card could be another isolated grid:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/card2-grid-aabf93b022fd19f65ab4ecf0e3c3350b-904ba.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 188px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.319148936170215%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB5klEQVQoz32SWY/aMBSF+f9/YR6ROn2iEioqFAVawiAYNQjyQJoNkjgbEIjaYUriLKe2GUSlisnVcbzly/W5bliWBdu2YZomDNOA9lPDYrHA0+QJw+EQkiTd1WAwgCzLmM/n0DQNnNXgMN7xXA9RECHyI4QkhO/5IC55V3yPs3FgGIZgCKBpmXAdFy/0BX5G4JwduJmLIAveVZiHcM8uTuVJgPkJeXIN3glIAMJgFCW2ZYKAhijq4j+VLPibVhR1XSMpEhzKA+Ighm7oNyD/A4ek4RrxcYMdPaAqStRVjaqsULI+F82pGF+f5E+CtEpBHIKVtroCDQQ+8+x1A2PyCZY9g0pWwvBOp4Nms4lWqwVlrqD3tYfHj49ot9uQv8l4+PAAPdKxNtdQFOXNw7cj+2cPp18J9vke5DXANt7ikByQ7FkWxxR5liOOYhCPiLU0SeElHnbZDj+eFVFtzroBcx8ZczEqtgiLGDWLSugSFIUY1+yolxbMvyN+s5jIE0gD6QLkafLSn+mZGU6RVZkQN55WlwKIQohiFP/MF8irXKwNB8Nbhtd7uFlvxPWxLRvqUsXo+wjdL110Pnfuiq/3uj30+30sl8tbhlcon9B1HaqqYvY8w3g8xmg0uiue1XQ6Ffv5d5zxFyDXGiovQei7AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The second card&apos;s grid&quot;
        title=&quot;&quot;
        src=&quot;/static/card2-grid-aabf93b022fd19f65ab4ecf0e3c3350b-904ba.png&quot;
        srcset=&quot;/static/card2-grid-aabf93b022fd19f65ab4ecf0e3c3350b-00daf.png 300w,
/static/card2-grid-aabf93b022fd19f65ab4ecf0e3c3350b-904ba.png 376w&quot;
        sizes=&quot;(max-width: 188px) 100vw, 188px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;And the header could be yet another grid, built in the same way:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/header-grid-764428d376a224e6b36aeb56d706530e-69494.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 208px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 47.11538461538461%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB2ElEQVQoz4WSu2+SURiHj1R6wY+L9AbSFoLUxNZCNEGJtjGpAwNJNYEI/gEkdbCzuKMWpHQk6sxaF0qAzgTCVgiXAAlhkdI/4vH7ICmmiXV4zpuc9z2/93bE4PeA7z9/MC2mWBb6EQtCi1FIzMtct/Oyb1GOmRG3eLW7S7/fp91u0+l06Ha7iOHFkFgizh1xmzkxPXo4K9QIIUaorlmFKaGS4zQ82XrMefWcer0+Eh0LDoccfouxOrvMtvs5trsrmBdMGIwGTGYTWp0Wy4oFSSuxZl1j/cE6s9Ickpx86+EjTn6dUC6XabVaY8HL4SWfv35hY9GB3/cGx5KNnWcv2Hu9Rzgc5uDDAe9CIfx+P4FAgFAwxPbLHbkLFQ7bfQ5jhxQKBZrN5qTlRDKBVs6oU0ssqY1YTavoDDrsdjsejweNRoPBYECSJPQ6PZJ+PGOrZY2PnyKcZk5pNBoTwaPk0dV81H/N6iZm5Aot5ntEIhEymcxEsNfrUalU2H+/z9tgEK/Xi/upG5fLhdPp/Ccbm5v4fD6i0Sj5fH4iqKxbEb0YDEabyuVypFIp4vE4sVjsRo6Tx6TTaUql0mQpyqGIKhe1Wm3kPDs7I5vN/helsmKxSLVavfo2fwBPD4lR3JtlFAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The header&apos;s grid&quot;
        title=&quot;&quot;
        src=&quot;/static/header-grid-764428d376a224e6b36aeb56d706530e-69494.png&quot;
        srcset=&quot;/static/header-grid-764428d376a224e6b36aeb56d706530e-4eef0.png 300w,
/static/header-grid-764428d376a224e6b36aeb56d706530e-69494.png 416w&quot;
        sizes=&quot;(max-width: 208px) 100vw, 208px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Let&apos;s put the previously discussed components together, just like that:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/grid-level1-same-data-8c77005fb017237feadf97e79d2c4e78-00cbd.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 255px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 192.156862745098%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAmCAYAAADEO7urAAAACXBIWXMAABYlAAAWJQFJUiTwAAAECUlEQVRIx5VWOU8zSRR0gESAhEREAogbCQICRIiEkBABOYfgT5CSEJIQEC8BKbsbrQQsp7nEfbNgDoO5bQzGB2AbY6C2632aWR8zs8ZSabrH3a/fUa96bBcXFyDOz8/leXl5CYfDgaOjI0scHh7KepfLpe8lbNrg7OwMHo8H/f39KCgoQGVlJSoqKnQkzquqqlBUVITW1lbZpzlEJBl8fHxER0cHbDZbRsjNzcXy8jKcTqcgzUMa7OrqQk1NDQoLC1FaWora2lqUlZWhrq5OvOS8sbERWVlZyMvLw/DwMLa3t8WgoYfd3d1iLD8/X4w0NTWhra0NnZ2daGhoQH19PVpaWpCTkyPo7e3FwsKCucH29vaMQ87OzkZPTw/sdnu6Qb64u7uTEJqbm8Wb6upqlJeXo6SkRMLmWHsWFxdLBH19fcYeapW6vb0V6nDR0NAQBgYGTDE4OIiRkRHJYVqVNYPX19fwPT/Dq8Inje7v7w3hdruFg/v7+zg9PdW5mGTQqfL4rIxl+ovH40lNkeYhCxMKBLDiusQ/t3eIht/g9Xpxc3ODh4cHHSwePXx7e8PJyYnOwTSDdD2sFv32x5/4e2ERXrV5cXERKysrEtrW1hZmZ2eFzBsbGwiow9fW1mSfoUHnmfNHIYfDYUxOToqXxgaV6wwlEo1KOMFgEE9PTxI2wVAJjnkwDdDjxH62paoNjXIBFWd1dRUTExMYHR1Nw9jYGGZmZiQVpkXhi6urK/GAySdt6LEZWCytIKYh+3y+jHMYi8WSokvjIUP1q8rFXgMIB3yIfcQRiUTw+voqYF5ZiKjKMef8j3sseegPBOG/duDBdYwLxUe7fVaaf3NzU3LKqs7NzWFpaUloQyoZFkUzaEWb7+9vfH196XN6OTU1ZU0bFuRLbWRbJeLj40Oen5+fMqZxFo4GTYmtKQabnt6ur69LiEa0GR8fx/T0tK7Wpgb5pOIQWhrogRksi8KT2AmpeSOM5qx24n5D2rAo0WhEcez9f3n4/v6uK7W5fIVeMP3X73CeOuBWnUJ6zM/PCz2oMBxTffievb63t2dNG7/fj5jyMK4qSVowBfT65eVFeEe1pmBwHgqFRBzM5Uu5z8WZ/ughWWBJG1KGFxVFgkpCgWVnaGDXELzEOKfAGtLmP/k6lwU89eDgQM+dEXZ3d5MuKMOQyX52g9YVWqdwnDhnC1IsEpXGlDY/kS+tuyyqHIBbqc3T440SUQ92dnZEZRg+QdUhVdhyrDK/E01b75eHfgR9HhVOUIntsyymMlO92Y68GrQvDFaZxTGt8k9DZg5555jKl/YpQi6yOHxH6jDsRDBcvqcasWMsacMnPeWp3JjKQw1sQeb2+PjY+tZLVQ/tw9wIqXs4/heSFhePi12cOAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The current grid, all cards with the same data&quot;
        title=&quot;&quot;
        src=&quot;/static/grid-level1-same-data-8c77005fb017237feadf97e79d2c4e78-00cbd.png&quot;
        srcset=&quot;/static/grid-level1-same-data-8c77005fb017237feadf97e79d2c4e78-e27f0.png 300w,
/static/grid-level1-same-data-8c77005fb017237feadf97e79d2c4e78-00cbd.png 510w&quot;
        sizes=&quot;(max-width: 255px) 100vw, 255px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The parent element is yet another grid, just to define the spacing among the cards and the header:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.grid&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; grid&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;grid-gap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 20px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It doesn&apos;t look bad.&lt;/p&gt;
&lt;p&gt;However, it&apos;s quite optimistic to assume that in real life all the cards will have identical content. So let&apos;s make it a bit more realistic:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/grid-level1-real-life-data-50df549f5e5730e1faa6be35f4fa89ba-cdbc2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 310px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 160.9677419354839%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAgCAYAAAASYli2AAAACXBIWXMAABYlAAAWJQFJUiTwAAADuklEQVRIx51WSy9rURRuhIjHhBERQyFhgqlEDERigv/gdyAxMTMQP+Emd2Ji6FHvt3i2Hm3RVumlaF19qva7+1vurtOeNh47+ex9ztn722utb61VFpfLhcvLS/j9ftze3n4LPHNzcwNyEBcXF7CQ7PT0FIODg+jt7UV/fz8GBgYy4DPR19eXBX7r6enB6OgovF5vhtTi8Xiws7MDi8XyI7S0tODk5AROp/OdkOybm5tobm5Ga2srGhoa0N3djc7OTnR0dMjc1dWFsrIyFBUVobi4WFBSUiKETU1NmJqaEi/FZVq4vb2N8vJy2VhdXY3Gxka0t7ejvr4edXV1qK2tFbJ8FtbU1GBiYgI2m+2d8OrqCsfHx2hra0NVVRUqKioyFuiZ4IX8plFZWYnS0lKxcHJy8oNQq3x+fo6ZmRmMj49jZGTEhOHhYROGhoYwNjaG6elpnJ2dvRNe/Fcn+PSE8MsLHh8f8fDwkEEgEMh6NuJJnXG73WJdJm20hclUCj8ZkUhEFCaZEPLB7/Nh027Hb+sC/qhkXd/YkFSyq3dra2vY39+X1Hh7e0NKXcyZ4KClR0dHQiZpwz80++/zM0LKhWQyiWg0KvPr6yteVBhisViGIHewWlZXV8XLDCHjGA6HhSAUCknc7u7uBFzf39/LmoeN4DdmyIbyKEOoTXU4HKIUXbVarZibm/sU8/PzEhKd1B8WqgdaFlWuRWNxcZnBNoIe5D5zH63UHB8qq+R+TcTxFgsjFgqoeCWRSqfzxiyVkw0kzlKZhFduD16CAdzatuCe/wWf5xLWhQUsKDAEKysrWF5exsHBAfb29iRm6+vrsmYsTSozoLkq0hIqrWej0pzj8bis2Rd5YbbKij0YDIr5zCs2TYKb9awbsPE91T88PCysMut5d3dXXKWCXwFd13WcZSETOJFIiGt0h8hd5z5zP2vfLIpSORIJq40xiVnaoLAuNeMwfqch9C6rlq99N3CeHMFhP1RuO7C4uCiBXlpaEnfY0ekaFafabMj6EsaR6ptUppIcWtl8OVeolnmJSWX2NprPzPep7sPfGoI/EUbod2wo3MdORA9MKlNh1iTdoXqzs7OCz+qZKcOzJpXD4Yi4q3ueFkevdQ/U0KFh/uZVOaFqOZ1+rwhuZkqwCRjJ8w2Tyi6XE26PFwH/NR4DXnWbSym8LLdubW1J82TQGS9ddsZUosqMY0GVvzsKqswaZk/U//zQDQ1ay8DngudYqhSyYMdmS9JJ/RWQTMcwy0IN3kSRvgruN57/B1HDZ65654EJAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The current grid, real-life data&quot;
        title=&quot;&quot;
        src=&quot;/static/grid-level1-real-life-data-50df549f5e5730e1faa6be35f4fa89ba-cdbc2.png&quot;
        srcset=&quot;/static/grid-level1-real-life-data-50df549f5e5730e1faa6be35f4fa89ba-24eaf.png 300w,
/static/grid-level1-real-life-data-50df549f5e5730e1faa6be35f4fa89ba-64e87.png 600w,
/static/grid-level1-real-life-data-50df549f5e5730e1faa6be35f4fa89ba-cdbc2.png 620w&quot;
        sizes=&quot;(max-width: 310px) 100vw, 310px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;That&apos;s the problem I wanted to show you. As we can see, the texts are not really aligned with each other:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/grid-level1-real-life-data-keyline-f2be83987c7f322f8b828bbc70bfd459-cdbc2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 310px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 160.9677419354839%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAgCAYAAAASYli2AAAACXBIWXMAABYlAAAWJQFJUiTwAAAEOElEQVRIx5VVW08qZxQlVmNE2/S0Lxpj0qdqo0lb7aM5xodzTE/Sin3tq79DTXyxz8b+hyb1xaQvRwUB71oVVAREucilXASR4TKMuPrtDcOd6PmSxXzDzKzZe62992hcLhdub28RCoUEgvDdBREMvg70TCAQAHEQbm5uoCGyq6srzM7O4sOHn/HLr79DN/MbZmZ0AjPQ6XSM6enpGtC1qakpLC4uwufzlUk1Xq8XR0dH0Gg0JbRV7V/GyMgIbDYbrq+vi4TEvr+/j+HhYfz4w/f4dvAnvHv3HhMTbzE+Pi6OE5icnERXVxfa2trQ3t7O6OjoYMKhoSGsrq5ylpwyRXh4eAittlvc+Bm++vobDA5+h7GxMQwMDKC/vx99fX1M1izC3t5eLC8v4+Liokjodrtxfn6O0dFRvHnzJT7/ol8Qd4gIKpEQtFoturu7y+jp6UFnZydHuLKyUiFUXbY7HPi4/hFLf/yJ+fkFLCzUYn5+vgFzc3NYWlrC2toa7HZ7kfCm5E48HkdaeoTHG0ckEkMsVkQ0Gi3v60HPeDwejq5cNmqE+UIBtNIZfNJKp9PsMJExIZ2E/H7sX17iL4MBbncMO7t7XEqX4r+dnR2cnp5yaTw9PaEgXkxHAi2K1Gq1MhmXDf1Q2I/JJJKJOOKJJ0hSBoqiIJ/PI5VKIZvNlgnqF3XL9vY2Z1kmJB1TKUmQ5HHnT7KGkUgY4XCYNYxEIrwvtmcFdI0qZG9vr0Kohup0OuFw2LFlPMHGph4bGxsvYnNzkyVRi7oSoThJPDwgm8viv6jMKWcyaRZchSRJDeeZTIajVDkqLovizss5FHISwoF7KHkFz8/PTTUrlKpBXURc4zIRuj1epBJRhC4PcPHP37jzuKEXjhsEyG2z2QyTyYSzszOcnJywZru7u7wnLRtcJkEVpeiilKlEQk6rx2qn6ZjL5XhPc5FeWOsyaZhICG0kEe29cDogbgzwzTRA1WFafU5Hct9isbR22SlcNppOodcbhINFF18Cpa72cU2Ej6KA83kZkWgOmWxOpJTlNCk1Au3rz2VZxv39fRNThMuUrixnEX8oCN2ea1yt75LqCqBOouxqepk0c9qsAhacWT3C3S0htAlGo5HToYlOqZHj5DYNZPUlpCO538RlpdjscUXcXGhac616mV7S4DLNNklKscs+n5+/ZAT6RFRD/Y8Gil9MKZpElEGDyw4xse12Gwxb/4o+1WN9fZ3xUj9TydCzDS5LUlqkqvD4UpSCEL7A4lPa1TNQhVr0VL9NXZZlqnyFy0aWFS4JGgIqYavebnDZ5boW3xEfIsE7xGNeWM+9QmSzeKsTBwcHPDxJdNJLbbvqUiKXSceWLos5+0mrpcv0bUgmH2B3hkQKpVYsgTQi4etBzx0fH3NdtpzY5m2L6GczF/VrQGSqhjURqnDd3LJJrwVFVv38/z0wZciZ76z+AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The current grid, real-life data, with a keyline&quot;
        title=&quot;&quot;
        src=&quot;/static/grid-level1-real-life-data-keyline-f2be83987c7f322f8b828bbc70bfd459-cdbc2.png&quot;
        srcset=&quot;/static/grid-level1-real-life-data-keyline-f2be83987c7f322f8b828bbc70bfd459-24eaf.png 300w,
/static/grid-level1-real-life-data-keyline-f2be83987c7f322f8b828bbc70bfd459-64e87.png 600w,
/static/grid-level1-real-life-data-keyline-f2be83987c7f322f8b828bbc70bfd459-cdbc2.png 620w&quot;
        sizes=&quot;(max-width: 310px) 100vw, 310px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Luckily for us, the new CSS Grid Layout provides an elegant solution to this ugly problem!&lt;/p&gt;
&lt;p&gt;We can define a single grid line that will be used to divide all the cards and the header together, on a higher level, above the individual elements:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/level2-grid-827d5f8d4f8aeda18fce40535a3ef29d-af6ab.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 299px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 173.57859531772576%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAjCAYAAACU9ioYAAAACXBIWXMAABYlAAAWJQFJUiTwAAAFk0lEQVRIx51WWW8bVRR2s9g0bUWBpklLeYAieIE2qtSHikqgpLygwnOf2h+AxJ+AN1BTpAaeqEQlQKCWKk3SpHFr11nseF9m8Yw99owd2/Fu186+fdx7x4njBpWGO/p0z9zlzLnnO+fcMcRiMSiKgoSawHxyXkdivim/AtS4ynRQXQYmxGOYC8zhqf0pLA4LLHMWvX8BVod13xjd4xf8iMfjTKkhrsQhxST0fdoHg8EA41Ej2rvb0XakDW2mNrQfJvJrbQwGowHtXe3o6OpgMB4zsj03vrmBdDaNSCQCAzWXkzic/fgsTB0mtsDQRRSbjDB1mnDIcAjGDiOMnUYcO3pMn2+AztG+/6t+hMQQZEnWFQbFIC5+dhEX+i6wBaa3TLh0+RIGBgZw7do19A/048rnV3D1y6t4/fhxtqatjVjf0c7k85+cx/3h+wiLYaIwpoKP8Oh9r7f5dXI002ETjnYdwelTp2EymdDZ2cms3GvhDt796F3c+fUOREGEIabEIKsyrn99Hef6zuHsh+/j5Ac9OHGmGyd6uvFG95s40duN7lMnCbpx8u0e9JzpZeh95xRbc/mLy7j7213dwngsjrASBpfkERRC+P3eH/j25+/w/dAPuDX0IwaHbjHcHBrU+9uDLRi8TcZ+uQmzxayTQhUKUQFKTkFtqY5qrYJYNY7c8zwqRC7VyiiTvvy8rIO8V+oVNkfl2mINIS0ETuT0OKQKRUVEcbmInVbYKmOLPK/akuUkRFkE1aUrjIrI1rNs8qcHwxgPTkNRo7A9s8HlckEQBNhsNjidToiiyNZtbm4y0CalJPhCPpYxTQuXdAuLhSJSi2nUV+pYXlzG6soq1tfWUa1Usby0jI31jX0WBpUApu3T0FSt6UNq9tr6GlbWVhGrqMhWc8SfVea3UpX4jckVJhfKRYZ8KY9avYYp/xRm52ahqnssdEkuiBERTp8Lf1r+wt8TDzA6MYqRxyMEo3g4ofcvYmzyEcZmxiBIQpMUgfhQysjs6/lyAVJRxnwxhVwph4ViFtkGmEzGso3xheICsbTAQk6KSq2ktLC8WcRB2j6Ww4qEhUoSBYVHZOwOhLAFrqAfjlk7fD4f/H4/OI5DKBRCNBrdfQ8EA0hqSchpGUE+yEpYw4dhFBZzwMYmNmolZJdT7Fip+RRSKR2aqhfRSqWCQqGAdDrNlFfLVQSigRdIIUfO1Bb0+CLIrOawsrXC3rewvfvQtrFF4m97k43vBP8cP9caNlShJ+pFJB6BlwToPdt9DJsf4pF5HGPmRy/BGCaePsbI1AhJvVArKVyCY1VXTWlwax6EtTAUTUFUizagNBDdRYQgnlThVXz7WS4sFXZZq6B6IJYTpQSL4aZCEtg5SgpNI7cDUla3juYmdXQymWTE0J6+a5rGgphebrTFcjF2BbQozC/m2aQWkaAUFbgDHgi8AI/HA57nmcKIHIEsy6zuBYNB8ALP9nBxDg6XY09xiDYtpK18wCO7JTdss7ZWloNqEIl0ErwsYMz5CJMzZlhnnsEyY2WgsrUh78W0Ywaj06Pwh/ytpPgIU4oWY7KFs8IRnGMh5Al54Ql69L4BbwNU9nN+2AU7Y7lZsfcUWNpK25UDHVkravtZLizppCzVy5ivJ5DJL7CiWi6XkclkUCqVGFZW9Aza3iaZsqVnilogV3GYbz1yvkFKJiEhmg/D6XXB6/GyfHW73XA4HLDb7SyPWUoSZTtXAK/xZL2zleXC8t7Afn6gI/siPthmbK1XgJgKk5JegDqvYUqchjPkIg4PwEecTsmh/b+BE3mM2yfg8XuaFtKL3iW7wMkcXCE3hu3k5psah3nqCSanzC/BJJ5MP4HVZ4W8w/LOD2ckFmGIxknikytUUcl/oxr7T9B1dE/rDyfNyx0o/w9UD8U/Mu4YR1J1bUsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The new CSS grid, grid vizualisation&quot;
        title=&quot;&quot;
        src=&quot;/static/level2-grid-827d5f8d4f8aeda18fce40535a3ef29d-af6ab.png&quot;
        srcset=&quot;/static/level2-grid-827d5f8d4f8aeda18fce40535a3ef29d-33562.png 300w,
/static/level2-grid-827d5f8d4f8aeda18fce40535a3ef29d-af6ab.png 598w&quot;
        sizes=&quot;(max-width: 299px) 100vw, 299px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;First, let&apos;s define one grid at the parent&apos;s level instead of defining multiple grids for each child:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.grid&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; grid&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;grid-template-columns&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; max-content 1fr&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then it&apos;s enough that we use the new &lt;code class=&quot;language-text&quot;&gt;subgrid&lt;/code&gt; option. It means that both the &lt;code class=&quot;language-text&quot;&gt;.header&lt;/code&gt; and the &lt;code class=&quot;language-text&quot;&gt;.card&lt;/code&gt; elements don&apos;t define their own grid lines, but instead, they inherit them from their parent element:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.header&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/* 1 / -1 to make it span across the whole container. */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;grid-column&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1 / -1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;grid-template-columns&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; subgrid&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.card&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;grid-column&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1 / -1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;grid-template-columns&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; subgrid&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And... that&apos;d be it!&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/comparison-ddd0eb1c53caab7502deede1c1100e32-04c70.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1024px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAACbklEQVQ4y3VUuW4iQRScmMSfwycgObJMgkBgyR+AxBE6WDIyNrD/A8mZnVtyZMQRYHPMzTUcwzHmru1qewa82m2p1DPd71XXq9czyna7xW63w/F4xOFwkLM/9vs9Pj8/5TPn9XqN/w3ubzYbKJ7noVgs4vLyErFYDNFoFFdXV4hEIiiVSuj3+5J4MBjg5eUFt7e3SCQSSKVSuLm5QTweRzKZxOvrK2azGRQqvL6+hqIouLi4kLOPcDgMTdMk4Xg8xuPjY7AXCoV+xD48PGC1WkGZLxZ4fn6SKn8VCih84+7uDvf39+h0OtIG27ZRrVbxW6jOZrPI5/PI5XLIZDJIp9Mol8twXRfKZDKBNRxiJ/yjB4Q/GEBCDt0wYJom6PBGKN4L3+m9P9rtNkaj0RehKsoyhQImE0ykonq9HhByrdvtYjAcoauq8pl79JY+v729SVskoW0acPo2dF2HZVkymaB/BEvme1sQjEScoalfigW4z7z393c4jgNlLAgZtHYd9Ho9eRqlc5Nl+AoNkaxqOjbuCPOJI2IcociRnSVYjSSkQsMwYdk9SXCORqMBVZQXKGy10BclttsdfHx8SFUtsdZsNlGr1c5Ktgws5nPweS5mbpCEJ54rZHneaonpZIzpdCqbxpmXmsRBU6zvJnCRijhTERWemmLIRswEAYmpkLGc6WGlUjlTaFvyhQ0hMZURDPxRsrCB64xhLEHf+X5qylg0ZTiA563kAg/wh09yKlnH8bAT9rjBof5gNUFTmERjKZvgnfLBMqmQhCxPE6qZzCacg3mSkLd9uVzK7/Bv8MdBw0nIPw3XGPsvMJb/hT/+ixkCogfogAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The new CSS grid&quot;
        title=&quot;&quot;
        src=&quot;/static/comparison-ddd0eb1c53caab7502deede1c1100e32-04c70.png&quot;
        srcset=&quot;/static/comparison-ddd0eb1c53caab7502deede1c1100e32-07ba5.png 300w,
/static/comparison-ddd0eb1c53caab7502deede1c1100e32-8c079.png 600w,
/static/comparison-ddd0eb1c53caab7502deede1c1100e32-04c70.png 1024w&quot;
        sizes=&quot;(max-width: 1024px) 100vw, 1024px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://codepen.io/lukaszmakuch/pen/ZEYjxWZ&quot;&gt;The complete code of this example may be found on CodePen.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Subgrids from CSS Grid Level 2 enabled us to define cross-component alignment rules that work well even for dynamic content.&lt;/p&gt;
&lt;p&gt;Just to be fair, I got to say that designers have been talking about it for ages! Maybe they called it differently, like &lt;a href=&quot;https://material.io/design/layout/spacing-methods.html#spacing&quot;&gt;keylines in Material Design&lt;/a&gt;, but anyway, it&apos;s nothing new to them!&lt;/p&gt;
&lt;p&gt;So is the new specification a spacing nirvana? Not yet. By looking at some ongoing discussions about &lt;a href=&quot;https://github.com/w3c/csswg-drafts/issues/2530&quot;&gt;possible extensions of the subgrid&lt;/a&gt; we can tell that there&apos;s still some room for improvement. But it&apos;s already a big step towards unifying the ways designers and developers think. &lt;strong&gt;Now when somebody says &quot;We need to align these components to this line.&quot; we can actually code &quot;this line&quot;.&lt;/strong&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to prevent intermittent test failures]]></title><link>https://coder.earth/post/how-to-prevent-intermittent-test-failures</link><guid isPermaLink="false">https://coder.earth/post/how-to-prevent-intermittent-test-failures</guid><pubDate>Sun, 03 Nov 2019 18:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/park-552d37c6bb7c11d9c09f347e20b3306f-20657.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.640625%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAABAADBf/EABYBAQEBAAAAAAAAAAAAAAAAAAIAA//aAAwDAQACEAMQAAABEzmIFlOsV//EABsQAAIDAAMAAAAAAAAAAAAAAAECAAMREyEx/9oACAEBAAEFAq1Q2XcWBTGPewef/8QAFhEAAwAAAAAAAAAAAAAAAAAAAAER/9oACAEDAQE/AYmQ/8QAFxEBAQEBAAAAAAAAAAAAAAAAAQACE//aAAgBAgEBPwF2hdL/xAAbEAACAgMBAAAAAAAAAAAAAAAAAREhAhASMf/aAAgBAQAGPwJdkYOWeFVv/8QAGhAAAwEAAwAAAAAAAAAAAAAAAAERUSExQf/aAAgBAQABPyFLNFpZo3ENLsyBOPlekupD/9oADAMBAAIAAwAAABDTD//EABcRAAMBAAAAAAAAAAAAAAAAAAABEUH/2gAIAQMBAT8QtTeEn//EABcRAAMBAAAAAAAAAAAAAAAAAAABEUH/2gAIAQIBAT8Qglo3p//EAB0QAQACAgIDAAAAAAAAAAAAAAEAETFBYXEhgdH/2gAIAQEAAT8QGffaXx74hK6sau/ktHYqXNaYo1BAsYFZYx08Cf/Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A park&quot;
        title=&quot;&quot;
        src=&quot;/static/park-552d37c6bb7c11d9c09f347e20b3306f-19371.jpg&quot;
        srcset=&quot;/static/park-552d37c6bb7c11d9c09f347e20b3306f-c766d.jpg 300w,
/static/park-552d37c6bb7c11d9c09f347e20b3306f-f0d1c.jpg 600w,
/static/park-552d37c6bb7c11d9c09f347e20b3306f-19371.jpg 1200w,
/static/park-552d37c6bb7c11d9c09f347e20b3306f-20657.jpg 1280w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Imagine a warm summer afternoon. You&apos;re chilling out, enjoying a glass of refreshing lemonade. All you can hear are distant chatter and birds singing.&lt;/p&gt;
&lt;p&gt;Suddenly, there&apos;s a buzzing sound! A fly passes right next to your head. Focus on that insect! Try not to lose sight of it as long as you can.&lt;/p&gt;
&lt;p&gt;What was its trajectory? Did it fly straight from point A to point B? Of course not! No insect ever does it! Observing it for as little as a couple of seconds was enough to witness it flying all over the place.&lt;/p&gt;
&lt;p&gt;Why does it do it? Is the fly having problems with flying? No, quite the opposite!&lt;/p&gt;
&lt;p&gt;In fact, it exhibits extraordinary maneuverability! And it literally uses it to fight for its life! How? Random changes in direction make the fly harder to catch, effectively deceiving predators.&lt;/p&gt;
&lt;p&gt;But what&apos;s a fly&apos;s gain is a bird&apos;s loss.&lt;/p&gt;
&lt;p&gt;Coping with unpredictability isn&apos;t a challenge that only birds face. It also affects us, the IT professionals. We&apos;ve all seen automated tests failing, just to pass correctly after nothing but a restart. Even when everything works fine on our machine, we can never know if it will work in the CI environment. Once we spot the problem, we may discover that the issue is somehow related to a statement like &quot;wait 100 ms&quot;. How do we solve it? Well, changing &quot;100 ms&quot; to &quot;200 ms&quot; may temporarily fix it, but it doesn&apos;t guarantee that it won&apos;t happen again. More importantly, it doesn&apos;t silence our inner voice telling us that this may not be the most professional thing to do. In the end, we want our test suite to tell us when something is broken. We don&apos;t want the tests to be the thing that breaks. When they fail, our reaction should be &quot;Oh no, the app broke!&quot; and not &quot;Oh no, the tests broke!&quot;.&lt;/p&gt;
&lt;p&gt;Let&apos;s say that we have an app that fetches a list of items. Before the list is ready, the user can see a spinner. It takes some time for the list to load, and we can use that time to verify if the spinner meets the requirements. Is it displayed? Is some button disabled when the list is being loaded? Are the previous results hidden?&lt;/p&gt;
&lt;p&gt;The idea of such a test is simple. However, in reality, it tends to be more than trivial to build. One thing, in particular, may pose a challenge - timing. How can we make sure that the test case has enough time to perform all the necessary assertions before the data is loaded and the screen changes? A common workaround to that problem is to delay the response from the mocked service for some number of milliseconds and hope that it will be enough. Unfortunately, we can never know what&apos;s the right delay. 100 ms? 84 ms? 1 second maybe? It depends on plenty of things we cannot control, such as the machine the tests run on and even the current load of that machine. A little slowdown of the test runner may be enough for the mocked service to respond and make the app transition to a different state before the test finishes making assertions about the loading state.&lt;/p&gt;
&lt;p&gt;A term to describe our problem was already coined over half of a century ago. It&apos;s a race condition. It happens when the correctness of a process depends on the order of events we cannot control. And similarly to betting on horse racing, relying on tests waiting an arbitrary number of milliseconds is more like gambling than a profession.&lt;/p&gt;
&lt;p&gt;Imagine how much easier our lives would be if the test and the mocked service communicated instead of competing with each other. There would be no race conditions if the test suite could just tell the mock &quot;Hey, I finished all the assertions for now and I&apos;m ready for you to give the app the data it asked for.”. We could see an increase in multiple areas spanning from the stability of individual test cases, through the performance of the whole pipeline, to our - developers - wellbeing. Just think about how comfortable would it be if no unexpected build failure would ever delay a deployment again! &lt;/p&gt;
&lt;p&gt;I got something that may give you relief. In &lt;a href=&quot;https://endpoint-imposter.js.org/&quot;&gt;Endpoint Imposter&lt;/a&gt; you can assign what&apos;s called a release key to any mocked response.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  request&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/todos&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  releaseOn&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;todos&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  response&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;a&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;b&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;c&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The mocked service won&apos;t give the app the items it asked for unless the test gives it permission to do so by issuing a request to &lt;code class=&quot;language-text&quot;&gt;http://mock/admin/release?session=sessid&amp;amp;key=todos&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;That way you will always have enough time to make all the necessary assertions about the loading state before the screen changes.&lt;/p&gt;
&lt;p&gt;It&apos;s that simple.&lt;/p&gt;
&lt;p&gt;If there&apos;s one thing I&apos;d like you to take away from this post, it&apos;s to let &lt;a href=&quot;https://endpoint-imposter.js.org/&quot;&gt;Endpoint Imposter&lt;/a&gt; make it easy for you to catch bugs.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[React hooks... Oops! Part 3 - an effect doesn't run again when its dependencies change]]></title><link>https://coder.earth/post/react-hooks-oops-part-3-an-effect-does-not-run-again-when-its-dependencies-change</link><guid isPermaLink="false">https://coder.earth/post/react-hooks-oops-part-3-an-effect-does-not-run-again-when-its-dependencies-change</guid><pubDate>Mon, 21 Oct 2019 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/cogs-b40eef1b0d0788f190c1a290e0a522b2-20657.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 65.15625%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABAAD/8QAFQEBAQAAAAAAAAAAAAAAAAAAAQL/2gAMAwEAAhADEAAAATNDsLo0z//EABkQAQADAQEAAAAAAAAAAAAAAAIAAREhA//aAAgBAQABBQLbueHbCJNHFXETs//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABURAQEAAAAAAAAAAAAAAAAAAAEQ/9oACAECAQE/ASf/xAAZEAEBAQADAAAAAAAAAAAAAAABAGERITH/2gAIAQEABj8CyS4fZNk27W//xAAbEAACAgMBAAAAAAAAAAAAAAABEQBRMUFxgf/aAAgBAQABPyHUQpcQMiwM1FhYHIEBtArjij15EyWHc//aAAwDAQACAAMAAAAQ4z//xAAWEQEBAQAAAAAAAAAAAAAAAAAAASH/2gAIAQMBAT8QrH//xAAWEQADAAAAAAAAAAAAAAAAAAABEEH/2gAIAQIBAT8QKr//xAAbEAEBAQEBAAMAAAAAAAAAAAABESEAMXHR8P/aAAgBAQABPxDahZWiqe7pwihRqg+udHQuB3Olygx3Z+nCQ4mCPwnnC5xFIvf/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Cogs&quot;
        title=&quot;&quot;
        src=&quot;/static/cogs-b40eef1b0d0788f190c1a290e0a522b2-19371.jpg&quot;
        srcset=&quot;/static/cogs-b40eef1b0d0788f190c1a290e0a522b2-c766d.jpg 300w,
/static/cogs-b40eef1b0d0788f190c1a290e0a522b2-f0d1c.jpg 600w,
/static/cogs-b40eef1b0d0788f190c1a290e0a522b2-19371.jpg 1200w,
/static/cogs-b40eef1b0d0788f190c1a290e0a522b2-20657.jpg 1280w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;In the previous post from &lt;a href=&quot;https://coder.earth/post/react-hooks-oops-part-1-introduction&quot;&gt;the React hooks... Oops! series&lt;/a&gt; we talked about a case where &lt;a href=&quot;https://coder.earth/post/react-hooks-oops-part-2-effect-runs-multiple-times-with-the-same-dependencies&quot;&gt;an effect is re-applied, even though the dependencies are still &quot;the same&quot;&lt;/a&gt;. We expected it to run again only if the dependencies changed, but it ended up running multiple times with the same values. Fortunately, it was enough to learn a little bit about how dependencies are compared, and it became clear what made React re-apply it. 🥳&lt;/p&gt;
&lt;p&gt;If you&apos;re reading this post, you might have already discovered that the array of dependencies is tricky. It seems to be pretty simple on the surface. After all, it just tells React to &quot;re-run this function when one of these values change&quot;, right? Well, that&apos;s not exactly what happens. &lt;strong&gt;The truth is that changing a value in the dependency list is not enough for React to re-run the effect!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;How come? 😰&lt;/p&gt;
&lt;p&gt;Let&apos;s have a look at a very simple example, where everything works as expected:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Just some local state:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;typed&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setTyped&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// An effect synchronized with that local state:&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;an effect of&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; typed&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;typed&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// The view:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      You typed: &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;typed&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;br&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;typed&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;onChange&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setTyped&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;target&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/proper-synchronization-9c2d27011abfcb6f4bfa52d4aea23cee.gif&quot; alt=&quot;A proper synchronization&quot;&gt;&lt;/p&gt;
&lt;p&gt;Looking at this component, it&apos;s tempting to say that the &lt;code class=&quot;language-text&quot;&gt;() =&amp;gt; console.log(&amp;quot;an effect of&amp;quot;, typed)&lt;/code&gt; fragment re-runs when &lt;code class=&quot;language-text&quot;&gt;typed&lt;/code&gt; changes. But that&apos;s a simplification.&lt;/p&gt;
&lt;p&gt;Why? 🤔&lt;/p&gt;
&lt;p&gt;Before I present you with an example that illustrates the problem, I&apos;d like to show you an alternative version that happens to work, even though there&apos;s already a bug waiting to surface.&lt;/p&gt;
&lt;p&gt;Here we still use state to control the input field, but the effect is synchronized with a value read directly from a reference to the DOM element.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Nothing changed here,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// it&apos;s still just some local state:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;typed&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setTyped&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// A ref to the input element:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; inputRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// The value read directly from the DOM node:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; inputValue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; inputRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current
    &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; inputRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value
    &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// An effect synchronized with the value&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// read from the DOM node:&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;an effect of&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; inputValue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;inputValue&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      You typed: &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;typed&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;br&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &amp;lt;input
        type=&quot;text&quot;
        &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/* The value of the input comes from the state: */&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
        value=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;typed&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/* Typing updates the state: */&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
        onChange=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;e &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setTyped&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;target&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/* We also set the ref: */&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
        ref=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;inputRef&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      /&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/proper-synchronization-9c2d27011abfcb6f4bfa52d4aea23cee.gif&quot; alt=&quot;The same result&quot;&gt;&lt;/p&gt;
&lt;p&gt;Everything &quot;works&quot;, but that&apos;s just a happy accident!&lt;/p&gt;
&lt;p&gt;What&apos;s the problem with this code?&lt;/p&gt;
&lt;p&gt;Imagine we don&apos;t want to that funny &lt;em&gt;You typed: ...&lt;/em&gt; message. It seems like we can just remove it together with the state used to hold its value, right?&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// This fragment stays the same:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; inputRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; inputValue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; inputRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; inputRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;an effect of&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; inputValue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;inputValue&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// No more local state:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;inputRef&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/the-effect-is-not-synchronized-9f046cef2340af4d84d5b87b384c1f28.gif&quot; alt=&quot;The effect is not synchronized&quot;&gt;&lt;/p&gt;
&lt;p&gt;Whoa, the effect doesn&apos;t work anymore, even though we haven&apos;t changed any code that&apos;d be directly related to it! 😲&lt;/p&gt;
&lt;p&gt;Why did it work before, but doesn&apos;t work now? &lt;strong&gt;It&apos;s because putting values in the dependency list doesn&apos;t turn them into any sort of observables.&lt;/strong&gt; React won&apos;t be notified when they get mutated. Thus even when the value changes, the effect is not re-applied. Previously it worked only because the component was re-rendered due to the local state update.&lt;/p&gt;
&lt;p&gt;To make it even more clear, let&apos;s try to bring back the &lt;em&gt;You typed: ...&lt;/em&gt; message, but this time it won&apos;t be done correctly:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// This fragment stays the same:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; inputRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; inputValue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; inputRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; inputRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;an effect of&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; inputValue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;inputValue&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/* We try to render the current value of the input: */&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      You typed: &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;inputValue&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;br&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;inputRef&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/nothing-is-synchronized-2bf1368a0ec86e2e4173cf1dec68895f.gif&quot; alt=&quot;Nothing is synchronized&quot;&gt;&lt;/p&gt;
&lt;p&gt;Nothing works. &lt;strong&gt;It&apos;s now clear that React is unaware of changes that happen outside of its lifecycle and neither the DOM nor the effect is synchronized with them.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Of course, the example shown above is rather simple. In real life, bugs like that may span over more lines. Judging from my experience, they tend to arise around refs and other mutable bags of data that make it easy to forget that if we want React to react to a change, that change must happen within React.&lt;/p&gt;
&lt;p&gt;You may find the snippets used in the writing of this post here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://codesandbox.io/s/wandering-snow-gyfsc&quot;&gt;A proper example where everything works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://codesandbox.io/s/keen-haze-tse34&quot;&gt;An incorrect example that just happens to work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://codesandbox.io/s/pedantic-ives-isjk1&quot;&gt;An illustration of why the example above is incorrect&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://codesandbox.io/s/twilight-voice-o03x0&quot;&gt;Another incorrect example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&apos;s all for today, I hope you enjoyed it! 🙂&lt;/p&gt;
&lt;p&gt;Stay tuned for the next post!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[React hooks... Oops! Part 2 - why does my effect run multiple times with the same dependencies?]]></title><link>https://coder.earth/post/react-hooks-oops-part-2-effect-runs-multiple-times-with-the-same-dependencies</link><guid isPermaLink="false">https://coder.earth/post/react-hooks-oops-part-2-effect-runs-multiple-times-with-the-same-dependencies</guid><pubDate>Sun, 06 Oct 2019 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/chairs-ceeb8beab958578e02a6ac484d89537c-20657.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 64.21874999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAMBBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAD/9oADAMBAAIQAxAAAAHm5WE6lh//xAAYEAADAQEAAAAAAAAAAAAAAAAAAQIhEf/aAAgBAQABBQLBpowrjlU5KUn/xAAYEQACAwAAAAAAAAAAAAAAAAAAAQIRMf/aAAgBAwEBPwF0tHA//8QAFxEBAAMAAAAAAAAAAAAAAAAAAAESIf/aAAgBAgEBPwGNWf/EABoQAAICAwAAAAAAAAAAAAAAAAABEDERITL/2gAIAQEABj8CxTNotCjk/8QAGxABAAICAwAAAAAAAAAAAAAAAQARITFBUWH/2gAIAQEAAT8hy28nU4GOyOB0wJJmseS+Lsh0eRe5/9oADAMBAAIAAwAAABDUz//EABgRAQEAAwAAAAAAAAAAAAAAAAEAETGh/9oACAEDAQE/ECmIo7O3/8QAFxEAAwEAAAAAAAAAAAAAAAAAAAERIf/aAAgBAgEBPxCkwSQ//8QAHRABAAICAwEBAAAAAAAAAAAAAQARITFBUYFhcf/aAAgBAQABPxAUbSw57ezeVFmQesM4EvkN+/Y6JQFZsfk3jMN9Xx1MhiStT//Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Identical chairs&quot;
        title=&quot;&quot;
        src=&quot;/static/chairs-ceeb8beab958578e02a6ac484d89537c-19371.jpg&quot;
        srcset=&quot;/static/chairs-ceeb8beab958578e02a6ac484d89537c-c766d.jpg 300w,
/static/chairs-ceeb8beab958578e02a6ac484d89537c-f0d1c.jpg 600w,
/static/chairs-ceeb8beab958578e02a6ac484d89537c-19371.jpg 1200w,
/static/chairs-ceeb8beab958578e02a6ac484d89537c-20657.jpg 1280w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://en.reactjs.org/docs/hooks-effect.html&quot;&gt;The Effect hook&lt;/a&gt; enables us to perform side effects, that is to run some imperative, effectful code. For example, we may want to fire a HTTP request after the component appears on the screen.&lt;/p&gt;
&lt;p&gt;As we can see in the React documentation, the way we use the effect hook looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; deps&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;fn&lt;/code&gt; is the effectful function, and &lt;code class=&quot;language-text&quot;&gt;deps&lt;/code&gt; is an array of values it depends on. Every time the component renders, React checks if all the values in the &lt;code class=&quot;language-text&quot;&gt;deps&lt;/code&gt; array are still the same. If any of them has changed since the last render, &lt;code class=&quot;language-text&quot;&gt;fn&lt;/code&gt; is run again.&lt;/p&gt;
&lt;p&gt;Even though it sounds pretty simple, there are some nuances to it that may lead to bugs or even crashing the browser (tab).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this post from the &lt;a href=&quot;https://coder.earth/post/react-hooks-oops-part-1-introduction&quot;&gt;React hooks... Oops!&lt;/a&gt; series, we&apos;ll focus on how the values in the &lt;code class=&quot;language-text&quot;&gt;deps&lt;/code&gt; array are compared.&lt;/strong&gt; We&apos;ll also have a look at the way how values are compared in a totally different programming language.&lt;/p&gt;
&lt;p&gt;Let&apos;s start with a simple example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Define a little state,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// just a letter and a flag telling whether it&apos;s been updated.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; letter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updated &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setLetterObj&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    letter&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    updated&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// This function updates the letter.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;setLetter&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; letter &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetterObj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; letter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updated&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// For the sake of clarity we declare&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// that the letter is what the effect depends on.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; effectDependency &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; letter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Run a dummy effect that simply logs the effectDependency.&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;effect of&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; effectDependency&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    effectDependency
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;updated &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;New&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;letter&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/* Buttons that call setLetter every time they are clicked. */&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;B&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is how it works:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/basic_example-3cfe20069003ce7ce7b9468221568f3e.gif&quot; alt=&quot;A basic example&quot;&gt;&lt;/p&gt;
&lt;p&gt;Please note that even though we click each button, and consequently alter the &lt;code class=&quot;language-text&quot;&gt;letter&lt;/code&gt; value, multiple times, the effect is re-applied only if the value actually differs from the previous one.&lt;/p&gt;
&lt;p&gt;To make it even more clear, let&apos;s add a simple counter to our example. The rest of the code remains intact:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Nothing fancy here, just a number.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;counter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setCounter&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; letter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updated &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setLetterObj&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    letter&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    updated&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;setLetter&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; letter &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetterObj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; letter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updated&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; effectDependency &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; letter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;effect of&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; effectDependency&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    effectDependency
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;updated &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;New&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;letter&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;B&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;counter&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/* Clicking this button will increment the counter by 1. */&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setCounter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;counter &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;+ 1&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can clearly see, that even thought the component is being re-rendered, the effect doesn&apos;t run unless the value it depends on changes:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/added-a-counter-06a0497b1f782e080eb2111dda84409f.gif&quot; alt=&quot;With the counter&quot;&gt;&lt;/p&gt;
&lt;p&gt;You might have been wondering what&apos;s the point of explicitly declaring that &lt;code class=&quot;language-text&quot;&gt;letter&lt;/code&gt; is the &lt;code class=&quot;language-text&quot;&gt;effectDependency&lt;/code&gt;. The reason behind it is that now we&apos;re going to derive some other value from &lt;code class=&quot;language-text&quot;&gt;letter&lt;/code&gt;, make it our new &lt;code class=&quot;language-text&quot;&gt;effectDependency&lt;/code&gt;, and see what happens.&lt;/p&gt;
&lt;p&gt;Here we turned a boring dependency like &lt;code class=&quot;language-text&quot;&gt;&amp;quot;A&amp;quot;&lt;/code&gt; into something much more fun, like &lt;code class=&quot;language-text&quot;&gt;&amp;quot;The letter A&amp;quot;&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;counter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setCounter&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; letter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updated &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setLetterObj&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    letter&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    updated&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;setLetter&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; letter &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetterObj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; letter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updated&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// This is the only line that has changed.&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// We build a new string based on the letter string&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// and it&apos;s that new string&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// that becomes the effect&apos;s dependency.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; effectDependency &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`The letter &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;letter&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;effect of&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; effectDependency&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    effectDependency
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;updated &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;New&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;letter&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;B&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;counter&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setCounter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;counter &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;+ 1&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The overall behavior hasn&apos;t changed. The effect is re-run only when the value of the dependency changes:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/simple-derived-dependency-7e0cf4e499a21cad9563a2e65f615f7c.gif&quot; alt=&quot;With a derived string dependency&quot;&gt;&lt;/p&gt;
&lt;p&gt;All right, so far all the examples exhibit the same behavior. The effect simply doesn&apos;t run again if the dependency value doesn&apos;t change.&lt;/p&gt;
&lt;p&gt;Let&apos;s take a look at one more example of a derived effect dependency and see if it follows the same rule:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;counter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setCounter&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; letter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updated &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setLetterObj&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    letter&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    updated&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;setLetter&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; letter &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetterObj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; letter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updated&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// This time instead of deriving a string, we derive an object.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; effectDependency &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; payload&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; letter &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;effect of&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; effectDependency&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    effectDependency
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;updated &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;New&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;letter&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;B&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;counter&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setCounter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;counter &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;+ 1&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here&apos;s how it behaves in the browser:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/object-payload-db0a8b1bcdfa2d2ed616dbc2967cfc05.gif&quot; alt=&quot;An object as the payload&quot;&gt;&lt;/p&gt;
&lt;p&gt;That&apos;s something new! Now the effect is re-applied on every render, even when the &quot;value&quot; of the &lt;code class=&quot;language-text&quot;&gt;payload&lt;/code&gt; stays the same.&lt;/p&gt;
&lt;p&gt;Why?&lt;/p&gt;
&lt;p&gt;The answer lies in the way how equality is understood. Depending on the data type, it&apos;s either value equality or reference equality.&lt;/p&gt;
&lt;p&gt;Primitive data types, like strings, are always compared in terms of the value their represent. They may be two different strings, living in two separate parts of the computer memory, yet, if their values are equal, they are considered equal. Here&apos;s an example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; left &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;
undefined
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; right &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;B&quot;&lt;/span&gt;
undefined
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; left &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; right
&lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; right &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;
&lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; left &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; right
&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If these were not variables but sticky notes, they would be considered equal if they had the same text written on them.&lt;/p&gt;
&lt;p&gt;However, the same rule doesn&apos;t apply to objects. Comparing objects is all about the place in the computer memory where they are stored, not about the value they represent. Let&apos;s have a look:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; left &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; payload&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
undefined
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; right &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; payload&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;B&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
undefined
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; left &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; right
&lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; right&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;
&lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; left &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; right
&lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; left &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; right
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; payload&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; left &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; right
&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Only after making both references - &lt;code class=&quot;language-text&quot;&gt;left&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;right&lt;/code&gt; - point at the very same object, they were considered equal. Imagine &lt;code class=&quot;language-text&quot;&gt;left&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;right&lt;/code&gt; are your hands. If you used both of your hands to point at sticky notes, the question would be &quot;Are both of your hands pointing at the very same note?&quot; and not &quot;Do the notes you&apos;re pointing at have the same text written on them?&quot;.&lt;/p&gt;
&lt;p&gt;So how can we trigger an effect that needs an object and not a primitive value?&lt;/p&gt;
&lt;p&gt;In this case it&apos;s quite easy to build the object inside the effect function. Instead of deriving an object from the primitive &lt;code class=&quot;language-text&quot;&gt;letter&lt;/code&gt; value outside of the effect function, we simply do it inside it. That way the dependency stays a primitive value and it&apos;s compared, well, based on it&apos;s value.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;counter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setCounter&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; letter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updated &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setLetterObj&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    letter&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    updated&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;setLetter&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; letter &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetterObj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; letter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updated&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// It&apos;s not effectDependency = { payload: letter } anymore.&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Instead, the dependency is a primitive value.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; effectDependency &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; letter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Please note how we build { payload: effectDependency }&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// inside the effect function.&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;effect of&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; payload&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; effectDependency &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;effectDependency&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;updated &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;New&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;letter&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;B&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;counter&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setCounter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;counter &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;+ 1&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This time the effect 😉 is what we expected:
&lt;img src=&quot;/working-object-dependency-e1060765ab95b606826c37ecd5683a9f.gif&quot; alt=&quot;A working object payload&quot;&gt;&lt;/p&gt;
&lt;p&gt;Alternatively, when deriving the object from a couple of primitive values is not trivial, you may want to consider using Kent C. Dodds&apos;s &lt;a href=&quot;https://github.com/kentcdodds/use-deep-compare-effect&quot;&gt;useDeepCompareEffect&lt;/a&gt; hook.&lt;/p&gt;
&lt;p&gt;It&apos;s similar to &lt;code class=&quot;language-text&quot;&gt;useEffect&lt;/code&gt;, but compares objects in terms of values, not references. That way &lt;code class=&quot;language-text&quot;&gt;effectDependency&lt;/code&gt; may be a new object with every render and the effect won&apos;t be unnecessarily re-applied. Have a look:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;counter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setCounter&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; letter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updated &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setLetterObj&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    letter&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    updated&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;setLetter&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; letter &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetterObj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; letter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updated&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// We have an object as a dependency again.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; effectDependency &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; payload&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; letter &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Like useEffect, but compares values, not references.&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;useDeepCompareEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;effect of&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; effectDependency&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;effectDependency&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;updated &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;New&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;letter&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setLetter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;B&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;counter&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setCounter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;counter &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;+ 1&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With &lt;code class=&quot;language-text&quot;&gt;useDeepCompareEffect&lt;/code&gt;, the dependency may be an object and still be compared in terms of its value:
&lt;img src=&quot;/working-object-dependency-e1060765ab95b606826c37ecd5683a9f.gif&quot; alt=&quot;A working object payload&quot;&gt;&lt;/p&gt;
&lt;p&gt;To sum it up, when declaring effect dependencies, you should remember that only primitive data types are compared in terms of values and that&apos;s why it&apos;s safer to stick to them. However, if you really need an object (or an array, which is actually an object as well), then you may consider one of these 3 solutions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;deriving it from some primitive values inside the effect function&lt;/li&gt;
&lt;li&gt;swapping &lt;code class=&quot;language-text&quot;&gt;useEffect&lt;/code&gt; for the &lt;a href=&quot;https://github.com/kentcdodds/use-deep-compare-effect&quot;&gt;useDeepCompareEffect&lt;/a&gt; hook&lt;/li&gt;
&lt;li&gt;ensuring that the reference to the dependency object changes only when its value changes&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I don&apos;t know how about you, but I feel like the meaning of equality is pretty tangled in JavaScript. Interestingly, there are some programming languages that make it a whole lot simpler. Let&apos;s try to define and compare two strings in &lt;a href=&quot;https://clojurescript.org/&quot;&gt;ClojureScript&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;clojure&quot;&gt;&lt;pre class=&quot;language-clojure&quot;&gt;&lt;code class=&quot;language-clojure&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;;; like let left = &quot;A&quot; in JS&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;;; like let right = &quot;A&quot; in JS&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;;; like left === right in JS&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;;; true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;left&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;right&lt;/code&gt; have been compared in terms of their values. Now, let&apos;s try comparing a key-value map:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;clojure&quot;&gt;&lt;pre class=&quot;language-clojure&quot;&gt;&lt;code class=&quot;language-clojure&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;;; like let left = { payload: &quot;A&quot; } in JS&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:payload&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;;; like let right = { payload: &quot;A&quot; } in JS&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:payload&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;;; like left === right in JS&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;;; true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Yay! That&apos;s like comparing objects by value, and built into the language! Let&apos;s try something even more crazy, that is comparing sets (which are unordered collections of unique elements):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;clojure&quot;&gt;&lt;pre class=&quot;language-clojure&quot;&gt;&lt;code class=&quot;language-clojure&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;;; like let left = new Set([&quot;A&quot;, &quot;B&quot;, &quot;C&quot;]) in JS&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;left&lt;/span&gt; #&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;B&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;C&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;;; like let right = new Set([&quot;C&quot;, &quot;B&quot;, &quot;A&quot;]) in JS&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;right&lt;/span&gt; #&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;C&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;B&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;;; like left === right in JS&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;;; true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Wow! 😲 It supports comparing sets by value without the need of using any extra libraries!&lt;/p&gt;
&lt;p&gt;You may find the snippets used in the writing of this post here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://codesandbox.io/s/wild-sky-2qkxk&quot;&gt;React examples on CodeSandbox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jsbin.com/vuyifacake/edit?js,console&quot;&gt;ClojureScript examples on JS Bin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Stay tuned for the next post!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[React hooks... Oops! Part 1 - Introduction]]></title><link>https://coder.earth/post/react-hooks-oops-part-1-introduction</link><guid isPermaLink="false">https://coder.earth/post/react-hooks-oops-part-1-introduction</guid><pubDate>Mon, 30 Sep 2019 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/hook-334e92e86e0938af6070a4e59e14ac48-8805c.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAIBA//EABYBAQEBAAAAAAAAAAAAAAAAAAMBAv/aAAwDAQACEAMQAAAB45UMBa5//8QAFxAAAwEAAAAAAAAAAAAAAAAAAAIQQf/aAAgBAQABBQIyLP/EABYRAQEBAAAAAAAAAAAAAAAAAAEREP/aAAgBAwEBPwEkc//EABURAQEAAAAAAAAAAAAAAAAAABBB/9oACAECAQE/Aaf/xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAY/Al//xAAaEAEAAwADAAAAAAAAAAAAAAABABARITFR/9oACAEBAAE/IcgcH2ZRAQ62v//aAAwDAQACAAMAAAAQRz//xAAXEQADAQAAAAAAAAAAAAAAAAAQETEh/9oACAEDAQE/EKVxD//EABcRAQEBAQAAAAAAAAAAAAAAABEAATH/2gAIAQIBAT8Q1Byb/8QAGBABAQEBAQAAAAAAAAAAAAAAAQARIXH/2gAIAQEAAT8QJsdE78mEbGDg2Q2//9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A hook&quot;
        title=&quot;&quot;
        src=&quot;/static/hook-334e92e86e0938af6070a4e59e14ac48-19371.jpg&quot;
        srcset=&quot;/static/hook-334e92e86e0938af6070a4e59e14ac48-c766d.jpg 300w,
/static/hook-334e92e86e0938af6070a4e59e14ac48-f0d1c.jpg 600w,
/static/hook-334e92e86e0938af6070a4e59e14ac48-19371.jpg 1200w,
/static/hook-334e92e86e0938af6070a4e59e14ac48-228e2.jpg 1800w,
/static/hook-334e92e86e0938af6070a4e59e14ac48-8805c.jpg 1920w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Familiarity makes us feel safe and confident. Yet, what&apos;s just familiar isn&apos;t exactly equal.&lt;/p&gt;
&lt;p&gt;I believe that&apos;s the very reason why it&apos;s both so tempting and dangerous to start relying on a new tool, regardless how familiar does it seem to be, without first understanding what makes it different from what we already know.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://en.reactjs.org/docs/hooks-intro.html&quot;&gt;React hooks&lt;/a&gt; are one of these new, shiny tools. Not only they are hip, but also some of them look pretty familiar and easy to use, like &lt;a href=&quot;https://en.reactjs.org/docs/hooks-state.html&quot;&gt;the useState hook&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But there&apos;s a catch to it - they are more of low-level building blocks that enable us to construct our own abstractions than something designed to directly solve everyday problems.&lt;/p&gt;
&lt;p&gt;They are intended to be &lt;a href=&quot;https://twitter.com/dan_abramov/status/1109602809798901760&quot;&gt;a way for the community to build and share cohesive fragments of logic&lt;/a&gt;, not a drop-in replacement for effectful methods in classes.&lt;/p&gt;
&lt;p&gt;Of course that doesn&apos;t mean that the built-in hooks cannot be useful on their own. If using a handful of them actually solves the problem, that&apos;s great! But if I learned anything important about hooks, it&apos;s that as soon as I get plenty of them in a single component, I should stop and think whether that&apos;s the way to go.&lt;/p&gt;
&lt;p&gt;More often than not, multiple interconnected hooks are a sign that there&apos;s an abstraction waiting to be extracted. Sometimes it may be possible to use an &lt;a href=&quot;https://github.com/rehooks/awesome-react-hooks&quot;&gt;off-the-shelf hook&lt;/a&gt;, and other times, we may need to extract one ourselves.&lt;/p&gt;
&lt;p&gt;You known what they say about mistakes. We can learn from them. And I must admit that I learned plenty of lessons that way. In this series, I&apos;m going to tell you about mistakes made when building custom hooks, so that you can avoid them.&lt;/p&gt;
&lt;p&gt;The next post from this serise: &lt;a href=&quot;https://coder.earth/post/react-hooks-oops-part-2-effect-runs-multiple-times-with-the-same-dependencies&quot;&gt;React hooks... Oops! Part 2 - why does my effect run multiple times with the same dependencies?&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What a decent API mocking tool looks like to me]]></title><link>https://coder.earth/post/decent-api-mocking-tool</link><guid isPermaLink="false">https://coder.earth/post/decent-api-mocking-tool</guid><pubDate>Sun, 29 Sep 2019 15:37:20 GMT</pubDate><content:encoded>&lt;p&gt;When I worked as a back-end developer, my tasks often included integrating our systems with third-party services. All I needed to do was to communicate with some other server over HTTP(S) and consume the responses. &lt;/p&gt;
&lt;p&gt;Now, when my day to day job is being a front-end developer, I often need to fetch and update data on the back-end. All I need to do is to communicate with the server over HTTP(S) and consume the responses. &lt;/p&gt;
&lt;p&gt;As you can see, when it comes to consuming APIs, the back end and front end world are pretty similar. It&apos;s all about sending requests and receiving responses. But it doesn&apos;t mean it&apos;s not challenging.&lt;/p&gt;
&lt;p&gt;Setting our app to communicate with the real API may be a good way to start, but things get tricky pretty fast. We may soon want to handle not only the happy path but also all the loading and various error states. Because we cannot control the external service, even a manual QA tester may struggle a lot or be unable to reproduce some of these cases. Having reliable, reproducible automated tests is simply impossible.&lt;/p&gt;
&lt;p&gt;The will of building robust solutions made me look for a tool that would allow me to create test doubles of APIs. That way I could not only test all the cases that are usually hard to reproduce, but also automate that process.&lt;/p&gt;
&lt;p&gt;So, what makes a decent mocking tool?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;One of the aspects I was looking for was the scalability of mocks.&lt;/strong&gt; I didn&apos;t want the shortcomings of a mocking utility to ever force me to switch to a totally different tool in the middle of the development process.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Another thing I care about is actually running the code I write.&lt;/strong&gt; The API specification may be thought as of a contract and assume that it&apos;s what the third party is going to deliver. That&apos;s why it&apos;s relatively safe to mock the API and test our code against that mocked API. However, mocking any sort of a higher-order API client is rather risky. We may ensure that our app communicates with that mocked client properly, but in the end, it&apos;s nothing but yet another piece of code we wrote. There&apos;s still no way to tell whether it sends the right requests and correctly reacts to the responses it gets.&lt;/p&gt;
&lt;p&gt;Then, only the most trivial applications just read data and never update it. Even our beloved To-Do app alters the current list of items. The same request sent twice may produce two different responses and it may depend on a request issued in the meantime. &lt;strong&gt;It&apos;s a clear sign that a good mocking utility should enable us to mimic stateful behavior.&lt;/strong&gt;
Some test scenarios, especially those involving many components, may fire multiple HTTP requests. If that&apos;s how the app works when the users interact with it, then it&apos;s totally fine. Modifying the system under the test to fire fewer requests by swapping some internal components for test doubles makes it drift away from what the users actually use, what decreases the real-world test coverage and increases the risk of making wrong assumptions about how things actually work. On the other hand, mocking many endpoints for every test may be tedious. The good thing is that it doesn&apos;t have to. Similarly to how we can reuse the implementation of a button, we should also be able to write a mock once and then reuse it in multiple test cases. That way the coverage is high, test-related changes to the app are kept low, and the mocking process is not painful.&lt;/p&gt;
&lt;p&gt;It&apos;s better to have slow tests instead of no tests, no doubt about that, but it&apos;s even better to have fast tests. And that becomes a challenge when asynchronous communication is involved. Some responses may need to be delayed to let the test code make assertions about how does the app behave while loading data. It&apos;s then important that they don&apos;t slow down all the other tests. &lt;strong&gt;To achieve good performance, we should be able to run both the test code and the mock code in parallel.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;And last but not least, &lt;strong&gt;I wanted a platform-agnostic tool.&lt;/strong&gt; I don&apos;t want to have to learn a new mocking tool just to test an app written in a different language.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I didn&apos;t find a tool matching these criteria. So I built one. And today I&apos;d like to share it with you.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It&apos;s called &lt;a href=&quot;https://endpoint-imposter.js.org/&quot;&gt;Endpoint Imposter&lt;/a&gt; and it&apos;s a Node.js app.&lt;/p&gt;
&lt;p&gt;You define your mocks in a JavaScript file.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    request&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/todos&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    response&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;a&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;b&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;c&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, assuming you have &lt;a href=&quot;https://www.npmjs.com/&quot;&gt;npm&lt;/a&gt; installed, you run one command in your terminal.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;npx endpoint-imposter --port 3000 --mocks ~/my-mocks.js&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And now you have a mocked server your system under the test can communicate with!&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ curl http://localhost:3000/sessionId/todos     
[&amp;quot;a&amp;quot;,&amp;quot;b&amp;quot;,&amp;quot;c&amp;quot;]%&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At first glance, it doesn&apos;t look much different from other popular solutions. &lt;strong&gt;But as soon as your tests grow, you&apos;ll notice that it scales pretty well.&lt;/strong&gt; You can use it to mock your whole back end, including requests modifying data. All that without the need of writing a single function to handle the state. And because mocks are nothing but a JavaScript module, you can reuse them like any other module. Are you like me, that is a bit impatient when waiting for the tests to finish, but still willing to build robust apps? Then you may want to check out Endpoint Imposter&apos;s parallel sessions and the manual response release mechanism.&lt;/p&gt;
&lt;p&gt;You can find more information in &lt;a href=&quot;https://endpoint-imposter.js.org/doc.html&quot;&gt;the documentation of Endpoint Imposter&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What do they mean by memoized callbacks and what does useCallback actually do?]]></title><link>https://coder.earth/post/usecallback</link><guid isPermaLink="false">https://coder.earth/post/usecallback</guid><pubDate>Sat, 03 Aug 2019 10:30:20 GMT</pubDate><content:encoded>&lt;p&gt;When I first read that &lt;a href=&quot;https://reactjs.org/docs/hooks-reference.html#usecallback&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;useCallback&lt;/code&gt;&lt;/a&gt; returns a &quot;memoized callback&quot; I thought I knew what it meant. &lt;/p&gt;
&lt;p&gt;I used both callback functions and memoized functions before so I was like &quot;Ah, okay, it&apos;s just memoization.&quot;.&lt;/p&gt;
&lt;p&gt;Well, it turns out that seeing the word &quot;memoization&quot; and immediately assuming that it means what it usually does was a mistake.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Much to my surprise, &lt;code class=&quot;language-text&quot;&gt;useCallback&lt;/code&gt; does NOT return a memoized function.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;According to Wikipedia, &lt;a href=&quot;https://en.wikipedia.org/wiki/Memoization&quot;&gt;memoization&lt;/a&gt; is about limiting the number of expensive function calls by using some sort of a cache.

  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 685px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75.76642335766424%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABYlAAAWJQFJUiTwAAADA0lEQVQ4y52SSW/TQBTHA735I/BR2kOFk25wgQsSXwEhARGfAXpBKhfaCmglOCBV7QkkpAoEEotI1SUtWRrHdRY7XsZ77CZ2Ys/j2W1DEcuBkf4e/+f5/Z5n3mQyOB5/eDW2UgRm6+kO8/DRA2bxySLz4uVL5vnzZ8zCwgKztrbGbG5uMhsbG8z8/DyzvLzMrK6uMisrK8zS0lIaI4SMZc5G4f2nm9zWprhVKxwSlXCiKHKCIHCtVovTNI1rNptcvV7nGo0GZxgGJ2G8VqulXpKkarVa0dbX12+MgO/ffbxvEA1qwhEITRGa7Q60RBlUYgLRbVA1A2RVBwVnYtigEStdS+KSrIFhufD6zdt7I+Dnr9/yfj8Cw3QHHYXEmBjjx7Ht+Cgvtl1/JCvxzjlve2E/iODL18KdEfDg4CDvui4oihLhFqksy5D4ZFBK/6rT+CCZkXF3BNzf3887CEBQ1OnIFM8QbNuGJOdfwCiKRsBisfgrcDiMkvXkcVL6pH6qJDmOUfRUcZxGTdOCIAwHwyiGvb1zwHK5nAJ1w4xQVCM6qLoDst4D1exBrx8miRAEiQbQD058Mvf6we9bxr7ne8EQ2h0tUjVCEQqm7abdU7CTpuWA5STeBst2gFg+FjoGxeiB4Z4AcZc/gaXS93x/CCCSfmR1Q9rtdsF2HHBQvo/vtoXbM7FRDnh+Dxx/iIrA9UJwXP9PTSnmu14ALdkdCm0jPuKbtFSq0Bon0KZk0cO6RMuHDco3ZKqoHSppCu0QjaqkTcV2JQQYQqlUPn+GpfthqIAib+OlLYHj8fiHdazOg+UKYHcbQEwez7UOhr4PjlWAY38Hesd74Drf0g5VKlx+BNzd3bqt61W8g3uuqhY9qVPwRLHi8XzNE44qXrPBeXy9iu/ohSNPaKAEHsWh6nbS0O3t7Vsj4MTExKWrV69MTk/PsFO5mctZdo7NsjMsy06jZtlsbo5ls+izic+xU1OzbC6X+stZXLt+/drk+Pj4pRQ2GHTPuBdQF/9TSW4mCPqZH6oEU6EjvbJFAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The Wikipedia definition of memoization &quot;
        title=&quot;&quot;
        src=&quot;/static/wikipedia_definition_of_memoization-e48b5db1d71c173b7442d2717b25ae68-1b435.png&quot;
        srcset=&quot;/static/wikipedia_definition_of_memoization-e48b5db1d71c173b7442d2717b25ae68-c4006.png 300w,
/static/wikipedia_definition_of_memoization-e48b5db1d71c173b7442d2717b25ae68-a37a6.png 600w,
/static/wikipedia_definition_of_memoization-e48b5db1d71c173b7442d2717b25ae68-1b435.png 1200w,
/static/wikipedia_definition_of_memoization-e48b5db1d71c173b7442d2717b25ae68-b1a02.png 1370w&quot;
        sizes=&quot;(max-width: 685px) 100vw, 685px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  &lt;/p&gt;
&lt;p&gt;For example, this is how we can use &lt;a href=&quot;https://lodash.com/docs/4.17.15#memoize&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;_.memoize&lt;/code&gt;&lt;/a&gt; from lodash to memoize a function.&lt;/p&gt;
&lt;p&gt;First, we obtain a memoized version of a potentially expensive function (here it&apos;s just the &lt;code class=&quot;language-text&quot;&gt;double&lt;/code&gt; function).&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/memoized_function_1-838793ca30727642681af525b819494d-04c70.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1024px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAABLklEQVQ4y51SS07EMAzNHWGJWHMBrjEbYAFHYMcJWLBASIgtqlpUwaoSs+hMm6ZNEz/stqD+oGUsvcSynl9sx8paYL+zyLM9ssyiKCpYWzJq2NoBRBCj7l4yVTeCNdJUI92VKEyF0mT8QAHN4vRfQaYuktaKNYLClYQ++kIt0LuHaHkDQRokiyVJgiiKGqbnkOXDekzg1wo65/hTLCd8M39v2dNkhpi06b3/Id7GhKN74PQBOOkg/jHH7j5ajpurUKqK4xhhGCIIArzF70387JGgNowrJl92EH8DnD+3ItL+bMtNZQzxnW9ZT5+Ei1fCTUC47iC+xF62NGlb/bUWa9ZlzJl8ynh95GNqPw8/s/Rq6eWqqpDnObTWA0jMGLNe8OCWl4hzoxiPZXWFh9gXmlmRRlmVxcsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A memoized function &quot;
        title=&quot;&quot;
        src=&quot;/static/memoized_function_1-838793ca30727642681af525b819494d-04c70.png&quot;
        srcset=&quot;/static/memoized_function_1-838793ca30727642681af525b819494d-07ba5.png 300w,
/static/memoized_function_1-838793ca30727642681af525b819494d-8c079.png 600w,
/static/memoized_function_1-838793ca30727642681af525b819494d-04c70.png 1024w&quot;
        sizes=&quot;(max-width: 1024px) 100vw, 1024px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The first time we call &lt;code class=&quot;language-text&quot;&gt;memoizedDouble(42)&lt;/code&gt;, it calls the original &lt;code class=&quot;language-text&quot;&gt;double&lt;/code&gt; function under the hood and returns its result, which is also stored in the cache.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/memoized_function_2-e3cc1f0a5cdaf84b64cc8404b8809ce5-04c70.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1024px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAABfklEQVQ4y51Ty07DMBD0R3JEPfIHiL8ABEKi/EWvXBDkCr3xCGkVUYFUCVolju0kfg122oa0DTRiJWvX9no8O2sTKQGaSrCMImMlimIEpWaQ0kIqDVgLb3bpdxlRFaBCknAkaYE8Fyhy6i4Q4KJ0QKYC9XhdQIlL63RzZ4arm5ujaUoyGFPWoLZmW6uB5hFiGxqt4ul0itEoquJkMgBLHuHUhNQG0ikgja286QqotXZNkTDan+ZugeFHmvUKjN3ScF0fHxtj6sTrscBBoHF0x9C7NdgPgF5gsXdjMZgscnQbQ88qjmNEUYQwDDGO36r1w4CDnLjECw1yKpz3sQU5dnv3CxBffmvJFTM3fKzNIuvhXeDsyaD/CvSHKS5fDK5C4PzZYvhlt8omfz2J0r96QVdqQX1++L6vabl5dqspzeZQSsHncyeH626WVV65LeUo+WFafhHZ9ZAFY6DzGXiagnEO5uZ86fM87wZof/u/LdJslbyL4aYUbdJ0Kvm/9g10MI86HcPvKAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A memoized function&quot;
        title=&quot;&quot;
        src=&quot;/static/memoized_function_2-e3cc1f0a5cdaf84b64cc8404b8809ce5-04c70.png&quot;
        srcset=&quot;/static/memoized_function_2-e3cc1f0a5cdaf84b64cc8404b8809ce5-07ba5.png 300w,
/static/memoized_function_2-e3cc1f0a5cdaf84b64cc8404b8809ce5-8c079.png 600w,
/static/memoized_function_2-e3cc1f0a5cdaf84b64cc8404b8809ce5-04c70.png 1024w&quot;
        sizes=&quot;(max-width: 1024px) 100vw, 1024px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The next time we call &lt;code class=&quot;language-text&quot;&gt;memoizedDouble(42)&lt;/code&gt;, the result is obtained from the cache. The original &lt;code class=&quot;language-text&quot;&gt;double&lt;/code&gt; function is not called at all.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/memoized_function_3-98a0c66d13d6d9eed31ecfe9b449bff9-04c70.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1024px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAABeElEQVQ4y51TTUvDQBDNj/QmehS8ePNvKFIF8daf4KVXDwWlKB48WGIqQe0hYmPTJLtJNrv7nE3amqTBBgceGSazb998rCUEEC4E4ihEFAlwnkGIlJBD5BLQGsb08rvNrLwgzBEEDMEiBU8ypElEF3AwItdaFaSGrwupRWmdbu6scHVzFVXLswhKZmvSMv8XZbxGqCvJpe95HiYTp/ADbwAWjUHdhFCKgDVUV0IpJQ1FLA/oBoBqm5Te6GG9P8ZXpGSVOPgADm6BoxGwOwT2hhr79N25Aa7fyxzZptCocl0XjuPAtm28um9F/PBOwzqlxAsJq0c4Nz7FTjSOH0oSU35ryYUygvGlUkVpoy/g7Bno38/Qf2K4fAGubI3eWONxpjfKtv5aiXVccVpWYqaJN3vYPLsxlNr6GNXF1D+Rfvvwp1NaI4GcfuUkS7W8ImvbInPOMQ8ChPM5mO+DhSEYY4jjGEmSdCdsK0d3yNmqsK0VzVfVWeF/7AfS949+IElXKQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A memoized function&quot;
        title=&quot;&quot;
        src=&quot;/static/memoized_function_3-98a0c66d13d6d9eed31ecfe9b449bff9-04c70.png&quot;
        srcset=&quot;/static/memoized_function_3-98a0c66d13d6d9eed31ecfe9b449bff9-07ba5.png 300w,
/static/memoized_function_3-98a0c66d13d6d9eed31ecfe9b449bff9-8c079.png 600w,
/static/memoized_function_3-98a0c66d13d6d9eed31ecfe9b449bff9-04c70.png 1024w&quot;
        sizes=&quot;(max-width: 1024px) 100vw, 1024px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;We can keep calling &lt;code class=&quot;language-text&quot;&gt;memoizedDouble(42)&lt;/code&gt;, but &lt;code class=&quot;language-text&quot;&gt;double&lt;/code&gt; will never be called again. Unless the cache is cleared, the results will be fetched from there.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/memoized_function_4-abfed885e4469e179a80f75d1fe475fb-04c70.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1024px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAABdUlEQVQ4y51Ty0rDQBTNR7oScSm4cuVvKFgUuusvuOnWRUGpiBvBElMJPsBAakjzmDTzOt5k+kjTaIIDh7ncnDlz5+Rei3MgmnMkcYQ45mAsB+cLggAXEtAaxdLLvW1ZohQUCMMU4XwBluVYZDFdwJCSuNaqFC30uohaROt0c+cKVzdXUV0ij6FkvhY1/A1MfktQV8gm9jwP06lTxqE3RBpPQG6CK0XAGqqroJSSfgpfHtDY2FKPN6IVD7f9KWJFlayIww/g6BY4GWvsj4ADwuFIY+8GuH43HNlUYVGV67pwHAe2bePVfSvzx3ca1jnhisg9aXBJ8ZnG6YM5Wzy/8cllZYQilsqwxr7GxQTo2xqD+xkGTwz9F6D3rPE423229VdLmPzym0ipYX0gT7Y8rJ/d+Sn19lG0Cwq9Lw95EGD2+QlBU1TkVMMUWW2NzBhDHEU0SSEC30cafFMb0SQlCbIs6y74mxW6hdNaYZMVdVs6V/if9QO9x49rflFxVwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A memoized function&quot;
        title=&quot;&quot;
        src=&quot;/static/memoized_function_4-abfed885e4469e179a80f75d1fe475fb-04c70.png&quot;
        srcset=&quot;/static/memoized_function_4-abfed885e4469e179a80f75d1fe475fb-07ba5.png 300w,
/static/memoized_function_4-abfed885e4469e179a80f75d1fe475fb-8c079.png 600w,
/static/memoized_function_4-abfed885e4469e179a80f75d1fe475fb-04c70.png 1024w&quot;
        sizes=&quot;(max-width: 1024px) 100vw, 1024px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;If there&apos;s no cached result for some input, the original function will be called once, and then the result will be added to the map.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/memoized_function_5-1f3cf9bd117d858812f78aec4d208563-04c70.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1024px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAABjElEQVQ4y51T3UrDMBjNW3ohPoIIis/hGAi7EN/BG1Hwal4oDkQQ3GYnU1Qo0nVt06Vt/o5purGWdj/6wUfSr8n5zjlJCOdAFHLENAKNM6TpCEJMwLkGFxLQGnno+bgpiLCAAkEwQxCmSBKGNIlMA4YZywyQsqA5ni6B6xWNiClt1bkJoIk1WXQuZzlERqFkVgGQnEEKVmJbAazLcF0Xo5Fj54F7iRntw7gJLgWMAZh+dRF5Xastt2QjoJTSHAqHsp8aS1vmozbsssBOVd3Dui9KqTkYcPMN7N8DRz2N3S6wdwscXPvYuWK4+CyayCaGOavxeAzHcTAcDvH2/mHrhw8apG2yY/LUbDiJTYYgLeC4V+zlaqmuItkyU8rOpVK2fvej0XoBOgONzitw9sxw/hiiPQCepgVDpddIbroqFf/y40lCYx6DYLSo6hUMm65PbrpQy4xZYoASZJSCel7tQMmmi8wYQxSZZ2kAfN+3YxQECCceeJrWlJBtXsfK/wu5pbVkm6e2Lv/E8D/xCxqhjniuGK3tAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A memoized function&quot;
        title=&quot;&quot;
        src=&quot;/static/memoized_function_5-1f3cf9bd117d858812f78aec4d208563-04c70.png&quot;
        srcset=&quot;/static/memoized_function_5-1f3cf9bd117d858812f78aec4d208563-07ba5.png 300w,
/static/memoized_function_5-1f3cf9bd117d858812f78aec4d208563-8c079.png 600w,
/static/memoized_function_5-1f3cf9bd117d858812f78aec4d208563-04c70.png 1024w&quot;
        sizes=&quot;(max-width: 1024px) 100vw, 1024px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;To sum it up, two functions were created the original &lt;code class=&quot;language-text&quot;&gt;double&lt;/code&gt; function and the &lt;code class=&quot;language-text&quot;&gt;memoizedDouble&lt;/code&gt; function. Calling &lt;code class=&quot;language-text&quot;&gt;memoizedDouble&lt;/code&gt; 4 times with 2 different inputs resulted in only 2 calls of the original &lt;code class=&quot;language-text&quot;&gt;double&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;This was memoization. The &lt;code class=&quot;language-text&quot;&gt;useCallback&lt;/code&gt; hook does something else. Let&apos;s see what&apos;s that.&lt;/p&gt;
&lt;p&gt;Here we have a callback &lt;code class=&quot;language-text&quot;&gt;cb&lt;/code&gt; that calls the &lt;code class=&quot;language-text&quot;&gt;double&lt;/code&gt; function. We use &lt;code class=&quot;language-text&quot;&gt;useCallback&lt;/code&gt; to get a memoized version of the &lt;code class=&quot;language-text&quot;&gt;cb&lt;/code&gt; callback. The first time the component renders, a new &lt;code class=&quot;language-text&quot;&gt;cb&lt;/code&gt; is created and the very same &lt;code class=&quot;language-text&quot;&gt;cb&lt;/code&gt; function is returned by &lt;code class=&quot;language-text&quot;&gt;useCallback&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/usecallback_1-aa6572c6cb98757914009ef9063d2204-04c70.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1024px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAABTklEQVQ4y5WTQW6DMBBFuWS3vR6X6KJST9ENIqAqSiEuBYNtbPw749QppQSakSwjx36Z+X8mEbWHOHc4ix7d5wfq6h1S9hgGg3EcaQGqtzBaQusJShlM0wQO7z2WkYyjhzaWLltYawmgA0hrBlp+RpAB0+LxGiwAcSOqqiKohjEGaZpCCHEFRdhqhvHCz8XL3rZtAHJoyngO2QSuleGcQ1mWpKv4V5l/gGv/yqXCkwkOeHrzcBtZ7WbIIfueUh1xUsDDs4dxEXhnhnVdh3IPhwLOKNQk4+MLA/Gt753AYRiCIU3TwHEbUcu9Nv7SNgsD16RK9gXfN2L+Npkf8N6Tdl3XhQwtjwmFIoNiT/I+/15OzS8g/3g8HlEUBbIsC/DoeATNl1JqHbjUkUF5nl8bmzXlM9Z3vvhsM8O480xLKUODb+m7acotc5Yjt+UwxxeH3J1cHObkwQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;useCallback &quot;
        title=&quot;&quot;
        src=&quot;/static/usecallback_1-aa6572c6cb98757914009ef9063d2204-04c70.png&quot;
        srcset=&quot;/static/usecallback_1-aa6572c6cb98757914009ef9063d2204-07ba5.png 300w,
/static/usecallback_1-aa6572c6cb98757914009ef9063d2204-8c079.png 600w,
/static/usecallback_1-aa6572c6cb98757914009ef9063d2204-04c70.png 1024w&quot;
        sizes=&quot;(max-width: 1024px) 100vw, 1024px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;When &lt;code class=&quot;language-text&quot;&gt;memoizedCb&lt;/code&gt; is called, it calls the original &lt;code class=&quot;language-text&quot;&gt;cb&lt;/code&gt; callback, which eventually calls the &lt;code class=&quot;language-text&quot;&gt;double&lt;/code&gt; function. &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/usecallback_2-a2b98829c04779f2ec2abd20993e774a-04c70.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1024px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAABi0lEQVQ4y4WUTVODMBCG+bme/FcdD3rteNfx6MlT61gpONNBECifSUj2NUkLRgp0mZ0MG/bJm90dvJ+EsN5wrN4EXvwKT+8ZtjFHFKdo6gpdB7S1AGc1GOMQYgOiFsaICGPzhCBEpcLXUYGLDlIwVEwiyQqw9pTYtA3UKHcKZoGYsfQnAedcHyJwv7pDFsdnkBpgkwpN8J/rR+m1KAp7RVIdCv8VJPgAWQROXUNKiTAIkGZHQJQQnw9mF6dtwpJ5c6ea6xoC4xLPHyXkGWb3iZaBU4Wu6lpLFYh0X27WMYRygNea4ipMkgRhGGK/DyB5i0QLvX3UwJahvzBdU+gCm6axDcnzHLIT0FOFrabKPAM1NUiPEjk5Y8XetbkamqBn0Tpnl184uZ4bMGuta1eWpVUo9Axa1VmK9juyg26axRgbVqXUpcL+xWweDgcEemR2u52FW2BZ2GR2hvTe6gMmgeM6GpDv+zbJmFFsYqa+rpvYosJ+7fQfoaoqO+B/cZqs3WxT5prjJkz5OOcXH+GZsmRtMRMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;useCallback &quot;
        title=&quot;&quot;
        src=&quot;/static/usecallback_2-a2b98829c04779f2ec2abd20993e774a-04c70.png&quot;
        srcset=&quot;/static/usecallback_2-a2b98829c04779f2ec2abd20993e774a-07ba5.png 300w,
/static/usecallback_2-a2b98829c04779f2ec2abd20993e774a-8c079.png 600w,
/static/usecallback_2-a2b98829c04779f2ec2abd20993e774a-04c70.png 1024w&quot;
        sizes=&quot;(max-width: 1024px) 100vw, 1024px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The next time the component renders, &lt;strong&gt;another &lt;code class=&quot;language-text&quot;&gt;cb&lt;/code&gt; is created&lt;/strong&gt;. However, because the dependencies passed to &lt;code class=&quot;language-text&quot;&gt;useCallback&lt;/code&gt; haven&apos;t changed, &lt;strong&gt;it&apos;s thrown away&lt;/strong&gt; and &lt;code class=&quot;language-text&quot;&gt;memoizedCb&lt;/code&gt; stays the same &lt;code class=&quot;language-text&quot;&gt;cb&lt;/code&gt; it was during the first render.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/usecallback_3-bf140f339e3a20d831810fecad5ef055-04c70.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1024px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAABgklEQVQ4y5WTwU6EMBCGeSefxKfxTTDx7tWLZhMvejDZk0cPZo0EWBPctYuwQFsK7e+0GwxLYNHZNC1l+vHP/F1vxwwWq09cv6yxjAI8vb/ijW2x+WLgVYWmAQRv0DYCUmoIUUNrDRvGGAzDU8pgU2h85C1qRQdVjVJKsO8MUkiXVJYFiqI8OjgGc0BMRLrbkSJJagz8yyv4vv8L6mCjCruE30E/TfN+vydgDaMb5OmK1NP6QDkNHCujbVus1zHSNAM0h2Z3s6UeAcfKqGurTqOm/i8S4CaOaN3OQr2pRpfkMDmErQDOHxrcJ+HfgX2FjDEqd40oiqGkQEWMs1uDi+fDAe1y/1Ey59wZkmUZ3cHG7S03Bo+JfT8wcKRV3lyz50wY5nj9DTtX1LuiKJxCpZTbr7gAp0tujbJ3045uPfzXHAHtyyRJEMcxgiBwcAekuQP1hxBiHDjsowWEYegO2bCK8zx3/e0Pm3dSYTdbM8qydBd8+LFh7yZNmTKh/zznsI0fHzaWxNC4Re8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;useCallback &quot;
        title=&quot;&quot;
        src=&quot;/static/usecallback_3-bf140f339e3a20d831810fecad5ef055-04c70.png&quot;
        srcset=&quot;/static/usecallback_3-bf140f339e3a20d831810fecad5ef055-07ba5.png 300w,
/static/usecallback_3-bf140f339e3a20d831810fecad5ef055-8c079.png 600w,
/static/usecallback_3-bf140f339e3a20d831810fecad5ef055-04c70.png 1024w&quot;
        sizes=&quot;(max-width: 1024px) 100vw, 1024px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The third time the component is rendered with the same dependencies, yet another &lt;code class=&quot;language-text&quot;&gt;cb&lt;/code&gt; is created and then thrown away. Calling the &lt;code class=&quot;language-text&quot;&gt;memoizedCb&lt;/code&gt; results in calling the same, old &lt;code class=&quot;language-text&quot;&gt;cb&lt;/code&gt;, which then calls the original &lt;code class=&quot;language-text&quot;&gt;double&lt;/code&gt; function again.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/usecallback_4-c1f5a221fc6470eeed2e95ae8b284541-04c70.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1024px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAABzUlEQVQ4y41Ty27UQBDcD+TOF/ADOcJ3ROIAHLjAJUFCQEAICQmk5JAD5ACKQpaNDVoW1l6/ZsbzLLpn48ha7F3aGs2ru6a6uj3JlgFHF2d48uUYx+kHfPz+Ft+ycyz+/IYUAtYCSlo4q2ntYMw5QlBgCyFg0ybGBCxqjx+lgzYUaDQaXSMrMrSqjU5CNCiKAk1d3gQOgUVAjFieEWDbwjmHh48e497eHh7s34dhyteAgwy7i5tBnw8eVVURoEbwFmV+AVXlKH9+RrDtdsD+pnNgVmmaIM8LwEvY7BUdSvjLl+TUIqydx1Puv9bNWjM70pW27y9rPP10ioOz55BG/b+GfSdBFeZ0c+Fw58UCR7+mePP1EMrI3Sn3L5fLJaWb4uoqIZYtlHa49azA7dcGd09AHeB3M+wDSiljQbhNrDVRr9O0wcHM411qoOuGdHXxfEiqya6+Wpuhsa4u6BHqboxJNekf8Mza1XUdGZrrQEENLlYriLJEW6yo4VUsGvep9/5fht2GL+fzOZIkwXQ6jeBdgThYcG8SGK95KFoPAm7qyACz2SwGsTHjkthVVR017gb7bWXYzZZ+r6ZpYoP3H9vUeWtRxoozBjIExvYXw8WPkEa+M14AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;useCallback &quot;
        title=&quot;&quot;
        src=&quot;/static/usecallback_4-c1f5a221fc6470eeed2e95ae8b284541-04c70.png&quot;
        srcset=&quot;/static/usecallback_4-c1f5a221fc6470eeed2e95ae8b284541-07ba5.png 300w,
/static/usecallback_4-c1f5a221fc6470eeed2e95ae8b284541-8c079.png 600w,
/static/usecallback_4-c1f5a221fc6470eeed2e95ae8b284541-04c70.png 1024w&quot;
        sizes=&quot;(max-width: 1024px) 100vw, 1024px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Unless the dependencies change, every render will create a new unused callback, and every call to the memoized callback, which is the old one, will actually call the original &lt;code class=&quot;language-text&quot;&gt;double&lt;/code&gt; function.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/usecallback_5-0aacccaf0b04a87b0fa2cf7eab59baaf-04c70.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1024px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAAB40lEQVQ4y42UTYsUMRCG5//5F/Tm0buKF8FfIAhe9OBlEZQVBVcQl0XwsOphwUVxdGec6WEZx52e6Y90J93p5DHJMmszX25BSKe68uZJVXV3ZlPLj2/HfD06JD/5QP59n2rSJT77Q1EUaA2y1DS6omkMxpxgrcSbtZZl69S1ZZIbTtOGqtbo2m1UOek8RkoVgopCkCYpWTIny7ILobWCbLA4jlFKOaqGR4+fcPfWTe7dvsPD+w+QSm0W9M72IMwmkChVYY12tD9RlWQ+/kI+/IjV8nKEiwBPNRpFzGaJc0r05BUYSXP6hqy363wKu03wgq4VVFVVINWNZf8k4+nxEc8Pdyi7z0CX2wWXCc8LUbjrNiSi5vreGXu/f/Gu+wJ6O1CLIMhlCKfTqbvuiOEwcpSKsjJc2U24+lZz7QBufALRhF3r9FYFy7IMBUmSxPVgHUg+R4KXA83rvuR9L3MH1WxKVWfddVfNC6h/S1WyKVWdtsPPPnd5ngfCuj4nKVyDF66x83iGmM9RWRaK5vvUGLNKuFj4l+PxmCiK6Pf7QXxRIOUERJYi3NfihfxaSrlecDkfXmAwGISN3jxxmqYht5l79nn2w8dtJVzM2v0RhBChwduHtQ/9b1E2FWddsZbF2zF/ARLZi2IYEwvMAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;useCallback &quot;
        title=&quot;&quot;
        src=&quot;/static/usecallback_5-0aacccaf0b04a87b0fa2cf7eab59baaf-04c70.png&quot;
        srcset=&quot;/static/usecallback_5-0aacccaf0b04a87b0fa2cf7eab59baaf-07ba5.png 300w,
/static/usecallback_5-0aacccaf0b04a87b0fa2cf7eab59baaf-8c079.png 600w,
/static/usecallback_5-0aacccaf0b04a87b0fa2cf7eab59baaf-04c70.png 1024w&quot;
        sizes=&quot;(max-width: 1024px) 100vw, 1024px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;When the dependencies finally change, the &lt;code class=&quot;language-text&quot;&gt;memoizedCb&lt;/code&gt; also changes.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/usecallback_6-f2e08074b114bc970fa00e191890a172-04c70.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1024px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAAB5UlEQVQ4y42Tz27TQBDG/WC8ASeExL1HxCMUhMQ7wAHRQ48VQq1AhUigWHBB4gKXUKRA5MSQVNRN/d9rr+0fO0sspVFiGGm8qx3Pt99+M+Msgxbv5QnfDw+Yv3+L7w5Yno1I44SqqoxDkWtqrahrqLT5rKxtWzbNqcqW7Pyc9KePVgqtK8o4IhdArSWNLEsJw8j4FUkSo4qCpmm2gjrssCAIbGJdNzw7OGR//z4PHj7i8ZOnDIcuaZpuB5QD6+ZGG1zt49gwUaXZa6LlGFUWhMEZyeUIXeX8xWn7GXbB2ojl+zOWyxCanDo4tedN4BJfDPo17AJdsFvLsrRMSyPVmwUceT94MToln5xw6b6i2vXkbQzF0iwzVCt+F3BrWDOYj3n39Tl4R3zZu0lmimhzVsXZyVCK4fs+0+mMShUkptA3XrfcduHOB7j7GT7e20P9mv4fYJ7ntiBhGJoW0sjpp4uW42nDsVcznDdcjb/RlMrGNqVy+gReBfiXrec6bNySGe2SJLEMZVLEsrwgKxRJlpOaF0h/lmYIlPHNBr8GKMHFYsFsNmMymVhwC2hWSZa124sXWybm2pO7Q0nyPM8miQnjKIqstuKyF61lWnoZdqsUQ36WBl+/bN139a/TJ3BfsbaBif0Bf8iGan7tRcMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;useCallback &quot;
        title=&quot;&quot;
        src=&quot;/static/usecallback_6-f2e08074b114bc970fa00e191890a172-04c70.png&quot;
        srcset=&quot;/static/usecallback_6-f2e08074b114bc970fa00e191890a172-07ba5.png 300w,
/static/usecallback_6-f2e08074b114bc970fa00e191890a172-8c079.png 600w,
/static/usecallback_6-f2e08074b114bc970fa00e191890a172-04c70.png 1024w&quot;
        sizes=&quot;(max-width: 1024px) 100vw, 1024px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;And similarly to how the previous &lt;code class=&quot;language-text&quot;&gt;memoizedCb&lt;/code&gt; was calling the first &lt;code class=&quot;language-text&quot;&gt;cb&lt;/code&gt;, this one also calls the first &lt;code class=&quot;language-text&quot;&gt;cb&lt;/code&gt; it got since the dependencies changed.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/usecallback_7-bd85d59569c0dc834c931abc121027b8-04c70.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1024px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAACE0lEQVQ4y42Uy04UQRSG58Hc+QIYE3euXbhyjbrwJYyJLExcKJKgZGB0IYghLtiYqINRBOaGg9IM3dNd1V3dVfVZ1WagmQt6kpNzuqrOX/+5VNcGgeWwvkX76RrB1meONj8RfeshhgKVK/IcUlmgC4XWBmN+AIq/YrHWUpVarizi6Iik16XIMgoXmMcC6TQvijJIiIQwjJyeEg+HSJkipDgDq4LWmCFBEJClacnq8cIT5ufvcu/+Ax4+WmB1ZYXG8gpFXkwC+o+q4q2xDB2TLFPOL4gGu2QqJQy+Ep80HVBK0v6IUeJyhqMNrTXdbofBIAQj0cFquW6CDYbBm9KXvTpWR9MBz9hVNpXy7AzKQKMPz1t7LDXryINXDBqL7C29QyXZ/zH0kgiXjs75ncK1dc3rn7u83XkBB8/YuTXH98UNcln8m6FvRrfbpd3ukGcpsYu5sma5vgE3NuH2F3g/d5XmnZsYfQ44ip8AlFKWDQnD0I1QgV/dPrYstw3LLc36L3fp9geOGy9dU9Q54HjK4wNaqQMzRbkaujrbyrlaFcxb4WoXx3HJMPfPxInwg5xmxEKSOD9zZ+RJQHo6cGnrC4QuABp3W7/fp9PpsL+/X4KXgM5m7hV5W/ouVeEulc43xk4CjtfRB7VarRLEi2ccRVFZW6/e92tJkpQkZjIcWd8Mf1hX0rlMpzKc1Rx7SVOm/Rz+AANdgTr/poooAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;useCallback &quot;
        title=&quot;&quot;
        src=&quot;/static/usecallback_7-bd85d59569c0dc834c931abc121027b8-04c70.png&quot;
        srcset=&quot;/static/usecallback_7-bd85d59569c0dc834c931abc121027b8-07ba5.png 300w,
/static/usecallback_7-bd85d59569c0dc834c931abc121027b8-8c079.png 600w,
/static/usecallback_7-bd85d59569c0dc834c931abc121027b8-04c70.png 1024w&quot;
        sizes=&quot;(max-width: 1024px) 100vw, 1024px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;To sum it up, 6 new callbacks were created during the 6 renders. Calling the memoized callback 4 times caused 4 calls of the original callback.&lt;/p&gt;
&lt;p&gt;So, if &lt;code class=&quot;language-text&quot;&gt;useCallback&lt;/code&gt; does neither limit the number of function calls nor functions being created, what is the value it provides?&lt;/p&gt;
&lt;p&gt;What helped me to finally wrap my head around it it was to ignore the meaning of memoization. Let&apos;s pretend this word doesn&apos;t even occur in the documentation.&lt;/p&gt;
&lt;p&gt;So far we&apos;ve focused almost solely on the &quot;memoized&quot; adjective, but we haven&apos;t talked about &quot;callbacks&quot; yet. So, what&apos;s the purpose of a callback? It&apos;s a function that we pass down to some other function and we expect it to be called once something happens, like a query finished or an error occurs. It is a way to establish communication between various pieces of code. The module that calls the callback is not consuming the result, but the code passing the callback down expects to receive a call when an event occurs.&lt;/p&gt;
&lt;p&gt;As we can see, side effects are the most important thing when it comes to callbacks. The results usually don&apos;t matter that much. What&apos;s crucial is that when one piece of code calls the callback, the other one receives the call. We don&apos;t want to lose any calls. &lt;strong&gt;That&apos;s why memoizing a callback would actually cut the communication link between modules in our application!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;What &lt;code class=&quot;language-text&quot;&gt;useCallback&lt;/code&gt; does is limit the number of identical callbacks floating around. As we can see in the picture visible above, across the first 4 renders, when the dependency was the number 42, &lt;code class=&quot;language-text&quot;&gt;memoizedCb&lt;/code&gt; stayed exactly the same &lt;code class=&quot;language-text&quot;&gt;cb&lt;/code&gt; function it was during the first render. It wasn&apos;t wrapped in anything. The results weren&apos;t returned from any cache. &lt;strong&gt;All what &lt;code class=&quot;language-text&quot;&gt;useCallback&lt;/code&gt; ensured was that &lt;code class=&quot;language-text&quot;&gt;memoizedCb&lt;/code&gt; equaled the first &lt;code class=&quot;language-text&quot;&gt;cb&lt;/code&gt; since the last time the dependencies changed.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Does it improve the performance? Not on its own. It may actually decrease it a bit, if no other code relies on referential equality of such callbacks.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The common language used by business people, designers, writers, and developers]]></title><link>https://coder.earth/post/common-language</link><guid isPermaLink="false">https://coder.earth/post/common-language</guid><pubDate>Tue, 30 Apr 2019 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/boxes_and_arrows-b7e44bba366a9c5305331b0912b83701-ef898.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIEBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAbItyQQYP//EABwQAQACAQUAAAAAAAAAAAAAAAIAAQMEERIUMf/aAAgBAQABBQLNpjkXTFQHgVUZ3Vef/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAHBAAAQQDAQAAAAAAAAAAAAAAAQACEBESIUFR/9oACAEBAAY/Asjdrbig0cgeCP/EABoQAAMAAwEAAAAAAAAAAAAAAAABESExgVH/2gAIAQEAAT8htxImBiKdI9FDqDo1Rn//2gAMAwEAAgADAAAAEFjP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFREBAQAAAAAAAAAAAAAAAAAAARD/2gAIAQIBAT8QZ//EAB0QAQACAgIDAAAAAAAAAAAAAAEAESExQYFhcZH/2gAIAQEAAT8QxhTkAo68wG6Nhwb6j9KVDtKHER90T7anwuWxtMz/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;&quot;A drawing of boxes and arrows&quot; form&quot;
        title=&quot;&quot;
        src=&quot;/static/boxes_and_arrows-b7e44bba366a9c5305331b0912b83701-19371.jpeg&quot;
        srcset=&quot;/static/boxes_and_arrows-b7e44bba366a9c5305331b0912b83701-c766d.jpeg 300w,
/static/boxes_and_arrows-b7e44bba366a9c5305331b0912b83701-f0d1c.jpeg 600w,
/static/boxes_and_arrows-b7e44bba366a9c5305331b0912b83701-19371.jpeg 1200w,
/static/boxes_and_arrows-b7e44bba366a9c5305331b0912b83701-ef898.jpeg 1500w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;When business people were explaining their ideas to me, they were often using slides with various boxes and arrows. These diagrams were high-level illustrations of how to complete various business processes and how things may go.&lt;/p&gt;
&lt;p&gt;It&apos;s easy to understand. The language of boxes and arrows is great to explain ideas.&lt;/p&gt;
&lt;p&gt;When UX people were providing me with user flows, they were using the language of boxed and arrows as well. Their work looked like a map, where each screen was an island that might be connected with other islands by bridges named after the interactions leading to the transitions.&lt;/p&gt;
&lt;p&gt;It&apos;s easy to understand. It worked for them, because it&apos;s a great way to capture how the UI changes as the user interacts with the application.&lt;/p&gt;
&lt;p&gt;When technical writers were showing me their work, it wasn&apos;t all just text. Complex processes were described using drawings of boxed and arrows.&lt;/p&gt;
&lt;p&gt;It&apos;s easy to understand. Such a documentation is clear to people with different backgrounds.&lt;/p&gt;
&lt;p&gt;When I was about to implement a new feature, I loved to grab a pen and a piece of paper and quickly sketch how the data flows and how the behavior changes.&lt;/p&gt;
&lt;p&gt;It&apos;s easy to understand. Seeing all the important steps and states is a great framework for thinking. It helps to understand what are we supposed to build.&lt;/p&gt;
&lt;p&gt;When I was delivering the requirements, the implementation was made solely of text. The desired behavior was achieved by utilising consitions checking if some values are true or not.&lt;/p&gt;
&lt;p&gt;It&apos;s not easy to understand. Especially taking into consideration the fact that all these boxes and arrows may be thought of as a visualisation of one of the fundamental concepts in computer science - a state machine.&lt;/p&gt;
&lt;p&gt;Maybe state machines are purely theoretical or not really useful in practice? By no means! They are already being used in various branches of software development, spanning from video game development to space exploration.&lt;/p&gt;
&lt;p&gt;I wish we, the web developers, could leverage the power of this common language. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Dynamic orthogonal regions in state machines]]></title><link>https://coder.earth/post/dynamic-orthogonal-regions</link><guid isPermaLink="false">https://coder.earth/post/dynamic-orthogonal-regions</guid><pubDate>Sat, 13 Apr 2019 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;Sometimes just one sub-machine is not enough.&lt;/p&gt;
&lt;p&gt;That&apos;s why orthogonal regions are so important when it comes to composing state machines. They let us say: here are my 2 sub-machines and I want both of them to be active simultaneously.&lt;/p&gt;
&lt;p&gt;For exampe, let&apos;s consider a screen with two buttons:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/buttons-df6e939e67a1d9252122e8b948a0a6c0.gif&quot; alt=&quot;Clickable buttons&quot;&gt;&lt;/p&gt;
&lt;p&gt;Each button is a graph:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_button-877d84508f755e43994bbaa3987fb8e6-efd02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 743px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 62.58411843876177%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAAChklEQVQ4y61SO28TQRC2kCivoOUPhDYFFjrFjhRweDQB/gEVoqfHgh8AoqM9ybaMjFCkpLITYkdyESAmiR+xdWefb+PXbfA7Pvvu9obZDQ5JAw0jfdqZ3dlvv5lZn5Jcv/7xiyqlIilJiSpSLBqTYrGYFIlExJpMJqVsNittbW2JOBqNSvF4XCCRSIg1k8lI+/v713zcvqWzL46/p3o5Nae3mx1Dr+ukWq2SdrtNOp0O0XWdqKpKarUaMU1T7JfLZQE8MwghxsHBQVNRlKAgzB8evQa04dkQZrOZgG3b4DgOuK4r/Pkejznm8TyPY3Nz84kgPMrnw81WG0qlko1gmqYxvMQwmXmex/Ctf8HlgnZ3dx8LwkKhEOYvUkqd8XjsTafTC1VICHNjjF3ElUoFsAWAreD5YnN7e/ucMJfLhTVVBVydVqvlWZYFo9EIkBy4j70S8dwMw+C5wm82mx72VBDu7Oz8KbneG0DdpM4MX7NQ4WQyERdwcrC4uAg4ceh2u/wSbGxsQK/XE+dcHZbq8Ucw95wQJxQeDgZwNho69tTynKkFM2siFHJi7Cv0+31RLlfcaDS4MkGIE/bwvlCYTqfPCYvF4quu7UDVPLWNnz123DKZftpl2MMrQ7nslwp51iKEGVWNea7jXulhvlh6Ey/X4W3mK0R/lCCcysKHvUP4m/VnLhjDMZDhGXSnNvxW+FQQYu0vGycnExxMW9NUSgyDnuLI8VML4CQpTpXiZ6dVrUILqknfJ/fo88gn+kxJmO+SGXOADf68vv5QEPr9/psrKyt3lpaW5EAgIAeCQTl4CWIPMfeXl4Pyo9Bdee3+qrz2YBX9e3IoFLp9a2Hhhu9/G1bu+wUhnewGY4l6IgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A button&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_button-877d84508f755e43994bbaa3987fb8e6-2b5c8.png&quot;
        srcset=&quot;/static/editor_button-877d84508f755e43994bbaa3987fb8e6-b9857.png 300w,
/static/editor_button-877d84508f755e43994bbaa3987fb8e6-802a5.png 600w,
/static/editor_button-877d84508f755e43994bbaa3987fb8e6-2b5c8.png 1200w,
/static/editor_button-877d84508f755e43994bbaa3987fb8e6-efd02.png 1486w&quot;
        sizes=&quot;(max-width: 743px) 100vw, 743px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The code associated with the nodes of this graph simply displays a button with the proper text and makes it follow the &lt;code class=&quot;language-text&quot;&gt;toggled&lt;/code&gt; arrow:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;makeButton&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;dispatch&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeHandler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;TOGGLED&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;toggled&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  &lt;span class=&quot;token constant&quot;&gt;RENDER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;toNode&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;button&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Please note that the `toNode` function makes&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// this action target this specific subtree.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Otherwise, clicking a button&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// could toggle more than just one button.&lt;/span&gt;
    on&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;click&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toNode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;TOGGLED&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Button_On &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeButton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;On&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Button_Off &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeButton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Off&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Button &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; defaultHandler&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The buttons then become orthogonal regions:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/static_state_machine-bc22c99bbc7bc3c7d2911366cabdb09d-30b8c.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 30px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 46.26666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAJABQDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAdsgLj//xAAWEAEBAQAAAAAAAAAAAAAAAAABEAD/2gAIAQEAAQUCjTf/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAWEAADAAAAAAAAAAAAAAAAAAAQICH/2gAIAQEABj8CET//xAAbEAEAAgIDAAAAAAAAAAAAAAABADERIRBx8P/aAAgBAQABPyEwhl73PXEjtG+KT//aAAwDAQACAAMAAAAQwM//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAdEAACAgEFAAAAAAAAAAAAAAABEQAhEDFxgZGx/9oACAEBAAE/EHMrI5IEiyW6aVF8hHc198e8/9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Static orthogonal regions&quot;
        title=&quot;&quot;
        src=&quot;/static/static_state_machine-bc22c99bbc7bc3c7d2911366cabdb09d-30b8c.jpeg&quot;
        srcset=&quot;/static/static_state_machine-bc22c99bbc7bc3c7d2911366cabdb09d-2ff46.jpeg 300w,
/static/static_state_machine-bc22c99bbc7bc3c7d2911366cabdb09d-c21fe.jpeg 600w,
/static/static_state_machine-bc22c99bbc7bc3c7d2911366cabdb09d-30b8c.jpeg 750w&quot;
        sizes=&quot;(max-width: 30px) 100vw, 30px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;It means both nodes are active and equaly important.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_static-a245df66af661705dc94a8b82ddf2a57-efd02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 743px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 62.58411843876177%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAACdklEQVQ4y62SS48SQRDHiYnHOXj1C6xfQGJGFg3K+ris+g28mHj3LtEPoF69SQIEgzEcuCwQWDYhUR7DmwUGmGHYWZhZWRZ5zbOtLlyjiY+Llfyme6qr/11d1Q5/PHrxfYpnEoEE4w/6mVAwxIRCISYQCOAYj+8x2WyWSSaT+B8MBplwOIxEIhEcM5kMUywWLzioFfazTw8LiVOO54SRPB4IoiD1ej1pNBpJ4/FYEgRB4nle6vf7kqIo6G+1WgisDSRJGpTLZdnv97tRsFapviBgs8WMaJqG6LpODMMgpmni/NxH/89959A4SiwWe4iC1VrNJx+PSLPZ1AGr2+1asMmCYMu2bQvO+hcmTQiu/QAF6/W6j2agnqjGfD631+v1j9MtyyKr1YosFgsE1jFDOIgsl0vqsyE7mwqmUqmNIMcVfV2eJ1BUQ5ZlmwbOZjMUmE6nhOM4UqlUCNQJEUUR/RBPcrmcDfVFQWja9ytXqz5xOCRHsmysNQ0Fl5AVzZAKl0olupHk83kEGoGZFgoFFIRm/SrYard9Gi2EaRow4CI1et0/GQ2CAlPgu9mTTqc3go1G4/lEM0hXOdEHJxPr8Fix+uoXC+pqmRtVbM7P/K4pILipYa3RfBluieTVQY4ES03iS2TJ288V8jc7000ifV2QwWxBJmsdfen9/UcoCMV9djQcLqExo36vpzbqdQQeNdLpdNR2u63Cc1JFoae2xVP1zd4n9Ungg/r4XUR5Hc8oZ5PJ5GM0eg8FnU7nZY/Hc83lcrHb29usC7gOc7fbjVAfZTN3szdvuNn73lvs7p0ddvfuDsxvs16v9+qVra1Ljv9tcHPHNwPW8C9wDdR4AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Orthogonal regions regions&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_static-a245df66af661705dc94a8b82ddf2a57-2b5c8.png&quot;
        srcset=&quot;/static/editor_static-a245df66af661705dc94a8b82ddf2a57-b9857.png 300w,
/static/editor_static-a245df66af661705dc94a8b82ddf2a57-802a5.png 600w,
/static/editor_static-a245df66af661705dc94a8b82ddf2a57-2b5c8.png 1200w,
/static/editor_static-a245df66af661705dc94a8b82ddf2a57-efd02.png 1486w&quot;
        sizes=&quot;(max-width: 743px) 100vw, 743px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The code associated with this dynamic composite may consume the results produced by its children. Here we are placing what they rendered in a &lt;code class=&quot;language-text&quot;&gt;div&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; main &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  handler&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeHandler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;RENDER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;alterResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;res &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;div&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Lights&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Temperature&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Usually you want this part to be automatically generated&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// with rosmaro-tools.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Here it&apos;s been left to highlight the issue&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// with a static list of orthogonal regions.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;bindings&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;opts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&apos;main&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; main&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&apos;main:Lights&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Button&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&apos;main:Lights:On&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Button_On&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;opts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&apos;main:Lights:Off&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Button_Off&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;opts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&apos;main:Temperature&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Button&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&apos;main:Temperature:On&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Button_On&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;opts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&apos;main:Temperature:Off&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Button_Off&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;opts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This technique is very helpful in avoiding state explosion.&lt;/p&gt;
&lt;p&gt;But it&apos;s limited. It&apos;s static. We need to declare in the graph that there are exactly two orthogonal regions: &lt;code class=&quot;language-text&quot;&gt;Lights&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Temperature&lt;/code&gt;. This cannot be changed while the machine is running. Imagine a multiplayer game suitable only for just 2 people, or even worse, a ToDo app that always shows exactly 2 items. It wouldn&apos;t be helpful at all!&lt;/p&gt;
&lt;p&gt;To overcome this limitation when using a state machine library that&apos;s not flexible enough, developers often create many completely separated state machines and then rely on some other machanism to wire them up to the main machine. This may do the job, but it has its cons, for example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The need of manually creating and destroying extra instances of state machines.&lt;/li&gt;
&lt;li&gt;Switching between automata-based programming and some other programming paradigm, like object oriented programming or a framework, like React.&lt;/li&gt;
&lt;li&gt;No more tools to easily share and update the external state of the parent node.&lt;/li&gt;
&lt;li&gt;Working with a dynamic list of orthogonal regions becomes a lot harder that working with a static list of orthogonal regions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Good for us, an elegant solution has already been described in the famous paper on statecharts by Prof. David Harel. It&apos;s all about dynamically repeating a single orthogonal region based on a value read from the external state:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/dynamic_orthogonal_regions-9347d702811a39e8f98f3f9983335cff-c0abc.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 18px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 94.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAATABQDASIAAhEBAxEB/8QAGQABAAIDAAAAAAAAAAAAAAAAAAEDAgQF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAB7c1YliBNQbAP/8QAHBAAAgICAwAAAAAAAAAAAAAAAQIAAxETFCEi/9oACAEBAAEFAh3MRWyCxWbDEHl6a7DxaYiKg//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQMBAT8BH//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EAB4QAAEEAQUAAAAAAAAAAAAAAAABAhARMSEyQoGR/9oACAEBAAY/AsmYrTs4+xb22bEKalIf/8QAHBABAAMAAgMAAAAAAAAAAAAAAQARIRBRcbHx/9oACAEBAAE/IbC8QsZeOL3Efari89IwgBGT6zPA8T//2gAMAwEAAgADAAAAEBMAAP/EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQMBAT8QH//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8QH//EAB8QAQACAgICAwAAAAAAAAAAAAEAESExUWFx8IGx4f/aAAgBAQABPxANbhLnHI/soLW1LdQ8MUva+sk7fbxMAIYsbGAxairg+JRr2O5W/ctOXc//2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Dynamic orthogonal regions&quot;
        title=&quot;&quot;
        src=&quot;/static/dynamic_orthogonal_regions-9347d702811a39e8f98f3f9983335cff-c0abc.jpeg&quot;
        srcset=&quot;/static/dynamic_orthogonal_regions-9347d702811a39e8f98f3f9983335cff-09a55.jpeg 300w,
/static/dynamic_orthogonal_regions-9347d702811a39e8f98f3f9983335cff-c0abc.jpeg 450w&quot;
        sizes=&quot;(max-width: 18px) 100vw, 18px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Let&apos;s see how this feature is implemented in Rosmaro.&lt;/p&gt;
&lt;p&gt;Instead of manually drawing a fixed number of orthogonal regions, we create a dynamic composite and select the node we want to repeat:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_dynamic-c05743b80553387115c827a666722a77-a1c59.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 616px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 70.61688311688312%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABYlAAAWJQFJUiTwAAACYElEQVQ4y62SzYtSURjGZ+Cs+g9qVdtWbVu1CRRaBC2izfwBrQJxKY2WBH0RilRMg5lIkIQxNRdFjo00WGPMcNVr3vFj9KozXTXN0eu31/t2zkUdBWdR9Fwezie/+5zzniV4k1iaCMj3X+Rxf7iY3sZ4a/d9gM9kcCGfx6lUSnWhWMSiKOJ0Oo15nsfJZBLnyXqpVFLXI5FIIBQKBZxO56Up0P3Orek36iB1qzCQZaAaDofQ6XRgMBjAaDSCXq+njtvtNvT7fXWOjiVJgkqlAi6X6/oUuPFxQ1Or1xVRLMuVcnlIEsm1Wo2SZSpFUdT+Ag/HrYIxPgF6PB7tYbEIXJwDcgwlkUhALpdT09FkNC2BLvJE4PV6T4AMw2ir1SqQe4E6SUo3UNGjUag8voZFQDpN13w+3zyQXDiEw2GIxWIKOS40m82pu93uFDirU4FkoM1msxDjOGhKktIhgDa5cNpSGE35Vwl9zKa21moD9WTDTAy1orOg0dinAr/5fZrtjKA82tqRN+NJee3rnvwsuCPbwxG50enKMK3yfLXJjyYvYb4o34Ofr/G/fsPbCA9c9Rhw7gg+pfLA7B9Ai1R5VsfkoXw5LEOq0Zqb9/v9N6bAtVfrl3OZ9G52n2ePBIH9SSzmBTaXSrKxaJSNEse5GBvns6w7+IO99fw1+8DDsGKxwKYzB6wgCHsOh+OKCntqsdLmDPFZ4gv/6HOUYTabl1WoXq9ftlqtyGg0IpvNhmjfYrEgk8mEDAYDuru6iu7fM6GHT2xoRf8Ynb+5gq7evoPWX75AFrLXbrcjnU6nwv4AqNTsZci7nfMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Dynamic orthogonal regions&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_dynamic-c05743b80553387115c827a666722a77-962c2.png&quot;
        srcset=&quot;/static/editor_dynamic-c05743b80553387115c827a666722a77-5f3db.png 300w,
/static/editor_dynamic-c05743b80553387115c827a666722a77-8d6c9.png 600w,
/static/editor_dynamic-c05743b80553387115c827a666722a77-962c2.png 1200w,
/static/editor_dynamic-c05743b80553387115c827a666722a77-a1c59.png 1232w&quot;
        sizes=&quot;(max-width: 616px) 100vw, 616px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Then, we define a function of the context that returns a dynamic list of children:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; main &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// This function returns the list of orthogonal regions.&lt;/span&gt;
  nodes&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;switches&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  handler&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeHandler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;RENDER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;alterResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;res &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// Instead of manually picking `Lights` and `Temperature`,&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// we just render all the results.&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;div&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// For the purpose of this presentation,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// we put two values in the context.&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// In real life applications,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// the context may be populated as a result of user interaction.&lt;/span&gt;
  lens&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;initialValueLens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;switches&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;Lights&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;Temperature&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;bindings&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;opts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&apos;main&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; main&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// &apos;main:child&apos; is the node that is going to be repeated.&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&apos;main:child&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Button&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&apos;main:child:On&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Button_On&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;opts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&apos;main:child:Off&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Button_Off&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;opts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dynamic composites have many benefits when compared to statically defined orthogonal regions, for instance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The framework creates and scraps sub-machines for us in the correct moment.&lt;/li&gt;
&lt;li&gt;There&apos;s no need to switch between different mental models.&lt;/li&gt;
&lt;li&gt;The external state may be consumed and altered in the same way like when the list is static.&lt;/li&gt;
&lt;li&gt;We don&apos;t need to build any custom plumbing to communicate between machines. We still have just one statechart and all the rules that apply to following arrows and working with the context stay intact.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The difference is huge. If it were a template language, a static list of orthogonal regions could be compared to a static HTML file:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Carrot&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Pepper&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;While a dynamic one looks more like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;veggies&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Thank you for reading this brief introduction to dynamic composites! It was my pleasure to share this with you, because I do really find this technique amazing! When combined with other powerful tools, like &lt;a href=&quot;https://coder.earth/post/lenses&quot;&gt;lenses&lt;/a&gt; and &lt;a href=&quot;https://coder.earth/post/what-did-we-lose-when-we-moded-to-redux&quot;&gt;a  dispatch mechanism based on state machines&lt;/a&gt;, it makes things like building &lt;a href=&quot;https://github.com/lukaszmakuch/bool-less-todo&quot;&gt;a ToDo app without a single boolean value or even a variable&lt;/a&gt; totally doable!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What did we lose when we moved to Redux?]]></title><link>https://coder.earth/post/what-did-we-lose-when-we-moded-to-redux</link><guid isPermaLink="false">https://coder.earth/post/what-did-we-lose-when-we-moded-to-redux</guid><pubDate>Mon, 08 Apr 2019 13:37:20 GMT</pubDate><content:encoded>&lt;p&gt;In simple procedural programming we used IFs to choose between code blocks operating on data structures.&lt;/p&gt;
&lt;p&gt;That&apos;s how a data structure could look:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; shape &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;circle&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  r&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And this could be a procedure operating on it:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeBigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;shape&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;circle&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;r &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rectangle&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;b &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Such a little piece of code was so straightforward that it was possible to understand it even without knowing JavaScript. That was a big plus!&lt;/p&gt;
&lt;p&gt;However, experience showed that IFs like the one visible within the body of the &lt;code class=&quot;language-text&quot;&gt;makeBigger&lt;/code&gt; procedure were repeated multiple times in other areas of the codebase. For instance, in a procedure meant to draw a shape:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;shape&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;circle&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// The logic responsible for drawing a circle.&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rectangle&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// The logic responsible for drawing a rectangle.&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is where object oriented programming came to the rescue. It provided a dispatch mechanism that associated procedures with data structures.&lt;/p&gt;
&lt;p&gt;For instance, there could be classes representing circles and rectangles:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Rectangle&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;makeBigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;b &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// The logic responsible for drawing a rectangle.&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Circle&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;r &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;makeBigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;r &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// The logic responsible for drawing a circle.&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This approach not only made the code more coherent by grouping procedures that were closely related to each other, but also saved us from constantly examining the type of structures we were working with. &lt;strong&gt;It meant no more &lt;code class=&quot;language-text&quot;&gt;if (type === &amp;#39;cicle&amp;#39;)&lt;/code&gt; nor &lt;code class=&quot;language-text&quot;&gt;if (type === &amp;#39;rectangle&amp;#39;)&lt;/code&gt;&lt;/strong&gt;. We simply put the code related to circles into the &lt;code class=&quot;language-text&quot;&gt;Circle&lt;/code&gt; class and the one that was all about rectangles into the &lt;code class=&quot;language-text&quot;&gt;Reactangle&lt;/code&gt; class. Then it was enought to call &lt;code class=&quot;language-text&quot;&gt;someShape.draw()&lt;/code&gt; and the proper implementation of &lt;code class=&quot;language-text&quot;&gt;draw&lt;/code&gt; was selected for us based on the type of &lt;code class=&quot;language-text&quot;&gt;someShape&lt;/code&gt;. Neat!&lt;/p&gt;
&lt;p&gt;But it wasn&apos;t all roses. It was soon that we discovered how difficult it was to synchronize local state changes with other state changes and with updating the user interface.&lt;/p&gt;
&lt;p&gt;Looking for a way to solve this issue resulted in a shift to more declarative and functional programming.&lt;/p&gt;
&lt;p&gt;The popular React Redux architecture defined views in a declarative manner, so that developers didn&apos;t need to manually trigger updates of the UI when the state changed. Also, state updates were happening in a more controlled way.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Unfortunately, in terms of function dispatch, Redux didn&apos;t offer more than the procedural approach.&lt;/strong&gt; The &lt;code class=&quot;language-text&quot;&gt;subscribe&lt;/code&gt; method left us with a data structure we needed to manually inspect in order to select the proper branch of code. It was quite common to see IFs like this one repeated over and over again both in the reducers and in the &lt;code class=&quot;language-text&quot;&gt;render&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;isFriend&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hasEaten&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// What to do when it&apos;s your friend and it has already eaten.&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// What to do when it&apos;s your friend but it hasn&apos;t eaten yet.&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// What to do when you&apos;re not a friend. &lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Putting great emphasis on declarative views and immutable data structures proved to be beneficial, no doubt about that. &lt;strong&gt;Nevertheless, I believe that there are still some valuable techniques we can learn from object oriented programming when it comes to function dispatch.&lt;/strong&gt; That&apos;s especially true when the decision depends not only on the data type, what&apos;s usually indicated by some sort of a &lt;code class=&quot;language-text&quot;&gt;type*&lt;/code&gt; property, but also on events that occurred in the past, which like to hide behind boolean flags such as &lt;code class=&quot;language-text&quot;&gt;has*&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;is*&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I&apos;d like to present a dispatch mechanism that identifies the ability to respond differently to the same action as one of its key purposes. And all that without a single boolean value!&lt;/p&gt;
&lt;p&gt;When is it useful? Just think of a &lt;code class=&quot;language-text&quot;&gt;RENDER&lt;/code&gt; action. It&apos;s always the same action, and yet, depending on the actions consumed in the past, we may want it to return different results. &lt;/p&gt;
&lt;p&gt;In this system, &lt;strong&gt;functions are assigned to nodes of a state machine&lt;/strong&gt;, what is somehow similar to how methods are associated with types of objects.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/fsm_javascript-8cfb2db9d5034a20844fa688ed24e4d8.gif&quot; alt=&quot;The Rosmaro architecture&quot;&gt;&lt;/p&gt;
&lt;p&gt;It&apos;s heavily inspired by both &lt;a href=&quot;https://en.wikipedia.org/wiki/State_pattern&quot;&gt;the state design pattern we know from object-oriented programming&lt;/a&gt; and functional front end architectures, like &lt;a href=&quot;https://guide.elm-lang.org/architecture/&quot;&gt;The Elm Architecture&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The current behavior of a model is defined by the currently active node.&lt;/p&gt;
&lt;p&gt;To alter it, the active node returns an arrow describing what has just happened:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token constant&quot;&gt;PIZZA&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  result&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`Tasty`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`ate`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It makes the state machine transition to the node this arrow is pointing at.&lt;/p&gt;
&lt;p&gt;The control flow reflects the hierarchical structure of the state machine. Parent nodes are capable of changing the way their children are called. They may also modify the result:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token constant&quot;&gt;PIZZA&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;alterResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;r &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;r&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;, my friend!`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Wrapping the result of calling the child node turns out especially helpful when composing UI components.&lt;/p&gt;
&lt;p&gt;Speaking of user interfaces, recently I released &lt;a href=&quot;https://www.youtube.com/watch?v=JpFn4Q81f14&quot;&gt;a screencast showing the complete process of using automata-based programming to build a wizard application&lt;/a&gt;. If you like this form, you may find it a nice introduction to this dispatch mechanism.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Consuming and updating the state object with Ramda lenses]]></title><link>https://coder.earth/post/lenses</link><guid isPermaLink="false">https://coder.earth/post/lenses</guid><pubDate>Sun, 03 Feb 2019 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;When I was designing a new major release of Rosmaro, I wanted to make it as modular as possible. I totally understood why component composition in React was so important and that&apos;s why I strived to make Rosmaro models easy to compose as well. Another aspect I cared a lot when I was building the most modular Rosmaro so far was high cohesion. In order to avoid jumping from one place to another, I wanted to group things that change together and separate those that are not related to each other. So I had two, very ambitious goals: modularity (what means decoupling) and cohesion (what means smart decoupling).&lt;/p&gt;
&lt;p&gt;Such a task was challenging, but it somehow felt like a breath of fresh air, because it was nothing like my day to day work. Instead of just making use of the knowledge and skills I already had, I needed to come up with an idea that was at this point unknown to me.&lt;/p&gt;
&lt;p&gt;The Internet, and computers in general, are wonderful. I love to use them and I owe some of the most wonderful memories and feelings to them. But sometimes, when I need to simply think about a hard problem, I like to escape from them. My thoughts often tend to be visual and I find it somehow inspiring and pleasant to sketch things on paper or on a whiteboard, if I happen to have one around.&lt;/p&gt;
&lt;p&gt;That day, when I wanted to find an answer to the question how to make Rosmaro models easy to compose and coherent in the same time, I decided to grab a pen and a couple of sheets of paper and go to the garden. Back then, I was living in the sunny city of Santa Cruz de la Sierra. Sitting under a palm tree, apparently inspired by the beauty of it, I had one of these aha moments! I got the idea to use a pair of symmetrical functions - one would map from form A to form B, and the other one would map from form B to form A. Unfortunately, I didn&apos;t know I just reinvented the concept of lenses. If I knew, it would save me some time. On the other hand, it was really nice to spend some time in that garden.&lt;/p&gt;
&lt;p&gt;For a short period of time, Rosmaro shipped with its own implementation of lenses. It was like that until I discovered &lt;a href=&quot;https://ramdajs.com&quot;&gt;Ramda&lt;/a&gt; which is a wonderful functional JavaScript library that provides a tooling for working with lenses. In this post, I&apos;ll do my best to share with you all the reasons why I find (Ramda) lenses so appealing.&lt;/p&gt;
&lt;p&gt;Regardless our framework of choice, it&apos;s quite common nowadays that there&apos;s some object representing the &lt;a href=&quot;behavior-related-state-and-data-related-state&quot;&gt;data-related state of the application&lt;/a&gt;. For example, it may look like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;flat&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  area&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  tenant&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Łukasz&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    pet&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Small animal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Kubuś&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you&apos;re wondering whether I was recently looking for a flat, then you must know you&apos;re right. Ah, and when I was a kid, I had a guinea pig named Kubuś.&lt;/p&gt;
&lt;p&gt;Let&apos;s get started! We&apos;re gonna start with something simple, that is a lens that will allow us to see the tenant property.&lt;/p&gt;
&lt;p&gt;This is how we build the lens with Ramda:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; tenantLens &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lensProp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;tenant&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And this is how we &quot;view&quot; the state through this lens:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tenantLens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It gives us the value of the &lt;code class=&quot;language-text&quot;&gt;tenant&lt;/code&gt; property:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Łukasz&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pet&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Small animal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Kubuś&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The illustration visible below is my attempt of visualizing this process of zooming in with a lens:

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/zooming_in-c6f42b23daa2bc4e860a707af76e2e20-f3be3.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 40px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAMBAgX/xAAWAQEBAQAAAAAAAAAAAAAAAAACAAH/2gAMAwEAAhADEAAAAd5DaEhJl//EABoQAAICAwAAAAAAAAAAAAAAAAISAAEDESH/2gAIAQEAAQUC3CNLE2peljaCC1//xAAYEQACAwAAAAAAAAAAAAAAAAAAEQECIf/aAAgBAwEBPwGzWEM//8QAGBEAAwEBAAAAAAAAAAAAAAAAAAERIUH/2gAIAQIBAT8BdmCvT//EABcQAQEBAQAAAAAAAAAAAAAAAAAxEBH/2gAIAQEABj8CRHYuf//EABkQAAMBAQEAAAAAAAAAAAAAAAABESFRQf/aAAgBAQABPyGLLp3FNzG9GsI3queinrgTBOn/2gAMAwEAAgADAAAAEIQv/8QAFxEAAwEAAAAAAAAAAAAAAAAAAAEhYf/aAAgBAwEBPxBNBGn/xAAXEQADAQAAAAAAAAAAAAAAAAAAIUFR/9oACAECAQE/EHqE6P/EABoQAQEBAQEBAQAAAAAAAAAAAAERACExQVH/2gAIAQEAAT8Q+IfwbiBoq2a15InWolEC45O4SiL4Zk0Lem//2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Zooming in&quot;
        title=&quot;&quot;
        src=&quot;/static/zooming_in-c6f42b23daa2bc4e860a707af76e2e20-f3be3.jpeg&quot;
        srcset=&quot;/static/zooming_in-c6f42b23daa2bc4e860a707af76e2e20-ba140.jpeg 300w,
/static/zooming_in-c6f42b23daa2bc4e860a707af76e2e20-edc11.jpeg 600w,
/static/zooming_in-c6f42b23daa2bc4e860a707af76e2e20-f3be3.jpeg 1024w&quot;
        sizes=&quot;(max-width: 40px) 100vw, 40px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;There&apos;s some big picture with many things, but when we look at it through this particular lens, all we can see is a small portion of it, magnified.&lt;/p&gt;
&lt;p&gt;If the big picture changes and we look at it through the lens again, the magnified portion reflects this change:

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a_change_in_the_big_picture-d64289ca1583e69e0106820c27573add-f3be3.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 40px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAMBAgX/xAAWAQEBAQAAAAAAAAAAAAAAAAACAAH/2gAMAwEAAhADEAAAAd5DaEhJl//EABoQAAICAwAAAAAAAAAAAAAAAAISAAEDESH/2gAIAQEAAQUC3CNLE2peljaCC1//xAAYEQACAwAAAAAAAAAAAAAAAAAAEQECIf/aAAgBAwEBPwGzWEM//8QAGBEAAwEBAAAAAAAAAAAAAAAAAAERIUH/2gAIAQIBAT8BdmCvT//EABcQAQEBAQAAAAAAAAAAAAAAAAAxEBH/2gAIAQEABj8CRHYuf//EABkQAAMBAQEAAAAAAAAAAAAAAAABESFRQf/aAAgBAQABPyGLLp3FNzG9GsI3queinrgTBOn/2gAMAwEAAgADAAAAEKQv/8QAFxEAAwEAAAAAAAAAAAAAAAAAAAEhYf/aAAgBAwEBPxBNJGn/xAAXEQADAQAAAAAAAAAAAAAAAAAAIUFR/9oACAECAQE/EHqE6P/EABsQAQEBAQEAAwAAAAAAAAAAAAERACExQVFx/9oACAEBAAE/EPhD9NxA0VbNa8kTrIk6Bc/eEoi+GZNC3pv/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A change in the big picture&quot;
        title=&quot;&quot;
        src=&quot;/static/a_change_in_the_big_picture-d64289ca1583e69e0106820c27573add-f3be3.jpeg&quot;
        srcset=&quot;/static/a_change_in_the_big_picture-d64289ca1583e69e0106820c27573add-ba140.jpeg 300w,
/static/a_change_in_the_big_picture-d64289ca1583e69e0106820c27573add-edc11.jpeg 600w,
/static/a_change_in_the_big_picture-d64289ca1583e69e0106820c27573add-f3be3.jpeg 1024w&quot;
        sizes=&quot;(max-width: 40px) 100vw, 40px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a_change_in_the_big_picture_reflected_in_the_magnified_portion-9fa42a3d0ee05c0dd1b7e251f7ab3c67-f3be3.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 40px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAMBAgX/xAAWAQEBAQAAAAAAAAAAAAAAAAAAAQL/2gAMAwEAAhADEAAAAd5LKYBIn//EABkQAQADAQEAAAAAAAAAAAAAAAIAERIBIf/aAAgBAQABBQK4nnpdzPqGukVP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAGREAAgMBAAAAAAAAAAAAAAAAABIBAiER/9oACAECAQE/AbMuENzT/8QAFxABAQEBAAAAAAAAAAAAAAAAADEQEf/aAAgBAQAGPwJEdi5//8QAGhAAAwEAAwAAAAAAAAAAAAAAAREhADFBUf/aAAgBAQABPyFGndCHLIuL7iKATTK71SMimTv/2gAMAwEAAgADAAAAELPP/8QAGBEAAwEBAAAAAAAAAAAAAAAAAAERIUH/2gAIAQMBAT8QiqpvD//EABYRAAMAAAAAAAAAAAAAAAAAAAAhQf/aAAgBAgEBPxB6xSj/xAAbEAEBAQACAwAAAAAAAAAAAAABEQAhQTFRcf/aAAgBAQABPxDpD6aiFpVszOuCO2RJ0C4+8INReA84XFjam//Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A change in the big picture reflected in the magnified portion&quot;
        title=&quot;&quot;
        src=&quot;/static/a_change_in_the_big_picture_reflected_in_the_magnified_portion-9fa42a3d0ee05c0dd1b7e251f7ab3c67-f3be3.jpeg&quot;
        srcset=&quot;/static/a_change_in_the_big_picture_reflected_in_the_magnified_portion-9fa42a3d0ee05c0dd1b7e251f7ab3c67-ba140.jpeg 300w,
/static/a_change_in_the_big_picture_reflected_in_the_magnified_portion-9fa42a3d0ee05c0dd1b7e251f7ab3c67-edc11.jpeg 600w,
/static/a_change_in_the_big_picture_reflected_in_the_magnified_portion-9fa42a3d0ee05c0dd1b7e251f7ab3c67-f3be3.jpeg 1024w&quot;
        sizes=&quot;(max-width: 40px) 100vw, 40px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;So far what we&apos;ve seen is very much like a property selector. That&apos;s totally true that we could do something like &lt;code class=&quot;language-text&quot;&gt;state.tenant&lt;/code&gt; as well and get the same result. However, the power of lenses lies in their bidirectional nature. What it means is that they don&apos;t only reflect changes in the source, but also apply changes in the magnified portion to the source. Visually, it would look like this:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a_change_in_the_magnified_portion-958ec7eeb818a8b24ca330ca539cf70a-f3be3.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 40px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAEDBf/EABYBAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAAB3o0niMYf/8QAGRAAAgMBAAAAAAAAAAAAAAAAAAIBERIh/9oACAEBAAEFArGfMq9meyuxUo//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAZEQACAwEAAAAAAAAAAAAAAAAAEgECIRH/2gAIAQIBAT8Bsy4Q3NP/xAAXEAADAQAAAAAAAAAAAAAAAAAAETEQ/9oACAEBAAY/AiEHBvP/xAAZEAADAQEBAAAAAAAAAAAAAAABESEAQVH/2gAIAQEAAT8hRp3Qg7yJMX3EUAmmV3BKkyKZO//aAAwDAQACAAMAAAAQn8//xAAYEQADAQEAAAAAAAAAAAAAAAAAAREhQf/aAAgBAwEBPxByo3h//8QAFhEAAwAAAAAAAAAAAAAAAAAAACFB/9oACAECAQE/EHrFKP/EABoQAQEBAAMBAAAAAAAAAAAAAAERACFBUXH/2gAIAQEAAT8Q6Q+Mqgoq2ZnOCO2RJ0C4+9OipJMLixtTf//Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A change in the magnified portion&quot;
        title=&quot;&quot;
        src=&quot;/static/a_change_in_the_magnified_portion-958ec7eeb818a8b24ca330ca539cf70a-f3be3.jpeg&quot;
        srcset=&quot;/static/a_change_in_the_magnified_portion-958ec7eeb818a8b24ca330ca539cf70a-ba140.jpeg 300w,
/static/a_change_in_the_magnified_portion-958ec7eeb818a8b24ca330ca539cf70a-edc11.jpeg 600w,
/static/a_change_in_the_magnified_portion-958ec7eeb818a8b24ca330ca539cf70a-f3be3.jpeg 1024w&quot;
        sizes=&quot;(max-width: 40px) 100vw, 40px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a_change_in_the_magnified_portion_reflected_in_the_source-26fb443dc0166d35bf0867e6a9e98254-f3be3.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 40px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAEDBf/EABYBAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAAB3o0niMYf/8QAGRAAAgMBAAAAAAAAAAAAAAAAAAIBERIh/9oACAEBAAEFArGfMq9meyuxUo//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAZEQACAwEAAAAAAAAAAAAAAAAAEgECIRH/2gAIAQIBAT8Bsy4Q3NP/xAAXEAADAQAAAAAAAAAAAAAAAAAAETEQ/9oACAEBAAY/AiEHBvP/xAAZEAADAQEBAAAAAAAAAAAAAAABESEAQVH/2gAIAQEAAT8hRp3Qg7yJMX3EUAmmV3BKkyKZO//aAAwDAQACAAMAAAAQn8//xAAYEQADAQEAAAAAAAAAAAAAAAAAAREhQf/aAAgBAwEBPxByqm8P/8QAFhEAAwAAAAAAAAAAAAAAAAAAACFB/9oACAECAQE/EHrFKP/EABoQAQEBAAMBAAAAAAAAAAAAAAERACFBUXH/2gAIAQEAAT8Q6Q+DKoKKtmZzgjtkSdAuPvToqSTC4sbU3//Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A change in the magnified portion reflected in the source&quot;
        title=&quot;&quot;
        src=&quot;/static/a_change_in_the_magnified_portion_reflected_in_the_source-26fb443dc0166d35bf0867e6a9e98254-f3be3.jpeg&quot;
        srcset=&quot;/static/a_change_in_the_magnified_portion_reflected_in_the_source-26fb443dc0166d35bf0867e6a9e98254-ba140.jpeg 300w,
/static/a_change_in_the_magnified_portion_reflected_in_the_source-26fb443dc0166d35bf0867e6a9e98254-edc11.jpeg 600w,
/static/a_change_in_the_magnified_portion_reflected_in_the_source-26fb443dc0166d35bf0867e6a9e98254-f3be3.jpeg 1024w&quot;
        sizes=&quot;(max-width: 40px) 100vw, 40px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;In the code, it looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    tenantLens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Łukasz&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      pet&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Small animal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Kubuś&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    state
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It gives us a new, updated object:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;flat&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  area&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  tenant&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;     &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Łukasz&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      pet&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Small animal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Kubuś&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As we can see, it&apos;s possible to modify the zoomed in part and have this change applied to the source. The difference when compared to, let&apos;s say, mutable object-oriented programming, is that in the functional approach we aren&apos;t actually modifying any existing structure. Instead of that, a new, slightly different variant is created. However, the similarity to getter and setter methods clearly stands out and that&apos;s why lenses are often called functional getters and setters.&lt;/p&gt;
&lt;p&gt;To illustrate how multiple lenses may be put together to create a telescope, we&apos;re gonna focus on the type of my pet. Even though it&apos;s technically possible, at least in the world of computers, to create a single lens that does it, we&apos;re gonna benefit more from building a telescope, that is a construct made of multiple lenses, because each of these lenses may be then reused in another telescope.&lt;/p&gt;
&lt;p&gt;Let&apos;s start by creating a three lenses:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Focuses on the `tenant` property.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; tenantLens &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lensProp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;tenant&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Focuses on the `pet` property.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; petLens &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lensProp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;pet&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Focuses on the `type` property.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; typeLens &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lensProp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Yay! Now we have everything what&apos;s needed to put together a telescope! 🔭&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; tenantPetTypeTelescope &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;compose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tenantLens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; petLens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; typeLens&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We use the telescope in the same way we use an ordinary lens.&lt;/p&gt;
&lt;p&gt;Both for reading:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tenantPetTypeTelescope&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;that gives:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Small animal&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and for writing:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tenantPetTypeTelescope&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Guinea pig&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;that updated only the very property the telescope is directed at:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;flat&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  area&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  tenant&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Łukasz&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    pet&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Guinea pig&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Kubuś&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Trying to discover what are lenses made of, we&apos;re gonna manually construct a lens that focuses on the area of the flat. Using the &lt;code class=&quot;language-text&quot;&gt;lensProp&lt;/code&gt; factory function, it&apos;s trivial to build it:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; areaLens &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lensProp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;area&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&apos;s trivial, yet cryptic. Let&apos;s decompose it one level down:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; areaLens &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;area&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;assoc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;area&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the snippet visible above we&apos;re using the &lt;code class=&quot;language-text&quot;&gt;lens&lt;/code&gt; factory function. We pass it two functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;code class=&quot;language-text&quot;&gt;area&lt;/code&gt; property &quot;getter&quot; function, that simply reads the value of the &lt;code class=&quot;language-text&quot;&gt;area&lt;/code&gt; property&lt;/li&gt;
&lt;li&gt;the &lt;code class=&quot;language-text&quot;&gt;area&lt;/code&gt; property &quot;setter&quot; function, that creates a new version of an object with the &lt;code class=&quot;language-text&quot;&gt;area&lt;/code&gt; property set to the value we pass to it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To be honest, I must admit, that when I first saw such an example it was still a bit enigmatic to me. It was only when I implemented both the getter and the setter functions myself that I really understood how to construct lenses. Going deeper, let&apos;s do the same with our &lt;code class=&quot;language-text&quot;&gt;areaLens&lt;/code&gt; example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; areaLens &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  wholeObject &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; wholeObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;area&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;smallPiece&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; wholeObject&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;wholeObject&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; area&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; smallPiece &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first function, that is the getter, takes one argument, that is the whole state object, and simply returns the &lt;code class=&quot;language-text&quot;&gt;area&lt;/code&gt; property. Very straightforward.
The second function, which is the setter, is a bit more complex, as it gets two arguments: a small piece and the whole object. The whole object is meant to be the very same thing we passed to the getter function, which in our case is the whole state object (&lt;code class=&quot;language-text&quot;&gt;wholeObject&lt;/code&gt;). The small piece is supposed to be an updated version of the value returned by the getter (&lt;code class=&quot;language-text&quot;&gt;wholeObject.area&lt;/code&gt;). Only then the change to the &lt;code class=&quot;language-text&quot;&gt;wholeObject.area&lt;/code&gt; property may be applied to the &lt;code class=&quot;language-text&quot;&gt;wholeObject&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is how this lens works, regardless the way it&apos;s constructed:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;areaLens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// output:&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;areaLens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;52&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// output:&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;flat&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  area&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;52&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  tenant&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Łukasz&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    pet&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Small animal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Kubuś&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, that we know lenses are not magic, but just two functions to map in and map out, let&apos;s try to do some even more interesting. So far we&apos;ve been just zooming in and zooming out, but the cool thing is that we&apos;re not limited to just this. In the same way mirrors in a hall of mirrors don&apos;t need to reflect the reality, our lenses don&apos;t need to be symmetrical. They may cast a projection that&apos;s different than the fragment of the source image we&apos;re looking at.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a_deformed_lens-66cdf0eb281b16bed7f7100fb43482ba-f3be3.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 40px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAEDBf/EABYBAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAAB3o0niMYf/8QAGRAAAgMBAAAAAAAAAAAAAAAAAAIBERIh/9oACAEBAAEFArGfMq9meyuxUo//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAZEQACAwEAAAAAAAAAAAAAAAAAEgECIRH/2gAIAQIBAT8Bsy4Q3NP/xAAXEAADAQAAAAAAAAAAAAAAAAAAETEQ/9oACAEBAAY/AiEHBvP/xAAZEAADAQEBAAAAAAAAAAAAAAAAAREhQYH/2gAIAQEAAT8hiy6YSukNx6NYRvVc6JbTCGVs/9oADAMBAAIAAwAAABCfz//EABgRAAMBAQAAAAAAAAAAAAAAAAABESFB/9oACAEDAQE/EHKjeH//xAAWEQADAAAAAAAAAAAAAAAAAAAAIUH/2gAIAQIBAT8QasUo/8QAGhABAQEAAwEAAAAAAAAAAAAAAREAIUFRcf/aAAgBAQABPxDpD4Mqgoq2ZnXAztkSdAuPvToqSTC4sbU3/9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A deformed lens&quot;
        title=&quot;&quot;
        src=&quot;/static/a_deformed_lens-66cdf0eb281b16bed7f7100fb43482ba-f3be3.jpeg&quot;
        srcset=&quot;/static/a_deformed_lens-66cdf0eb281b16bed7f7100fb43482ba-ba140.jpeg 300w,
/static/a_deformed_lens-66cdf0eb281b16bed7f7100fb43482ba-edc11.jpeg 600w,
/static/a_deformed_lens-66cdf0eb281b16bed7f7100fb43482ba-f3be3.jpeg 1024w&quot;
        sizes=&quot;(max-width: 40px) 100vw, 40px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    
Please note that little bump on the surface of the lens. It&apos;s making the triangle shape in the source image being projected as a spherical one. And because our lenses are bidirectional, an update to the &quot;distorted&quot; projection will be reflected in the source.&lt;/p&gt;
&lt;p&gt;For a more concrete example, let&apos;s try to enhance our &lt;code class=&quot;language-text&quot;&gt;areaLens&lt;/code&gt; in such a way it changes the unit from square meters to square centimeters.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; areaLens &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  wholeObject &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; wholeObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;area &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;smallPiece&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; wholeObject&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;wholeObject&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; area&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; smallPiece &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10000&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can treat the area like it were in square centimeters, both when reading and when writing, and in the whole state it will always be represented in square meters.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;areaLens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// output:&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;420000&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// square centimeters&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;areaLens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;520000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// square centimeters&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// output:&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;flat&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  area&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;52&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// square meters&lt;/span&gt;
  tenant&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Łukasz&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    pet&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Small animal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Kubuś&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&apos;s pretty neat! The little pieces of code that operate on the area are totally unaware that it&apos;s actually in a different unit and that there are some other fields as well. Thanks to the lens they are totally decoupled from the shape and size of the state object.&lt;/p&gt;
&lt;p&gt;Another cool thing about Ramda lenses is how easy it is to use them with the &lt;code class=&quot;language-text&quot;&gt;pipe&lt;/code&gt; function. Because all Ramda functions are curried, what&apos;s returned by the &lt;code class=&quot;language-text&quot;&gt;set&lt;/code&gt; function when called with only two arguments (the lens and the value to set) is a function that takes the remaining argument, that is the object where the value is supposed to be set, and returns the updated version of this object.&lt;/p&gt;
&lt;p&gt;Let&apos;s suppose that we want to update two fields in our global state object: the &lt;code class=&quot;language-text&quot;&gt;area&lt;/code&gt; (provided in square centimeters) and the &lt;code class=&quot;language-text&quot;&gt;type&lt;/code&gt; of the &lt;code class=&quot;language-text&quot;&gt;pet&lt;/code&gt;. Doing it using the spread operator would look like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  area&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;450000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  tenant&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tenant&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    pet&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tenant&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pet&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Guinea pig&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is heavily coupled to the structure of the state and quite error prone, because every time we update an object field, we need to remember to spread the rest of the properties, otherwise we&apos;re gonna lose some data. Also, all key names must be exactly the same. Usually it&apos;s not a problem, because within one project it&apos;s a good idea to keep the terminology consistent, but as soon as we want to share a piece of code that operates on the global state it becomes a challenge, because then the structure and key names must be consistent among all its clients, what makes it not so reusable.&lt;/p&gt;
&lt;p&gt;With lenses, this is a lot cleaner, less coupled and reusable:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;areaLens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;450000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tenantPetTypeTelescope&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Guinea pig&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The next time we want to update the type of the pet, we can use exactly the same lens (or telescope):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tenantPetTypeTelescope&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rodent&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can use this telescope to read it as well:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tenantPetTypeTelescope&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;state&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &apos;rodent&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And if the name of the field changes, there&apos;s just one place that really requires a change - the telescope. For example, if the global state doesn&apos;t use &lt;code class=&quot;language-text&quot;&gt;type&lt;/code&gt; anymore, because it&apos;s been renamed to &lt;code class=&quot;language-text&quot;&gt;kind&lt;/code&gt;, the client code doesn&apos;t really need to know about it. This is how the updated telescope may look like:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; tenantPetTypeTelescope &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lensPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;tenant&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pet&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;kind&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Lenses turn out to be so useful, that they became first-class citizens in Rosmaro. For example, here&apos;s the code associated with a child node of the &lt;a href=&quot;https://coder.earth/post/an-overview-of-the-rosmaro-todomvc-app-codebase/&quot;&gt;TodoMVC app implemented in Rosmaro&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Child node (component)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;ADD&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; content &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  context&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;cleared&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  effect&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DISPATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;TODO_ADD&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;trim&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As we can see, it treats the context, which is the Rosmaro&apos;s term for the global state, like it were an object with just one propety - &lt;code class=&quot;language-text&quot;&gt;content&lt;/code&gt;. It uses destructing to read it directly from the context: &lt;code class=&quot;language-text&quot;&gt;({ context: { content } })&lt;/code&gt; and when it needs to clear it, it just provides an object that consists of nothing but a single property: &lt;code class=&quot;language-text&quot;&gt;context: { content: &amp;#39;&amp;#39; }&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;From the child node&apos;s perspective, the context is very simple and doesn&apos;t have any data it doesn&apos;t need to have. However, the whole context is a lot bigger:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  newTodoForm&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;What I am typing&apos;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  list&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    todos&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;zc&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;asdf&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    lastId&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&apos;s only thanks to a proper lens associated with the parent node that the child node may stay focused solely on its own teeny tiny part of the context:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Parent node (component)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; opts &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  lens&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;compose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;sliceLens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;newTodoForm&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;initialValueLens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  handler&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; transparentHandler&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Personally, I love lenses for their cohesion (keeping the code related to property access together) and the freedom they give (may be used to adapt an incompatible otherwise piece of code). They are one of those very intuitive constructs, that like state machines, may be reinvented and appear under various names (like adapters or user flows).&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Testing the TodoMVC app]]></title><link>https://coder.earth/post/testing-the-todomvc-app</link><guid isPermaLink="false">https://coder.earth/post/testing-the-todomvc-app</guid><pubDate>Sun, 27 Jan 2019 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;We&apos;ve already covered two important parts of building the &lt;a href=&quot;https://github.com/lukaszmakuch/todomvc-rosmaro&quot;&gt;TodoMVC app&lt;/a&gt;: &lt;a href=&quot;https://coder.earth/post/decomposing-the-todomvc-app-with-state-diagrams&quot;&gt;state diagrams drawn in the editor&lt;/a&gt; and the &lt;a href=&quot;https://coder.earth/post/an-overview-of-the-rosmaro-todomvc-app-codebase&quot;&gt;code associated with nodes&lt;/a&gt;. These things are crucial in the development process, because without them there would be no app at all. However, if we want to make sure the development process is sustainable, we need to have an automatic test suite. Without such a thing we can&apos;t really know if a little change to the codebase we&apos;ve just introduced doesn&apos;t break any important functionality without testing the whole thing manually. And because humans are not the best test runners, at least compared to computers, manual tests tend to be not so repetitive and quite error prone.&lt;/p&gt;
&lt;p&gt;I&apos;m pretty sure you also love that feeling of freedom that a good automatic test suite brings. There&apos;s no fear of refactoring, no fear of regression. So why are we even talking about automatic tests, if it&apos;s so obvious that they are beneficial? It&apos;s because they are not trivial to introduce. Many frameworks have their own testing framework, testing philosophy etc. So does Rosmaro. It only shows that test automation is still kind of an uncharted territory.&lt;/p&gt;
&lt;p&gt;Before we dive deep into the details of how the &lt;a href=&quot;https://github.com/lukaszmakuch/todomvc-rosmaro/tree/master/__tests__&quot;&gt;tests in our codebase&lt;/a&gt; are implemented, I&apos;d like to show you a snippet from the test of adding a new item:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// __tests__/adding_a_todo.js&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;adding a todo&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;testFlow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    assertFooterInvisible&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    assertMainInvisible&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    assertNewTodoFormFocused&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    assertMarkAllAsCompletedInvisible&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;addTodo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;new todo&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertTodoPresent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;new todo&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertTodoActive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;new todo&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    assertMarkAllAsCompletedUnchecked&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    assertFooterVisible&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    assertMainVisible&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A test is a high-level description of the required behavior, without going deep into any implementation details of the application, like what does it exactly mean that the footer is invisible or how to add a todo.&lt;/p&gt;
&lt;p&gt;Every test is made of a series of little steps that can either make assertions, like &lt;code class=&quot;language-text&quot;&gt;assertFooterInvisible&lt;/code&gt; or &quot;perform&quot; an action, like &lt;code class=&quot;language-text&quot;&gt;addTodo&lt;/code&gt;. Steps are reusable and may be composed in various way to create different tests.&lt;/p&gt;
&lt;p&gt;Even though there are multiple wonderful testing libraries under the hood, like &lt;a href=&quot;https://github.com/kentcdodds/dom-testing-library&quot;&gt;dom-testing-library&lt;/a&gt; which is the framework-agnostic core of &lt;a href=&quot;https://github.com/kentcdodds/react-testing-library&quot;&gt;react-testing-library&lt;/a&gt;, which in our case of a &lt;a href=&quot;https://github.com/snabbdom/snabbdom&quot;&gt;snabbdom&lt;/a&gt;-based implementation is used via &lt;a href=&quot;https://github.com/lukaszmakuch/snabbdom-testing-library&quot;&gt;snabbdom-testing-library&lt;/a&gt; or &lt;a href=&quot;https://jestjs.io&quot;&gt;jest&lt;/a&gt;, the testing framework itself, it&apos;s the functional approach that makes tests simple. The Virtual DOM enables us to narrow down the whole DOM-related code to a bunch of pure functions of the application state (&lt;code class=&quot;language-text&quot;&gt;state =&amp;gt; UI&lt;/code&gt;). Rosmaro&apos;s side-effect model, heavily inspired by &lt;a href=&quot;https://elm-lang.org&quot;&gt;Elm&lt;/a&gt;, where effects are simply values returned by pure functions, is usually implemented by running the Rosmaro model function in a &lt;a href=&quot;http://redux.js.org&quot;&gt;Redux store&lt;/a&gt; with &lt;a href=&quot;https://redux-saga.js.org&quot;&gt;Redux-Saga&lt;/a&gt;. It&apos;s quite straightforward to achieve, as the &lt;a href=&quot;https://rosmaro.js.org/doc/#utilities&quot;&gt;Rosmaro ecosystem&lt;/a&gt; provides the glue necessary to make all these pieces work together. Standing on the shoulders of giants, it took just a little bit of code to create &lt;a href=&quot;https://github.com/lukaszmakuch/rosmaro-testing-library&quot;&gt;rosmaro-testing-library&lt;/a&gt; which main purpose is to reduce the tests to a series of steps looking like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  feed&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;...&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  consume&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Because a Rosmaro model is nothing but a pure function of state and action that returns an updated version of the state and some result, that is &lt;code class=&quot;language-text&quot;&gt;({ state, action }) =&amp;gt; ({ state, result })&lt;/code&gt;, there are no moving parts we need to keep track of when testing it. As long as we provide the same &lt;code class=&quot;language-text&quot;&gt;state&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;action&lt;/code&gt; values, it will always return the exact same new &lt;code class=&quot;language-text&quot;&gt;state&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;result&lt;/code&gt;. We don&apos;t need to think about asynchronous calls, unexpected side effects run in the test suite or unhandled promise rejections, because there are not things like that at all.&lt;/p&gt;
&lt;p&gt;We could say that the rosmaro-testing-library is a &quot;fake&quot;, manually &quot;increased&quot; runtime environment for the Rosmaro model under test. It&apos;s actually very similar to Redux, in terms of reducing the list of steps using the model function. The testing-related part is the &lt;code class=&quot;language-text&quot;&gt;consume&lt;/code&gt; function that allows us to make assertions about the result of consuming an &lt;code class=&quot;language-text&quot;&gt;action&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Please don&apos;t worry, if some of the things above are not totally clear. They will certainly make sense after we go through the code.&lt;/p&gt;
&lt;p&gt;Let&apos;s then take a look at the complete test file, not just a snippet extracted from it:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// __tests__/adding_a_todo.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; testFlow &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~/testUtils/testFlow&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; assertFooterInvisible &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~/testSteps/assert_footer_invisible&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; assertFooterVisible &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~/testSteps/assert_footer_visible&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; assertMainInvisible &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~/testSteps/assert_main_invisible&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; assertMainVisible &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~/testSteps/assert_main_visible&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; addTodo &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~/testSteps/add_todo&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; assertNewTodoFormFocused &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~/testSteps/assert_new_todo_form_focused&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; assertMarkAllAsCompletedInvisible &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~/testSteps/assert_mark_all_as_completed_invisible&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; assertMarkAllAsCompletedUnchecked &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~/testSteps/assert_mark_all_as_completed_unchecked&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; assertTodoPresent &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~/testSteps/assert_todo_present&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; assertTodoActive &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~/testSteps/assert_todo_active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;adding a todo&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;testFlow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    assertFooterInvisible&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    assertMainInvisible&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    assertNewTodoFormFocused&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    assertMarkAllAsCompletedInvisible&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;addTodo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;new todo&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertTodoPresent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;new todo&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertTodoActive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;new todo&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    assertMarkAllAsCompletedUnchecked&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    assertFooterVisible&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    assertMainVisible&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The file lives in the &lt;code class=&quot;language-text&quot;&gt;__tests__&lt;/code&gt; directory, what denotes that it will be picked by &lt;code class=&quot;language-text&quot;&gt;jest&lt;/code&gt; and run when we run &lt;code class=&quot;language-text&quot;&gt;npm t&lt;/code&gt; in our terminal.&lt;/p&gt;
&lt;p&gt;As we can see, there isn&apos;t much more code than what we&apos;ve already seen. Actually there are only imports. Starting from the very top of the file, we import the &lt;code class=&quot;language-text&quot;&gt;testFlow&lt;/code&gt; helper function from a project-specific setup file &lt;code class=&quot;language-text&quot;&gt;~/testUtils/testFlow&lt;/code&gt;, which main goal is to wrap the &lt;a href=&quot;https://github.com/lukaszmakuch/rosmaro-testing-library#testflow&quot;&gt;testFlow utility from rosmaro-testing-library&lt;/a&gt;. All the other imports are test steps, that is &lt;code class=&quot;language-text&quot;&gt;{ feed, consume }&lt;/code&gt; objects or collections of these objects (they may be nested).&lt;/p&gt;
&lt;p&gt;The difference between a test and a test step is that a test is the final, complete scenario the test runner picks and runs, while a test step is just a building block that may be reused in multiple tests, or even within the same test.&lt;/p&gt;
&lt;p&gt;The complete code of the step asserting that the footer is invisible is just a couple of lines long:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// testSteps/assert_footer_invisible.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; testContext &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  feed&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;RENDER&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  consume&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; queryByTestId &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; testContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;queryByTestId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;footer&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBeNull&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What&apos;s returned by the function of &lt;code class=&quot;language-text&quot;&gt;testContext&lt;/code&gt; is the actual test step. We&apos;ll go back to the &lt;code class=&quot;language-text&quot;&gt;testContext&lt;/code&gt; soon, but for now, I think it&apos;s a better idea to focus on &lt;code class=&quot;language-text&quot;&gt;feed&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;consume&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;feed&lt;/code&gt; value is the action that&apos;s passed to the model. In this case, we want to ensure that the footer is not rendered, so we&apos;re giving the model a &lt;code class=&quot;language-text&quot;&gt;{ type: &amp;#39;RENDER&amp;#39; }&lt;/code&gt; action, expecting it to render the UI.&lt;/p&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;consume&lt;/code&gt; function takes the result of calling the Rosmaro model with the recent &lt;code class=&quot;language-text&quot;&gt;state&lt;/code&gt; and the &lt;code class=&quot;language-text&quot;&gt;action&lt;/code&gt; from the &lt;code class=&quot;language-text&quot;&gt;feed&lt;/code&gt; property. Let&apos;s focus on this function for a moment, as it plays a very important role in testing Rosmaro models. Because we&apos;re using &lt;a href=&quot;https://github.com/lukaszmakuch/rosmaro-binding-utils&quot;&gt;rosmaro-binding-utils&lt;/a&gt;, the &lt;code class=&quot;language-text&quot;&gt;result&lt;/code&gt; always has the following structure: &lt;code class=&quot;language-text&quot;&gt;{ data, effect }&lt;/code&gt;. The &lt;code class=&quot;language-text&quot;&gt;RENDER&lt;/code&gt; action is not supposed to have any side effects, and that&apos;s why we may totally ignore the &lt;code class=&quot;language-text&quot;&gt;effect&lt;/code&gt; property and focus solely on the &lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt;, which in this case is a Snabbdom VDOM node. We&apos;re using the &lt;code class=&quot;language-text&quot;&gt;render&lt;/code&gt; function from the &lt;code class=&quot;language-text&quot;&gt;testContext&lt;/code&gt;. It comes from &lt;a href=&quot;https://github.com/lukaszmakuch/snabbdom-testing-library&quot;&gt;snabbdom-testing-library&lt;/a&gt; and gives us all the selectors and utilities provided by &lt;a href=&quot;https://github.com/kentcdodds/dom-testing-library&quot;&gt;dom-testing-library&lt;/a&gt;. Due to the fact that the template of the TodoMVC app doesn&apos;t really help us with label-based selectors, we&apos;re using a little bit less nice (when it comes to test coverage), but well functioning selector function &lt;code class=&quot;language-text&quot;&gt;queryByTestId&lt;/code&gt;. It matches the element based on the &lt;code class=&quot;language-text&quot;&gt;data-testid&lt;/code&gt; attribute we&apos;re setting on it:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// components/root/bindings/main/Layout/WholeApp/index.js&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;footer.footer&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; attrs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;data-testid&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;footer&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  list&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;counter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  controls&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Navigation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ui&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  controls&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ClearCompleted&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After querying for the element, we can use the &lt;code class=&quot;language-text&quot;&gt;expect&lt;/code&gt; function from &lt;code class=&quot;language-text&quot;&gt;jest&lt;/code&gt; to make sure that no footer is rendered:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// testSteps/assert_footer_invisible.js&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;queryByTestId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;footer&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBeNull&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;testContext&lt;/code&gt; object comes from &lt;code class=&quot;language-text&quot;&gt;rosmaro-testing-library&lt;/code&gt; and is used to store things that may be useful during the test. In our setup file, &lt;code class=&quot;language-text&quot;&gt;testUtils/testFlow.js&lt;/code&gt;, we put there the &lt;code class=&quot;language-text&quot;&gt;render&lt;/code&gt; function from &lt;code class=&quot;language-text&quot;&gt;snabbdom-testing-library&lt;/code&gt;. This object may be updated in a very similar way the state is updated, that is by returning its new version. If there&apos;s something in the result of consuming an action that we would like to make available for further test steps, we can add it to the context. You can find more on this in the &lt;a href=&quot;https://github.com/lukaszmakuch/rosmaro-testing-library/blob/master/README.md&quot;&gt;README of rosmaro-testing-library&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the test, there&apos;s an interesting, parameterized step to add a new item - &lt;code class=&quot;language-text&quot;&gt;addTodo&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// __tests__/adding_a_todo.js&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;adding a todo&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;testFlow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;addTodo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;new todo&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let&apos;s take a closer look at its source code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// testSteps/add_todo.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; typeInNewTodo &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~/testSteps/type_in_new_todo&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; enterInNewTodoInput &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~/testSteps/enter_in_new_todo_input&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;typeInNewTodo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; enterInNewTodoInput&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As we can see, this step consists of two smaller steps: &lt;code class=&quot;language-text&quot;&gt;typeInNewTodo&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;enterInNewTodoInput&lt;/code&gt;. The first one simulates writing something in the input field and looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// testSteps/type_in_new_todo.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; fireEvent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;snabbdom-testing-library&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; consumeActionsWithEffects &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rosmaro-testing-library&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; testContext &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  feed&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;RENDER&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  consume&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    testContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;store&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clearActions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; getByPlaceholderText &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; testContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; input &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getByPlaceholderText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;What needs to be done?&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    fireEvent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;input&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; actions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; testContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;store&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getActions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; step&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;consumeActionsWithEffects&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;actions&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We&apos;re using a factory function, that is a function of &lt;code class=&quot;language-text&quot;&gt;value&lt;/code&gt;, in order to build a test step (a function of &lt;code class=&quot;language-text&quot;&gt;testContext&lt;/code&gt;) that simulates typing the &lt;code class=&quot;language-text&quot;&gt;value&lt;/code&gt; in the input field. In order to examine the input field and its behavior, we&apos;re rendering the UI in the same way we did it previously, that is by passing a &lt;code class=&quot;language-text&quot;&gt;RENDER&lt;/code&gt; action to the model. This time, however, we need to do something more sophisticated - we need to simulate user interaction. That&apos;s why after querying for the input field, here using the &lt;code class=&quot;language-text&quot;&gt;getByPlaceholderText&lt;/code&gt; function, we&apos;re simulating input event using the &lt;code class=&quot;language-text&quot;&gt;fireEvent&lt;/code&gt; function from &lt;code class=&quot;language-text&quot;&gt;snabbdom-testing-library&lt;/code&gt;. Because all the UI does is dispatching actions to the redux store, we&apos;re using the &lt;code class=&quot;language-text&quot;&gt;redux-mock-store&lt;/code&gt; package to simulate a store and get all the actions that have been dispatched to it. Aadding an item and reacting to it is quite complex and takes a few events, and that&apos;s why we&apos;re making use of the &lt;code class=&quot;language-text&quot;&gt;consumeActionsWithEffects&lt;/code&gt; helper from &lt;code class=&quot;language-text&quot;&gt;rosmaro-testing-library&lt;/code&gt; in order to emulate &lt;code class=&quot;language-text&quot;&gt;DISPATCH&lt;/code&gt; effects. It will generate further test steps, that is &lt;code class=&quot;language-text&quot;&gt;{ feed, consume }&lt;/code&gt; objects necessary to fully handle the process of adding an item. As mentioned in the &lt;a href=&quot;https://coder.earth/post/an-overview-of-the-rosmaro-todomvc-app-codebase&quot;&gt;previous post with the code of the TodoMVC app&lt;/a&gt;, the list of items dispatches events that the rest of the app may react to, for example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// main/Components/List/View/index.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DISPATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;SOME_TODOS_COMPLETED&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sometimes, when we do really care about every single iteration, we may want to manually &quot;execute&quot; effects by storying them in the &lt;code class=&quot;language-text&quot;&gt;testContext&lt;/code&gt; and passing them as actions in the &lt;code class=&quot;language-text&quot;&gt;feed&lt;/code&gt; property, for example to make sure that there&apos;s no race condition, if our Rosmaro model is used to handle some network communication or another time sensitive process.&lt;/p&gt;
&lt;p&gt;Below you can see some other tests, taken directly from the &lt;strong&gt;tests&lt;/strong&gt; directory, just without all the imports (for the sake of brevity):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// __tests__/counter_for_1_active_todo.js&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;the counter shows &quot;1 item left&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;testFlow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;addTodo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;todo A&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;addTodo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;todo B&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;toggleTodo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;todo A&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertCounterValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; expectedValue&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;1 item left&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// __tests__/marking_a_todo_as_completed.js&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;marking a todo as completed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;testFlow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;addTodo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;first todo&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;addTodo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;second todo&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;toggleTodo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;second todo&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertTodoCompleted&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;second todo&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertTodoActive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;first todo&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// __tests__/removing_a_todo.js&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;removing a todo&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;testFlow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;addTodo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;todo A&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;toggleTodo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;todo A&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;addTodo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;todo B&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;addTodo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;todo C&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;assertTodoPresent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;todo A&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertTodoCompleted&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;todo A&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;clickDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; todo&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;todo B&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;assertTodoNotPresent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;todo B&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;assertTodoPresent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;todo C&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertTodoActive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;todo C&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I hope you enjoyed this post and that it gave you a broad idea how Rosmaro models may be tested. If you&apos;re willing to learn more, you may find the following resources helpful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/lukaszmakuch/rosmaro-testing-library&quot;&gt;rosmaro-testing-library on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/lukaszmakuch/todomvc-rosmaro/tree/master/testUtils&quot;&gt;testUtils&lt;/a&gt;, &lt;a href=&quot;https://github.com/lukaszmakuch/todomvc-rosmaro/tree/master/testSteps&quot;&gt;testSteps&lt;/a&gt; and &lt;a href=&quot;https://github.com/lukaszmakuch/todomvc-rosmaro/tree/master/__tests__&quot;&gt;the test files&lt;/a&gt; from the repository of the Rosmaro TodoMVC app&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[An overview of the Rosmaro-TodoMVC app codebase]]></title><link>https://coder.earth/post/an-overview-of-the-rosmaro-todomvc-app-codebase</link><guid isPermaLink="false">https://coder.earth/post/an-overview-of-the-rosmaro-todomvc-app-codebase</guid><pubDate>Sun, 20 Jan 2019 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;In the previous post about &lt;a href=&quot;https://coder.earth/post/decomposing-the-todomvc-app-with-state-diagrams&quot;&gt;decomposing the TodoMVC app with state diagrams&lt;/a&gt; I showed you the state diagrams I used to build &lt;a href=&quot;https://coder.earth/todomvc-rosmaro/&quot;&gt;this TodoMVC app&lt;/a&gt;, but no code at all. Even though the diagrams are a crucial part of the implementation, as they define when and how does the behavior of the app change, they don&apos;t specify the very details of any particular behavior. It&apos;s the code&apos;s job. That&apos;s why today we&apos;re gonna take a look at the written part of the implementation. It&apos;s gonna be a broad overview of the important pieces, what should give you an idea what it is like to build a Rosmaro application, without going through all the boring details.&lt;/p&gt;
&lt;h2&gt;Directory structure&lt;/h2&gt;
&lt;p&gt;Due to the fact that the graph-code connection is managed with &lt;a href=&quot;https://github.com/lukaszmakuch/rosmaro-tools&quot;&gt;rosmaro-tools&lt;/a&gt;, the directory structure serves as a good starting point.&lt;/p&gt;
&lt;p&gt;The model-specific part of the directory tree, that is where the behavior of the application lives, looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;.
├── index.js
├── Layout
│   ├── index.js
│   ├── WholeApp
│   │   └── index.js
│   └── JustForm
│       └── index.js
└── Components
    ├── index.js
    ├── NewTodoForm
    │   ├── index.js
    │   ├── FilledIn
    │   │   └── index.js
    │   ├── Empty
    │   │   └── index.js
    │   └── lib
    │       └── form.js
    ├── List
    │   ├── index.js
    │   └── View
    │       ├── index.js
    │       └── child
    │           ├── index.js
    │           ├── Active
    │           │   ├── index.js
    │           │   ├── Editing
    │           │   │   ├── index.js
    │           │   │   ├── FilledIn
    │           │   │   │   └── index.js
    │           │   │   └── Empty
    │           │   │       └── index.js
    │           │   └── Displaying
    │           │       └── index.js
    │           ├── Completed
    │           │   ├── index.js
    │           │   ├── Editing
    │           │   │   ├── index.js
    │           │   │   ├── FilledIn
    │           │   │   │   └── index.js
    │           │   │   └── Empty
    │           │   │       └── index.js
    │           │   └── Displaying
    │           │       └── index.js
    │           └── lib
    │               ├── filtering.js
    │               ├── editing.js
    │               └── displaying.js
    └── Controls
        ├── index.js
        ├── Navigation
        │   ├── index.js
        │   └── Buttons
        │       ├── index.js
        │       ├── Completed
        │       │   └── index.js
        │       ├── All
        │       │   └── index.js
        │       ├── Active
        │       │   └── index.js
        │       └── lib
        │           └── templates.js
        ├── MarkAll
        │   ├── index.js
        │   ├── Unchecked
        │   │   └── index.js
        │   ├── Checked
        │   │   └── index.js
        │   └── lib
        │       └── view.js
        └── ClearCompleted
            ├── index.js
            ├── Visible
            │   └── index.js
            └── Hidden
                └── index.js&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Please don&apos;t let the number of files scare you, as &lt;strong&gt;most of them are just a couple of lines long&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Their main purpose is to enable automatic graph-code bindings. Instead of manually specifying that a particular node is bound to a particular piece of code and then importing the code from its own file, with this directory-based approach we can just place the code under a path coresponding to its node and the binding is going to be built for us. We&apos;re killing two birds with one stone here!&lt;/p&gt;
&lt;p&gt;The utility is registered as one of the npm scripts in the &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt; file, so that we can re-build the automatically generated code by simply running &lt;code class=&quot;language-text&quot;&gt;npm run rosmaro-bindings&lt;/code&gt; in the terminal:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;rosmaro-bindings&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rosmaro-tools bindings:build js/components/root/bindings&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Simple handlers&lt;/h2&gt;
&lt;p&gt;The &quot;Clear completed&quot; button is one of the simplest subgraphs in the application. It&apos;s either hidden or visible, and when it&apos;s visible, then clicking it dispatches the &lt;code class=&quot;language-text&quot;&gt;CLEAR_COMPLETED&lt;/code&gt; action that is consumed by the list items.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/clear_completed-ecd4adce8c22ab6e90e19966653f7451.gif&quot; alt=&quot;&amp;#x22;Clear completed&amp;#x22; button&quot;&gt;&lt;/p&gt;
&lt;p&gt;The code assigned to the &lt;code class=&quot;language-text&quot;&gt;Visible&lt;/code&gt; node handles rendering the button (with an event listener) and follows the &lt;code class=&quot;language-text&quot;&gt;none are completed&lt;/code&gt; arrow when the list of items dispatches either &lt;code class=&quot;language-text&quot;&gt;NO_TODOS_COMPLETED&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;NO_TODOS&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Visible/index.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;noneCompleted&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;none are completed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;dispatch&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  handler&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeHandler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token constant&quot;&gt;NO_TODOS_COMPLETED&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; noneCompleted&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;NO_TODOS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; noneCompleted&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token constant&quot;&gt;RENDER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;button.clear-completed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        on&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;click&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;CLEAR_COMPLETED&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Clear completed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When the button is hidden, it renders as an empty string. As soon as the list dispatches an event like &lt;code class=&quot;language-text&quot;&gt;SOME_TODOS_COMPLETED&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;ALL_TODOS_COMPLETED&lt;/code&gt;, it follows the &lt;code class=&quot;language-text&quot;&gt;some are completed&lt;/code&gt; arrow in order to transition to the &lt;code class=&quot;language-text&quot;&gt;Visible&lt;/code&gt; state. Of course, the graph code is not aware of the target node, as it&apos;s specified in the graph. The graph code is concerned only about things directly related to its functions, like when should it follow one of its arrows:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Hidden/index.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;someCompleted&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;some are completed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;dispatch&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  handler&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeHandler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token constant&quot;&gt;ALL_TODOS_COMPLETED&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; someCompleted&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;SOME_TODOS_COMPLETED&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; someCompleted&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token constant&quot;&gt;RENDER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;Coding similar behaviors&lt;/h1&gt;
&lt;p&gt;The nodes we&apos;ve seen above are quite distinctive, because they react to different events and render in a totally different way. They don&apos;t really share any code. But it&apos;s not always the case. For example, the form used to add new items may also be in two differnet states: &lt;code class=&quot;language-text&quot;&gt;FilledIn&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Empty&lt;/code&gt;, but the only difference between these two states is that an &lt;code class=&quot;language-text&quot;&gt;Empty&lt;/code&gt; form doesn&apos;t allow to add a new item.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/new_todo_form-3d1bbccae78bd6742d51e716b07e1388-5fc3e.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 594px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 37.878787878787875%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAjklEQVQoz6WRWQpDIQxF3f9GHcDZ5wDCLUlr6c+z2AqHGEnMTSJaa6i1oveOMQaz3k6gnFIKBF7HWgvnHNs5J34513VBLGUpJYQQGKq21J5AfwhjDKSUUEpBa82QfwrlUYeCFNHlX7z3T4U0yDvWGGKMb7uL56XQIO/IOWN1QMuiArt4Xsqu2gr69L8pfACFMWfB5BwTOgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;&quot;New todo item&quot; form&quot;
        title=&quot;&quot;
        src=&quot;/static/new_todo_form-3d1bbccae78bd6742d51e716b07e1388-5fc3e.png&quot;
        srcset=&quot;/static/new_todo_form-3d1bbccae78bd6742d51e716b07e1388-07eee.png 300w,
/static/new_todo_form-3d1bbccae78bd6742d51e716b07e1388-e1611.png 600w,
/static/new_todo_form-3d1bbccae78bd6742d51e716b07e1388-5fc3e.png 1188w&quot;
        sizes=&quot;(max-width: 594px) 100vw, 594px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;To avoid code duplication and make this difference clear, the code of makes use of a shared library. This is the code of the &lt;code class=&quot;language-text&quot;&gt;FilledIn&lt;/code&gt; state:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// main/Components/NewTodoForm/FilledIn/index.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;makeBinding&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ADD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./../lib/form&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeBinding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ADD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It imports both the binding factory and a handler of the &lt;code class=&quot;language-text&quot;&gt;ADD&lt;/code&gt; action from the library located on the same level as the &lt;code class=&quot;language-text&quot;&gt;FilledIn&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Empty&lt;/code&gt; directories.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/new_todo_form_directory_structure-749ce9005dbb178d7a4ae86071279722-a9b9a.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 129px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 122.48062015503875%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAYAAAD6S912AAAACXBIWXMAABYlAAAWJQFJUiTwAAADh0lEQVQ4y32VZ1caURCG+eP5FHOOOScmaiyxIBbEoNhQI1IVkM6ygFJEinQ15i+8mZnN4gKaD7P3bnvvlOfONVVuglBi5+AxdX2GRPgEd/kr/DragOtkCyGfA9GrI+zvLCEWPIbLuYUr9y7OjzcRuLAjHnLCd/4T8aATvUYKplrxGsVsALeKD4f2VRztrsq9c38NCzOfsGWehm19Fid0v2dbxPL8JNaXp3B6YIF9ax7He2b5hx14bCowtasJdOsptO7jaJSjYvzssZkRe+nm0H9Q0G+kxQOe8/ePNPboGc/1d6xh4gsL1EsRsLeNcgTVQlju2TgdPPI3vFi9dC3zZiUuAkbj5yLIq9xmfPJzNnlB+VqG07GGHM3npydgty5Q+BOYm/6ITfM3yR1736zExgX5ot+wcDl3KQlWE248kBf5tFc85uSnIlS00AluFK98qwsaNUyjbndqScpTBr37EDolrzbWEpJLo/G3fclhciA2EDSuwGPznl4WfeioDvRVG8L+Q3jOtmHb+A7Hzg+4T63IJi6kuhyRUXRIcGDVFAmSd5EZPKbMiIXPcEnsbRM+O5tzhNeK5NG6NoOi6h9QMpRDDpVf6K532GqERFPFcyuD57aK3+0s/vTyEjLnr0ff839jIfPDym1QgOYC3FAhCrQyz3mnBL0OZIgAhj9EczXhEsHRVA1hU1QDyKU8UOMuOGxLON23EDZuCdNCO2NpbhLLC58xNflBwmbM9Ny9iQ17yeSzV3kSLuWuKJda2A93UYH+/jYkxqAbGRzz0FgURqTboG11FyBsfGiX/JTPOJ5aKpmWy5dO7h9eylBB3sWmVU0KNt2kBU+KBV6XnXaOWXbNCoXNO4c70NrSFxQk9NT7HrZ1QfKsm1hBP2OjInikrXHLYgYZmbD/QDrQGIe6WFdyqGEzQKhOoTezhIsq4XG4euj8XhvfwYZXyqc90ly50SrRcypAkLwwC9RchFfTotHHsaLogswe87ZrXaScWVDOBwWbbcusVFeHeBSV/2Dzigj3xU4lTDmNCj76LuLvtDHxPtijq3TqaQ2Zghvdkoe8D8iZw+FWCyEZedFRsSEPx7ApBQSbZ8UM/8WeNFhuChurX+W84d3CFedzxNgXTbrywHTBMgkqVnRzh6iXY1SoU9rjHuku3GhDvn2ZG/P6pmBrIErzWlqsI4eWdihpB1VaTD+YjP//BR2oYz3FsKKRAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;New todo form directory structure&quot;
        title=&quot;&quot;
        src=&quot;/static/new_todo_form_directory_structure-749ce9005dbb178d7a4ae86071279722-a9b9a.png&quot;
        srcset=&quot;/static/new_todo_form_directory_structure-749ce9005dbb178d7a4ae86071279722-a9b9a.png 258w&quot;
        sizes=&quot;(max-width: 129px) 100vw, 129px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The code of the &lt;code class=&quot;language-text&quot;&gt;FilledIn&lt;/code&gt; state puts both of these pieces together to get a form that is capable of &lt;code class=&quot;language-text&quot;&gt;ADD&lt;/code&gt;ing a new item. However, because the &lt;code class=&quot;language-text&quot;&gt;Empty&lt;/code&gt; is not supposed to support adding new items, it simply skips the &lt;code class=&quot;language-text&quot;&gt;ADD&lt;/code&gt; action handler:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// main/Components/NewTodoForm/Empty/index.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;makeBinding&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./../lib/form&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeBinding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;makeBinding&lt;/code&gt; factory looks almost like a regular node binding, except for the &lt;code class=&quot;language-text&quot;&gt;({ADD})&lt;/code&gt; part. It&apos;s a higher order function that takes the &lt;code class=&quot;language-text&quot;&gt;ADD&lt;/code&gt; action handler so that it may be placed in the binding:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// main/Components/NewTodoForm/lib/form.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;makeBinding&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ADD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;dispatch&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  handler&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeHandler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token constant&quot;&gt;RENDER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;toNode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;input.new-todo&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        props&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          placeholder&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;What needs to be done?&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        hook&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          insert&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;elm&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; elm&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        on&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          keydown&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; key &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Enter&quot;&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toNode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ADD&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; undefined&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          input&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;target&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toNode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;TYPE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token constant&quot;&gt;TYPE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; arrow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;trim&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;changed&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;cleared&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; arrow&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        context&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token constant&quot;&gt;ADD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The handler of the &lt;code class=&quot;language-text&quot;&gt;ADD&lt;/code&gt; action is placed in the library as well:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// main/Components/NewTodoForm/lib/form.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;ADD&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  context&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;cleared&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  effect&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DISPATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;TODO_ADD&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;trim&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It clears the input by setting the context to &lt;code class=&quot;language-text&quot;&gt;{content: &amp;#39;&amp;#39;}&lt;/code&gt;, follows an arrow called &lt;code class=&quot;language-text&quot;&gt;cleared&lt;/code&gt; and dispatches a &lt;code class=&quot;language-text&quot;&gt;{type: &amp;#39;TODO_ADD&amp;#39;, content}&lt;/code&gt; action. This action is then consumed by the subgraph responsible for handling the list of items.&lt;/p&gt;
&lt;h2&gt;Working with a big context object&lt;/h2&gt;
&lt;p&gt;Every Rosmaro model uses one big, global context object. It&apos;s very much like the global store in Redux (and that&apos;s why &lt;a href=&quot;https://github.com/lukaszmakuch/rosmaro-redux&quot;&gt;Redux is such a great environment to run Rosmaro models&lt;/a&gt;!). As we&apos;ve seen, from the form&apos;s perspective the context looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;What I am typing&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Does it mean there&apos;s no other data in the context? No, of course there is more data! The whole context looks actually like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  newTodoForm&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;What I am typing&apos;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  list&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    todos&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;zc&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;asdf&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    lastId&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The form may focus solely on its tiny part thanks to a lens attached to the &lt;code class=&quot;language-text&quot;&gt;NewTodoForm&lt;/code&gt; state. It selects a small slice of the whole object (&lt;code class=&quot;language-text&quot;&gt;newTodoForm&lt;/code&gt;) and in case there&apos;s no such property, it provides an initial value (&lt;code class=&quot;language-text&quot;&gt;{content: &amp;#39;&amp;#39;}&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// main/Components/NewTodoForm/index.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; opts &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  lens&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;compose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;sliceLens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;newTodoForm&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;initialValueLens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  handler&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; transparentHandler&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What sets lenses apart from Redux selector is that they work in both ways, not only zooming in to focus on a small part, but also zooming out to allow updates of the original, big object. This is how the form may not only read &lt;code class=&quot;language-text&quot;&gt;context.content&lt;/code&gt;, but also update &lt;code class=&quot;language-text&quot;&gt;context.content&lt;/code&gt; without being aware it&apos;s actually &lt;code class=&quot;language-text&quot;&gt;context.newTodoForm.content&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you&apos;d like to learn more about Ramda lenses, I strongly recommend checking out &lt;a href=&quot;https://ramdajs.com/docs/#lens&quot;&gt;the chapter on lenses in the official Ramda documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;List filtering&lt;/h2&gt;
&lt;p&gt;Another aspect that in my opinion deserves attention is how does the filter work. Usually todo apps relay on some form of a filter function that discards all the entries that don&apos;t match the current filter status. There&apos;s nothing wrong with this approach! However, in order to demonstrate that there are also other ways, this implementation uses &lt;code class=&quot;language-text&quot;&gt;map&lt;/code&gt; instead of &lt;code class=&quot;language-text&quot;&gt;filter&lt;/code&gt;. Both &lt;code class=&quot;language-text&quot;&gt;Completed&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Active&lt;/code&gt; items are difned with a list of states in which they should be rendered:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// main/Components/List/View/child/Active/index.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeBindings&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  renderWhen&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;all&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Their &lt;code class=&quot;language-text&quot;&gt;RENDER&lt;/code&gt; handler is a bit different than in the case of the other nodes. Instead of simply returning a VDOM node, it returns an object with keys corresponding to all the possible states of the filter. For example, the &lt;code class=&quot;language-text&quot;&gt;Active&lt;/code&gt; node renders in the following way:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    completed&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;
    all&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; renderedItem&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    active&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; renderedItem
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Navigation states don&apos;t only render a bunch of buttons, but also pick a specific key from the object returned by each item. In this case, it&apos;s &lt;code class=&quot;language-text&quot;&gt;active&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// main/Components/Controls/Navigation/Buttons/Active/index.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeBinding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selected&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  buttons&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    allTodosButton&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; allTodosButton&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;notSelected&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    completedTodosButton&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; completedTodosButton&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;notSelected&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    activeTodosButton&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; activeTodosButton&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selected&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;makeBinding&lt;/code&gt; factory looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// main/Components/Controls/Navigation/Buttons/lib/templates.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;makeBinding&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;selected&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; buttons&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;allTodosButton&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; completedTodosButton&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; activeTodosButton&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  handler&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeHandler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token constant&quot;&gt;NAVIGATE_TO_ALL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;navigated to all&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;NAVIGATE_TO_COMPLETED&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;navigated to completed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;NAVIGATE_TO_ACTIVE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;navigated to active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;token constant&quot;&gt;RENDER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; children&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      ui&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;ul.filters&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        allTodosButton&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        completedTodosButton&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        activeTodosButton
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      selectTodos&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;selected&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What&apos;s important to note is that the &lt;code class=&quot;language-text&quot;&gt;RENDER&lt;/code&gt; handler returns both the &lt;code class=&quot;language-text&quot;&gt;ui&lt;/code&gt; and a &lt;code class=&quot;language-text&quot;&gt;selectTodos&lt;/code&gt; function that selects one particular key from every object on the list. That way, when both &lt;code class=&quot;language-text&quot;&gt;Navigation&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;List&lt;/code&gt; are rendered, the &lt;code class=&quot;language-text&quot;&gt;map&lt;/code&gt; fuction provided by &lt;code class=&quot;language-text&quot;&gt;Navigation&lt;/code&gt; is applied to the list of items returned by &lt;code class=&quot;language-text&quot;&gt;List&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;List events&lt;/h2&gt;
&lt;p&gt;So far we&apos;ve seen how various parts of the application react to events related to the list of items. For example, the &quot;Clear completed&quot; button disappears, when there are no completed items. But where do messages like this come from?&lt;/p&gt;
&lt;p&gt;Events like &lt;code class=&quot;language-text&quot;&gt;ALL_TODOS_COMPLETED&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;SOME_TODOS_COMPLETED&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;NO_TODOS_COMPLETED&lt;/code&gt;, and &lt;code class=&quot;language-text&quot;&gt;NO_TODOS&lt;/code&gt; are dispatched by the &lt;code class=&quot;language-text&quot;&gt;List&lt;/code&gt; node. Every time an action that may cause a transition reaches one of the item nodes, the parent of all of them asks its children their current state. It does it by dispatching a &lt;code class=&quot;language-text&quot;&gt;GET_STATE&lt;/code&gt; action to its children. It doesn&apos;t directly read their state, because it&apos;s considered an implementation detail and may be actually quite complex. In fact, an item may not only be &lt;code class=&quot;language-text&quot;&gt;Active&lt;/code&gt;, but also in the &lt;code class=&quot;language-text&quot;&gt;Editing&lt;/code&gt; state with the form being &lt;code class=&quot;language-text&quot;&gt;FilledIn&lt;/code&gt;. All these detail don&apos;t really matter from the point of view of the &lt;code class=&quot;language-text&quot;&gt;List&lt;/code&gt;, which expects either just &lt;code class=&quot;language-text&quot;&gt;active&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;completed&lt;/code&gt;. It&apos;s a bit like in &lt;code class=&quot;language-text&quot;&gt;Java&lt;/code&gt; where it&apos;s a good practice to use a getter method instead of directly accessing object properties, because the internal property may change, be calculated on the fly or the read operation may be delegated to some other object:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// main/Components/List/View/index.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; getStateAction &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET_STATE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;readStats&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; children&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; childrenResults &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;callChildren&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; children&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; getStateAction&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    values&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;data&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;soFar&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;soFar&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; soFar&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;active&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; completed&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;childrenResults&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;buildEffects&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; stats &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stats&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;completed &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;stats&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;active&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DISPATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ALL_TODOS_COMPLETED&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stats&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;completed&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DISPATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;SOME_TODOS_COMPLETED&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stats&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;active&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DISPATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;NO_TODOS_COMPLETED&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;DISPATCH&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;NO_TODOS&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

&lt;span class=&quot;token constant&quot;&gt;DISPATCH_EVENTS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; children&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; stats &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;readStats&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; children&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; effect &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;buildEffects&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stats&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;effect&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;DISPATCH_EVENTS&lt;/code&gt; handler uses the &lt;code class=&quot;language-text&quot;&gt;readStats&lt;/code&gt; function to call the children, get stats in the form of an object like &lt;code class=&quot;language-text&quot;&gt;{active: 3, completed: 8}&lt;/code&gt; and pass them to the &lt;code class=&quot;language-text&quot;&gt;buildEffects&lt;/code&gt; function in order to get effect objects describing the current state of the list, like &lt;code class=&quot;language-text&quot;&gt;SOME_TODOS_COMPLETED&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Routing&lt;/h2&gt;
&lt;p&gt;The last part I&apos;d like to show you is the routing. It uses &lt;a href=&quot;https://github.com/krasimir/navigo&quot;&gt;Navigo&lt;/a&gt; to associate callback functions with routes. Every time a route is visited, it dispatches an action:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// app.js&lt;/span&gt;
router
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dispatchFn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;NAVIGATE_TO_ALL&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dispatchFn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;NAVIGATE_TO_ACTIVE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/completed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dispatchFn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;NAVIGATE_TO_COMPLETED&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The UI renders ordinary links:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// main/Components/Controls/Navigation/Buttons/lib/templates.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;notSelectedButton&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;li&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;a&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;href&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Because in this simple app every filter may be accessed at any time, all three navigation actions are supported in every state of the app:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// main/Components/Controls/Navigation/Buttons/lib/templates.js&lt;/span&gt;

&lt;span class=&quot;token constant&quot;&gt;NAVIGATE_TO_ALL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;navigated to all&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token constant&quot;&gt;NAVIGATE_TO_COMPLETED&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;navigated to completed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token constant&quot;&gt;NAVIGATE_TO_ACTIVE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;navigated to active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As mentioned in the previous post, entry points are used to mitigate state explosion. You can read more about entry points in &lt;a href=&quot;https://rosmaro.js.org/doc/&quot;&gt;the documentation of Rosmaro&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/navigation_buttons_graph-39208077ed3923b11db776b23c21aa8c-a9bfe.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 553px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 33.45388788426763%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABHElEQVQoz3WQzaqCUBSFfS8ngo4E8Q18DmfOGjtt6hv4CA3DQCjxLxAilFKJ0ghFc132ieO9t2iBeNzr7G+vrTBNE0hN0yBNU0RRhPP5zGrk0TmOY2y3W4RhiDzPMY4j8263G4qiQF3X6Pue9QjP55MdXNeFpmmQJAmLxYI1dF0H27ah6zpEUYSqqrAsC/f7ncENw4Asy1AUBcvl8gXk03ia/X4PGsKTk09gSn+9Xtk3iRKdTif4vo8gCNC27QuIP3o8HjgcDvO6HEqiJgJzj6uqKpaY1wXTNNmky+WC9XqNzWbzAUySBKvVCp7nzc08Jd2n9DPQcRx2iSIfj0eUZTmD+JtWpR9PzzAM/zba7XbIsuwXiC96h7573+o/dSgDEbmg8KsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Navigation graph&quot;
        title=&quot;&quot;
        src=&quot;/static/navigation_buttons_graph-39208077ed3923b11db776b23c21aa8c-a9bfe.png&quot;
        srcset=&quot;/static/navigation_buttons_graph-39208077ed3923b11db776b23c21aa8c-a7224.png 300w,
/static/navigation_buttons_graph-39208077ed3923b11db776b23c21aa8c-afc5a.png 600w,
/static/navigation_buttons_graph-39208077ed3923b11db776b23c21aa8c-a9bfe.png 1106w&quot;
        sizes=&quot;(max-width: 553px) 100vw, 553px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h2&gt;Coming soon&lt;/h2&gt;
&lt;p&gt;Thank you for reading this post! In the next part we&apos;re gonna focus on the test suite powered by &lt;a href=&quot;https://github.com/lukaszmakuch/rosmaro-testing-library&quot;&gt;rosmaro-testing-library&lt;/a&gt;, &lt;a href=&quot;https://github.com/dmitry-zaets/redux-mock-store&quot;&gt;redux-mock-store&lt;/a&gt;, and &lt;a href=&quot;https://github.com/lukaszmakuch/snabbdom-testing-library&quot;&gt;snabbdom-testing-library&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can find &lt;a href=&quot;https://github.com/lukaszmakuch/todomvc-rosmaro&quot;&gt;the complete code of this app&lt;/a&gt; on GitHub.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Decomposing the TodoMVC app with state diagrams]]></title><link>https://coder.earth/post/decomposing-the-todomvc-app-with-state-diagrams</link><guid isPermaLink="false">https://coder.earth/post/decomposing-the-todomvc-app-with-state-diagrams</guid><pubDate>Sun, 13 Jan 2019 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;Most probably you&apos;ve already heard about &lt;a href=&quot;http://todomvc.com&quot;&gt;TodoMVC&lt;/a&gt;. Its purpose is to demonstrate how a to-do list may be implemented in various frameworks and languages.&lt;/p&gt;
&lt;p&gt;In this post, we&apos;ll identify verious states of this famous demo app. As it turns out, they are not only helpful to understand the requirements, but may also be used to actually implement the application!&lt;/p&gt;
&lt;p&gt;Let&apos;s start!&lt;/p&gt;
&lt;p&gt;When there are no items, only the form is visible.
But as soon as there&apos;s at least one item, the list and the controls become visible.
We can recognize different layouts and components. Here&apos;s what it looks like:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/layouts-0d5ae07fa6a178bf22a1d987c226cd41.gif&quot; alt=&quot;Different app layouts&quot;&gt;&lt;/p&gt;
&lt;p&gt;There are two layouts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;just the form&lt;/li&gt;
&lt;li&gt;the whole app&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They are represented as a graph:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/layout_graph-670792bd1d93696ea5a40cc5c8284590-3d130.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 497px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 51.10663983903421%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABJElEQVQoz41Ty6qDQAyd3/Fj/E4/QbCbIoKCYqFKFz5w46tWXPisoKYkMGX0Xq73QMbBZE7OJBkGB2zbttv/x8RYhouqqqAoCkzTRM51XXfEZxBj2TAMIMsySJIErut+HUiK1nUdJXq/39D3PYzjCHhmnmfacxGclOFSliUkSQJVVUEcx5Bl2Zc0TVP65zgORFFEviAIKPnz+YS6rndK2fFqmNH3fdB1nVQ0TQOPx4MUikAiLFXbtnQL7mfi9dA4DMOgA5fLBW63Gx3A5MuykP/1esH1eqU40zQpKSkUOyTWAhWgeZ4Hmqb9aAQqsywLwjAkMl4mdtY1BNbxfr9DURSkLM9zsG2bSI9gR6LjXPGSYMOQiDcCv7/NKjubrb/m8fgIEB+utv42rEjDxQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Layouts&quot;
        title=&quot;&quot;
        src=&quot;/static/layout_graph-670792bd1d93696ea5a40cc5c8284590-3d130.png&quot;
        srcset=&quot;/static/layout_graph-670792bd1d93696ea5a40cc5c8284590-ac599.png 300w,
/static/layout_graph-670792bd1d93696ea5a40cc5c8284590-51d1b.png 600w,
/static/layout_graph-670792bd1d93696ea5a40cc5c8284590-3d130.png 994w&quot;
        sizes=&quot;(max-width: 497px) 100vw, 497px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;We have three main components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the new todo form&lt;/li&gt;
&lt;li&gt;the list of todos&lt;/li&gt;
&lt;li&gt;all the various controls&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because they are simultaneously active and we never switch from one component to another, they are represented as three orthogonal regions:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/components_graph-22e806363c50367ac5094837e859c33f-727e7.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 279px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 108.6021505376344%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAWCAYAAADAQbwGAAAACXBIWXMAABYlAAAWJQFJUiTwAAABuklEQVQ4y61UZ4vCQBTM//81gmAQS7DE3hXEjqhYUGzgB9sc87iVPUvcwC0MW7KZfWXes/A77vf7Y77dbkbQ/1FrC9pQh36GTvqHUB1cLhcMBgP0+330ej2MRiPZcz0cDgX81ul0sN1uXwx5IUwmk4JarYZms4l0Oo1SqYRGo4FsNot8Po96vS6wbRuHw+GzhUQkEsF4PEYwGITruigUCjKHw2HEYjEh4iO0muS86+lyKBTCYrEQl4j5fC5ut9ttTKdT2dPtzWYjj3PvScifotEoMpmMWEb3U6nUY03Qwng8jmq1+v9Z/poUXYcq68vlUrBer1/ufJTNuxev1yscxxEXK5XKRzf14Um42+1EGvv9HrlcDpPJRDKtrPdNSOFSLqvVSpI0m80kYc9uehLqrnBOJBIiD2aZkmq1WvJNxe+Z1PKqTb0cz+ezxFQne2el9U0GpnL5auHpdJLsMnYE61jNDMPxeDSzULnFhkBClhxLkM2C6263K4R6LI0IaQmJ2LaoP8qGZ9QlNUlyI0J1gQ2AWS2XyygWi0LCmd0mEAhIwzAifNYhO48Odhe9sfqSjd8MG+nQC++IfwCHXpJNuHjoJAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Components&quot;
        title=&quot;&quot;
        src=&quot;/static/components_graph-22e806363c50367ac5094837e859c33f-727e7.png&quot;
        srcset=&quot;/static/components_graph-22e806363c50367ac5094837e859c33f-1763f.png 300w,
/static/components_graph-22e806363c50367ac5094837e859c33f-727e7.png 558w&quot;
        sizes=&quot;(max-width: 279px) 100vw, 279px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;In our implementation, on the highest level, the TodoMVC app consists of two orthogonal regions, that is a layout and a bunch of components.&lt;/p&gt;
&lt;p&gt;In the editor, they look similar to the components, because they are also orthogonal regions:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/main_graph-54ba72542cbcda16d8082c8d340b9b7d-148ec.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 264px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 42.803030303030305%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA5UlEQVQoz61RywqDQAz0/39J9OD77UXEtxcFL3pVBE2ZFLdVaqHQwOzmMROSXYn+bBKOfd9p27YTkLurfcLBlw7nk32r3fF5wnEcqSxLatuWUVUVDcMgiIgdx6EoihhhGArf931KkoSnFCsrisKkOI4FWZZlmueZoaoqNy2KgtE0DQ+QZRn7pmlS3/fPhuu6km3blOc5Cy3LojRNyXVdmqaJG2qaRnVdcw0cXddZgzgIAr67rntNCLFhGLwWVsAN0bEGRJgCNcDzvJOPhsuyvBrCkACONe8e/f3332PxKdfkVfwLYA9eK6ikTVdICAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Main regions&quot;
        title=&quot;&quot;
        src=&quot;/static/main_graph-54ba72542cbcda16d8082c8d340b9b7d-148ec.png&quot;
        srcset=&quot;/static/main_graph-54ba72542cbcda16d8082c8d340b9b7d-17721.png 300w,
/static/main_graph-54ba72542cbcda16d8082c8d340b9b7d-148ec.png 528w&quot;
        sizes=&quot;(max-width: 264px) 100vw, 264px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;This is the form used to add a new todo:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/new_todo_form-3d1bbccae78bd6742d51e716b07e1388-5fc3e.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 594px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 37.878787878787875%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAjklEQVQoz6WRWQpDIQxF3f9GHcDZ5wDCLUlr6c+z2AqHGEnMTSJaa6i1oveOMQaz3k6gnFIKBF7HWgvnHNs5J34513VBLGUpJYQQGKq21J5AfwhjDKSUUEpBa82QfwrlUYeCFNHlX7z3T4U0yDvWGGKMb7uL56XQIO/IOWN1QMuiArt4Xsqu2gr69L8pfACFMWfB5BwTOgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;New todo form&quot;
        title=&quot;&quot;
        src=&quot;/static/new_todo_form-3d1bbccae78bd6742d51e716b07e1388-5fc3e.png&quot;
        srcset=&quot;/static/new_todo_form-3d1bbccae78bd6742d51e716b07e1388-07eee.png 300w,
/static/new_todo_form-3d1bbccae78bd6742d51e716b07e1388-e1611.png 600w,
/static/new_todo_form-3d1bbccae78bd6742d51e716b07e1388-5fc3e.png 1188w&quot;
        sizes=&quot;(max-width: 594px) 100vw, 594px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;We are not allowed to add a new, empty todo. In other words, the behavior of an empty form differs from the behavior of a filled-in form. In order to be able to assign adding a todo only to a filled-in form, we model this form as a graph with two states:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/new_todo_form_graph-1bf76a893933bf76f8c5a002807a125b-322db.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 512px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 85.15625%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAABYlAAAWJQFJUiTwAAABrUlEQVQ4y6WUyY4CMQxE8338GVf+gyOcERdOIA6A2MS+7/sOHj1LbmWaZmakidRKOu2Uy67qOAmN1+ul8/V6ldFoJNPpVJ7PZ2RM1HDhQAseDAZyPB7lcDhIvV6X/X4v9/tdHo/Hj6AuKjOHZ7OZrgFotVpSq9Wk0Wgo838BWrnM/X7/7wz9cne7naxWq2DfQLfbrSwWi78ztIMw2Ww2b8Hr9Tpg/hHQmFkALHK5nBQKBVkul3I+nxUIkVDdL9k/Z3MAaIGVSkXS6bRkMhnJ5/PSbDaVrX2PspkP6nzq8/lcyuWydLtd6fV6QZl40R/YaTgc6rewoEEPEQJb0EfYWK8Y7XZbSqWSCsI+5d9uNyXA2gd1lBSLxSSRSHzLRCBG5p1k4/FYgekjfTYSxWJR24RXiXeUE4/HJZvNBkZmYBsr1ZLAEAcglO8KfEsLPhqbwE6nI9VqVUs9nU66jziwsRhfTCogztmmZfNVY0wmE32IYT+VSkWqDUPEcp9uEX9NzzgAu2Qyqf81SWgBj91KbyWHwcJsERAwWoHC3EQku1wu0b/eb2wpGxAs88ngX1c9I5PZTGkxAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;New todo form&quot;
        title=&quot;&quot;
        src=&quot;/static/new_todo_form_graph-1bf76a893933bf76f8c5a002807a125b-322db.png&quot;
        srcset=&quot;/static/new_todo_form_graph-1bf76a893933bf76f8c5a002807a125b-ae7d7.png 300w,
/static/new_todo_form_graph-1bf76a893933bf76f8c5a002807a125b-373c0.png 600w,
/static/new_todo_form_graph-1bf76a893933bf76f8c5a002807a125b-322db.png 1024w&quot;
        sizes=&quot;(max-width: 512px) 100vw, 512px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Only the &lt;code class=&quot;language-text&quot;&gt;FilledIn&lt;/code&gt; one actually adds todo items, while the &lt;code class=&quot;language-text&quot;&gt;Empty&lt;/code&gt; one never does it.&lt;/p&gt;
&lt;p&gt;There&apos;s a checkbox on the left side of the form:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/mark_all-e5697e908464d535264b5f5aec443e64.gif&quot; alt=&quot;The &amp;#x22;mark all as completed&amp;#x22; checkbox&quot;&gt;&lt;/p&gt;
&lt;p&gt;When all items are completed, it&apos;s checked and clickig it marks all the items as active.&lt;/p&gt;
&lt;p&gt;When not all items are completed, it&apos;s unchecked and clicking it marks all the items as completed.&lt;/p&gt;
&lt;p&gt;It&apos;s something that may be expressed as a graph:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/mark_all_graph-adeae83b23e39dd6faeb855ed6b375b5-0aa9f.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 356px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 67.13483146067416%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAABeUlEQVQ4y52S2c7BUBSF+y4ewNvxLK5cc+nWhbEIDWKoRIKEFBFDEWJef9ZOdtOWC/6dnO4z9TtrD8br9ULYPu19awY/9XodsVgMiUQCp9PJg/4HLMB4PI5IJIJoNIrJZCIHj8cjAOZ4Pp/e0LU+ql6Ay+USqVQKmUwG8/n859D994zwT8PhEOPxGJfLRdaO42A2m2Gz2cicEYxGI7iui+l0ivV6/a6Q0jXE2+2GWq0mYNpisRBQpVJBv9+Xx7rdLprNpjy02+0CSg0/3V8Ihp/L5WTe6XQCqaBZloV0Oi1CqFIFGX66wnghn8+jWCyKkmq1Kqq1A47HI9rtNkqlElqtlswHg0EQqKFrkQqFAhqNhnjCs9kszueznB8OBwGZpinn5XJZ0vAGVIWUv9/vRcn1ekUymfTaSY0F6fV6uN/v3r03YLgFCKYa5o9qmYrtdiuFYQqomHuq3CtKGKaeL7NFqI5V55yeRWLOVqsVbNsOtI7xTbP+0tx/2gHZup3kfLwAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The &quot;mark all as completed&quot; checkbox&quot;
        title=&quot;&quot;
        src=&quot;/static/mark_all_graph-adeae83b23e39dd6faeb855ed6b375b5-0aa9f.png&quot;
        srcset=&quot;/static/mark_all_graph-adeae83b23e39dd6faeb855ed6b375b5-a5099.png 300w,
/static/mark_all_graph-adeae83b23e39dd6faeb855ed6b375b5-a7c06.png 600w,
/static/mark_all_graph-adeae83b23e39dd6faeb855ed6b375b5-0aa9f.png 712w&quot;
        sizes=&quot;(max-width: 356px) 100vw, 356px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;In the bottom right corner of the app there&apos;s a button that appears only when there&apos;s at least one completed item.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/clear_completed-ecd4adce8c22ab6e90e19966653f7451.gif&quot; alt=&quot;The &amp;#x22;clear completed&amp;#x22; button&quot;&gt;&lt;/p&gt;
&lt;p&gt;Clicking it removes all the completed items.&lt;/p&gt;
&lt;p&gt;In the &lt;a href=&quot;https://rosmaro.js.org/editor&quot;&gt;Rosmaro editor&lt;/a&gt; it looks like this:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/clear_completed_graph-1cac2283e5b3f1fc3d4f624c45ad9588-14c01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 506px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 53.55731225296443%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABZklEQVQoz42SSarCQBCGc4vcxcN4m4BnkKzdeYK4EaNBNM5xSBQn0KxExUXi9L/3N3Tb0ffAhqKnr6v+qi4Dv2MwGMBxHByPR27xfD7V/K1J3phMJsjlcjBNE5ZliYv7/a6gb4fkDaoqFArI5/Mol8vi8PF4CIBzkiRqfb1ehaVpKrjb7abulUI9yna7xXA4FArlnhl0Oh20Wi1EUYR+vw/P88TZcrnEfD5XGQmHMjpnXhCsVCoqyG63w2g0wuVyUeUgH8cxGo0G9vt9JnVDSiXEwZRs20YQBOj1eqjVah91kmy73UapVMJmsxGZnE6nl0MJHw4HAdbrdbiuK0A9oL6mOqon5/s+wjB81VA6pELWar1eo9lsolgsZhTqwclUq1UsFgtMp1Ocz+fsp7y3CpWMx2PMZjP1s5KjM57zp/V3Hwp1BWwpPqJSGlNiOVhXfshqtUK32/2/bf5yLltIKn7f67Wl/QANCz6e4Q64zgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The &quot;clear completed&quot; button&quot;
        title=&quot;&quot;
        src=&quot;/static/clear_completed_graph-1cac2283e5b3f1fc3d4f624c45ad9588-14c01.png&quot;
        srcset=&quot;/static/clear_completed_graph-1cac2283e5b3f1fc3d4f624c45ad9588-5e740.png 300w,
/static/clear_completed_graph-1cac2283e5b3f1fc3d4f624c45ad9588-4bbe0.png 600w,
/static/clear_completed_graph-1cac2283e5b3f1fc3d4f624c45ad9588-14c01.png 1012w&quot;
        sizes=&quot;(max-width: 506px) 100vw, 506px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Below are all the possible states of the filter:

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/navigation_button_all-fc72b56d4e84b76e1536323726356916-ea972.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 240px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 21.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAgklEQVQY022MyQ7DIAxE+f9PJMeUTaQCbuxToARRNZae7LHHQ2qtqGhVKt7XBaVUmwuccxBCQEoJzjle5wnGGErOiCGMW0drjZ7Rq3eyRAtJzRi9R21PeT6GphfBD1/p3pQQYxz8BBpjcGMnS1v7x9N+zyCUUiyO48s977fd87SffACSPy6g85NZaAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;&quot;All&quot;&quot;
        title=&quot;&quot;
        src=&quot;/static/navigation_button_all-fc72b56d4e84b76e1536323726356916-ea972.png&quot;
        srcset=&quot;/static/navigation_button_all-fc72b56d4e84b76e1536323726356916-09b0c.png 300w,
/static/navigation_button_all-fc72b56d4e84b76e1536323726356916-ea972.png 480w&quot;
        sizes=&quot;(max-width: 240px) 100vw, 240px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/navigation_button_completed-567210d3d1dcd7cb181b494ed36d40ab-ea972.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 240px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 21.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAgklEQVQY03WO2wrDIBBE/f9PTB7FC0qqfUm8T9eFhDY0wnF0Z0YUoDXGmILXtsE5x+d3jDDGwFoLrRSklFCkvRTknNkzWsN7f/Wnirmdg9YaM3pHo2JJCWnfmXwczCC/k19rRZkZ4ufBEAJOIv1qct2/Zswtd89PxLIs+Mu6PvPUIT6XIy6mkk41IgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;&quot;Completed&quot;&quot;
        title=&quot;&quot;
        src=&quot;/static/navigation_button_completed-567210d3d1dcd7cb181b494ed36d40ab-ea972.png&quot;
        srcset=&quot;/static/navigation_button_completed-567210d3d1dcd7cb181b494ed36d40ab-09b0c.png 300w,
/static/navigation_button_completed-567210d3d1dcd7cb181b494ed36d40ab-ea972.png 480w&quot;
        sizes=&quot;(max-width: 240px) 100vw, 240px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/navigation_button_active-44dda41897747614884b20c815697e66-ea972.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 240px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 21.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAg0lEQVQY05WOyQoDIRBE/f9PdK5uGFCZw4x7xZYYZHJKw6MLu6qQYUzvnRacc7DWTn2eJ7TWMMZAKQUhBKSU6K0hXte80ftr+FvOM0MtjMpWYa0VpZSp2wiSTilN8ggRw4xKOkYk4r7RRm59jHnvsQghTHb95Ovd2DsY5xx/cxy/fG5vqrUutD6tq0UAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;&quot;Active&quot;&quot;
        title=&quot;&quot;
        src=&quot;/static/navigation_button_active-44dda41897747614884b20c815697e66-ea972.png&quot;
        srcset=&quot;/static/navigation_button_active-44dda41897747614884b20c815697e66-09b0c.png 300w,
/static/navigation_button_active-44dda41897747614884b20c815697e66-ea972.png 480w&quot;
        sizes=&quot;(max-width: 240px) 100vw, 240px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Because it&apos;s totally possible to navigate from any of the states to any other state, the graph uses entry points in order to avoid state explosion:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/navigation_buttons_graph-39208077ed3923b11db776b23c21aa8c-a9bfe.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 553px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 33.45388788426763%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABHElEQVQoz3WQzaqCUBSFfS8ngo4E8Q18DmfOGjtt6hv4CA3DQCjxLxAilFKJ0ghFc132ieO9t2iBeNzr7G+vrTBNE0hN0yBNU0RRhPP5zGrk0TmOY2y3W4RhiDzPMY4j8263G4qiQF3X6Pue9QjP55MdXNeFpmmQJAmLxYI1dF0H27ah6zpEUYSqqrAsC/f7ncENw4Asy1AUBcvl8gXk03ia/X4PGsKTk09gSn+9Xtk3iRKdTif4vo8gCNC27QuIP3o8HjgcDvO6HEqiJgJzj6uqKpaY1wXTNNmky+WC9XqNzWbzAUySBKvVCp7nzc08Jd2n9DPQcRx2iSIfj0eUZTmD+JtWpR9PzzAM/zba7XbIsuwXiC96h7573+o/dSgDEbmg8KsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Navigation&quot;
        title=&quot;&quot;
        src=&quot;/static/navigation_buttons_graph-39208077ed3923b11db776b23c21aa8c-a9bfe.png&quot;
        srcset=&quot;/static/navigation_buttons_graph-39208077ed3923b11db776b23c21aa8c-a7224.png 300w,
/static/navigation_buttons_graph-39208077ed3923b11db776b23c21aa8c-afc5a.png 600w,
/static/navigation_buttons_graph-39208077ed3923b11db776b23c21aa8c-a9bfe.png 1106w&quot;
        sizes=&quot;(max-width: 553px) 100vw, 553px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/navigation_graph-058fafb990af6d8358f04835ca2ea179-81cbe.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 580px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 81.37931034482759%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB1ElEQVQ4y31UV6oCQRDcf2/tGTyEB1AQEf0RMaAi5pyzmHOqRzX0Mq7uKxh6wk5Nd3X3WjDwfr/Fvl4vDIdDjMdjsZPJRPbMb2idg7Cch8RgMMB2u5X54/HAarVCq9XCbrezH9TBO2q/CIn9fi9ekWSxWJgByP5ms4EbyGHpQkPq9XooFos4nU5ot9tIJpOyHo1G6Pf7KJfLYuv1OiqVCmazGRqNhv24ZepCZDIZrNdrO9zz+SzE1WpV5txrNpvodruyPh6PEtX1ev0mvFwuCIfDqNVq4kGn07EH9xgy90mYSqXkIWrL8ZOQifD7/TgcDjLm8zny+bwkg54xVHp6u93EOxI/n085+0oKQZ1CoZDoUigUxDIJ9KRUKokn2WxWzgjqpvJoYi0zIbxAbRT0MBaLST2ylBSc8zLD1P0PD01CCqzwer3weDzw+XwiPiNQQpIx9H8JqZGKyzkzTgnoqUqihNSQ0fChD0KtdII1x2zG43FMp9OPomV9MiHMMuuSD2rnmGVnab3lcjnRKxKJIBqNYrlcyuVEIoFAIIBgMIh0Oi2ZZQWYPf0zZNYaPyYJvWNN8iKzSOvWas7WtUx3KfL9fnftVfOH8IvsZ+u5/ZqcJG74A6F6wQtiX68BAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Navigation&quot;
        title=&quot;&quot;
        src=&quot;/static/navigation_graph-058fafb990af6d8358f04835ca2ea179-81cbe.png&quot;
        srcset=&quot;/static/navigation_graph-058fafb990af6d8358f04835ca2ea179-f9bc6.png 300w,
/static/navigation_graph-058fafb990af6d8358f04835ca2ea179-134f0.png 600w,
/static/navigation_graph-058fafb990af6d8358f04835ca2ea179-81cbe.png 1160w&quot;
        sizes=&quot;(max-width: 580px) 100vw, 580px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Finally, we&apos;re getting closer to the most important part of the TodoMVC app, that is a todo.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/todo-245d2a2c0c286e4e8e1553654514ef04.gif&quot; alt=&quot;A single todo item&quot;&gt;&lt;/p&gt;
&lt;p&gt;It may be either active or completed:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/todo_graph-6b5f0acdfb6e607227ed8c49b23ccfff-1084a.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 543px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.036832412523026%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAABmElEQVQoz52SWYrCQBCGcwEP4Am8iK8ewCv44jU8ha85gg8KgluUEFFEiPuGGBcSiPv6z/wlHWSQwZmCSjddqaqv/m4N32bbNrLZLGazGf5qo9EIuVwuyNWm0ymi0SjC4TDi8bgEeEafTCaYz+cYj8fSVMW49vt9gYjFYgiFQpJ7Op2gPR4P6LqORCKBSqWCy+WC/X6Pw+EgfjwecT6fZVVndP6z3W5hGAbS6TRM03wS8pNMJhGJRKQwjU3+a1KQ6KlUCoPBIAiQiAQkoe92OxmJrpre73fcbjdcr1dZg4I8sCwrKLZcLlEul9HpdDAcDkUvik8t8/m8NPqVcLFYIJPJSEKhUMB6vQ46/jQS8lJ6vR48zxPNqTGd1Bo3vHaKyu6u60oix6Gr0dRe6UviarWKWq2GYrGIUqn0LMgO7XZb9Gs2m1itVh+JTwgW6na7aLVaUkMKMsjxSEotHceRILXjeOrJ8FK4JxnHpb6+70suoTiBaPjuiTChXq/LZfBxM5kUfOSNRgObzeYttRAqXV79E3vV9DXvC9xtfRQ7JosQAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A single todo item&quot;
        title=&quot;&quot;
        src=&quot;/static/todo_graph-6b5f0acdfb6e607227ed8c49b23ccfff-1084a.png&quot;
        srcset=&quot;/static/todo_graph-6b5f0acdfb6e607227ed8c49b23ccfff-04873.png 300w,
/static/todo_graph-6b5f0acdfb6e607227ed8c49b23ccfff-847df.png 600w,
/static/todo_graph-6b5f0acdfb6e607227ed8c49b23ccfff-1084a.png 1086w&quot;
        sizes=&quot;(max-width: 543px) 100vw, 543px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Both active and completed items may be edited.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/todo_editing-56ce029f8196180578243a34ea428aa4.gif&quot; alt=&quot;Editing todo items&quot;&gt;&lt;/p&gt;
&lt;p&gt;It indicates that they both have a subgraph saying that they are either being disaplyed or edited:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/active_or_completed_todo_graph-af5344c5c99deb8cb0b7e0dce0e70f20-818a7.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 416px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 53.605769230769226%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABSUlEQVQoz51Su66CQBDlM/g+/4CKT7KxsbGBwlejaEjQGEIDJCo+CAqKT+DczBg2YOH13k02u7Ozc87MmZHwyyqKAn/5I5FR7qqz+vZ4PJCmKe73Oy6XC9/Jdz6f8Xw+a3FSnudslOc7Aa3j8QjTNNHr9WDbNmazGSzLwmKxYIIa4KdSrtcrbrcbTqcTA8RxLHybzQaapnEiWZYJUKnVakFRFHZSMAVtt1tmHw6HmE6nMAwDg8EA+/1eABJJs9nEfD7nnSTJK8NGowFZlqGqKsIwhOu6nI2u6+h2u+j3+3xvt9sIgkAARlHEvslkwmS73e4FSKyj0UgwVFcpOAF1Op2aj3Qdj8ec9Xq9FmXXNCQ9qrsaTFlTY5bLJRzH4cZ4nieaIjQsRf00NqTrarXiRtDp+z4OhwPbZWVfdflfg/3Nx/c5fZ/Z6t8fqeVFshhJItIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A single todo item&quot;
        title=&quot;&quot;
        src=&quot;/static/active_or_completed_todo_graph-af5344c5c99deb8cb0b7e0dce0e70f20-818a7.png&quot;
        srcset=&quot;/static/active_or_completed_todo_graph-af5344c5c99deb8cb0b7e0dce0e70f20-e35e8.png 300w,
/static/active_or_completed_todo_graph-af5344c5c99deb8cb0b7e0dce0e70f20-deca6.png 600w,
/static/active_or_completed_todo_graph-af5344c5c99deb8cb0b7e0dce0e70f20-818a7.png 832w&quot;
        sizes=&quot;(max-width: 416px) 100vw, 416px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;An attempt to change the content of an item to an empty value actually removes this item instead of just updating its content:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/discarding_empty_todos-62348f2fdf56737a112f5d0d96843dce.gif&quot; alt=&quot;Discarding&quot;&gt;&lt;/p&gt;
&lt;p&gt;This difference in behavior is visible in the graph represending an item that&apos;s being edited.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/todo_editing_graph-ac0401f4dcd3179f03459635a87407e0-78701.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 495px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 73.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABYlAAAWJQFJUiTwAAABjklEQVQ4y5WTyY7CQAxE+6f4Un6FAzcOwIETAiG2AyCx7/u+ePQsOTLJIGYstZJ0V8pllzuIi9frFb3vdjs5Ho/R/vP5jM49Lh7BkxlwMpnIdDqV2Wwmi8VCPiX9Skicz2cZj8f6frlcpFqtSrPZlOFwqN//UkicTidVR9xuN12r1Uq63W6iko+EHrRcLuVwOCSAlL7f7/+ukKYTg8FArtdrArjdbrWnhjURcaOC30RBoVCQSqWiZVMuTo9GI13e6biZEaFnx91sNiv5fF6f5XJZe/d4PN5IMAeTNptNsmTPDrBUKqkaC8pstVrqPmrv97u2BfX0tdPpaEK+4Qm+f7iJSkjMGAacnyBFFW2xXiKA/Xa7rUkiheZuLpdTJWT0Km0+UQTObpAJIbnhg22m02lJpVKajajX69Lr9VSNYTCKPW+Gnc3ncyV+U9hoNLRHKKQ0QNwSmz8ik8n8OqcoRHn4Nqg0G2L6WCwWdQK4juv1WhVD5B0PfjDjA+sTcdbv96VWq+li0LkAVGRlg/8Bhs2GlCv7iM8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Editing a todo item&quot;
        title=&quot;&quot;
        src=&quot;/static/todo_editing_graph-ac0401f4dcd3179f03459635a87407e0-78701.png&quot;
        srcset=&quot;/static/todo_editing_graph-ac0401f4dcd3179f03459635a87407e0-91581.png 300w,
/static/todo_editing_graph-ac0401f4dcd3179f03459635a87407e0-1ec04.png 600w,
/static/todo_editing_graph-ac0401f4dcd3179f03459635a87407e0-78701.png 990w&quot;
        sizes=&quot;(max-width: 495px) 100vw, 495px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;These are all the states that matter from the point of our implementation!&lt;/p&gt;
&lt;p&gt;Check out &lt;a href=&quot;https://coder.earth/post/an-overview-of-the-rosmaro-todomvc-app-codebase&quot;&gt;the next part&lt;/a&gt; to see the code associated with the nodes visible above.&lt;/p&gt;
&lt;p&gt;If you&apos;d like to simply browse the whole code, just visit &lt;a href=&quot;http://github.com/lukaszmakuch/todomvc-rosmaro&quot;&gt;the GitHub repository of the Rosmaro-TodoMVC app&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[A comparison of dispatch management solutions: if, switch, object, automaton, multimethod]]></title><link>https://coder.earth/post/dispatch-management</link><guid isPermaLink="false">https://coder.earth/post/dispatch-management</guid><pubDate>Sun, 25 Nov 2018 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;Conditions are hard to implement. Fortunately, nowadays we have multiple ways of telling the computer which piece of code should be used. Some of these techniques are more appealing than the others, because they reflect the way we think about a particular problem.&lt;/p&gt;
&lt;p&gt;In this post, I&apos;d like to talk a bit about my favorite ways of picking the proper piece of code. These are the techniques that turned out to be extremely helpful over the course of my career. I&apos;ll focus on runtime polymorphism, that is the decisions made during the execution of a program, as opposed to the compile time polymorphism, that is the decisions made by the compiler or any other tool before the program is run. Because the thing I&apos;d mainly like to focus on is the mental model and not the details, for each dispatch management solution I&apos;ll use the language, library or framework that I think illustrates it best.&lt;/p&gt;
&lt;h2&gt;IF&lt;/h2&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/if-9d68a30545003e24eae4cea28a545d0a-eb7a6.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 317px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 157.72870662460568%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAgABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIDAQX/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAHuGyLGAytIqAf/xAAZEAEAAwEBAAAAAAAAAAAAAAABABAxAkL/2gAIAQEAAQUCWCwxhpXqg6r/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAXEAADAQAAAAAAAAAAAAAAAAABECAx/9oACAEBAAY/Asgsz//EAB0QAQACAQUBAAAAAAAAAAAAAAEAERAhMUFhcYH/2gAIAQEAAT8hUdLVEWoHsVhnHb7PJLVgwPUA2t4//9oADAMBAAIAAwAAABDjyzz/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAfEAEBAAICAQUAAAAAAAAAAAABEQAhEDFRYXGRobH/2gAIAQEAAT8QdCaKHfx4wYAuihmaIlLkhR2lFmAtC2uh/MT6CXT1T24+ucVHS+uOyp7HV4//2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;IF&quot;
        title=&quot;&quot;
        src=&quot;/static/if-9d68a30545003e24eae4cea28a545d0a-eb7a6.jpg&quot;
        srcset=&quot;/static/if-9d68a30545003e24eae4cea28a545d0a-c2524.jpg 300w,
/static/if-9d68a30545003e24eae4cea28a545d0a-eb7a6.jpg 317w&quot;
        sizes=&quot;(max-width: 317px) 100vw, 317px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;em&gt;IF&lt;/em&gt;s are about &lt;strong&gt;picking one of two predefined paths&lt;/strong&gt;: the one for &lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt; or the one for &lt;code class=&quot;language-text&quot;&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can define what&apos;s at the end of each path, but we can neither define more paths nor rename them.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/boolean-evaluation-c07b2a5406ad5f87b92fa6475ee3017e-8b75e.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 800px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 38.125%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAIABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAIF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAB25Cwf//EABcQAQEBAQAAAAAAAAAAAAAAAAAhAhL/2gAIAQEAAQUCrPSv/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFhAAAwAAAAAAAAAAAAAAAAAAABAh/9oACAEBAAY/Air/xAAZEAACAwEAAAAAAAAAAAAAAAABEQAhQTH/2gAIAQEAAT8hDvorYN3ER6p//9oADAMBAAIAAwAAABDwD//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABgQAQEBAQEAAAAAAAAAAAAAAAERAEEx/9oACAEBAAE/EPZAiELccoPEJqlo8Hf/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;An expression evaluated to a boolean value&quot;
        title=&quot;&quot;
        src=&quot;/static/boolean-evaluation-c07b2a5406ad5f87b92fa6475ee3017e-8b75e.jpg&quot;
        srcset=&quot;/static/boolean-evaluation-c07b2a5406ad5f87b92fa6475ee3017e-5df75.jpg 300w,
/static/boolean-evaluation-c07b2a5406ad5f87b92fa6475ee3017e-dcc9d.jpg 600w,
/static/boolean-evaluation-c07b2a5406ad5f87b92fa6475ee3017e-8b75e.jpg 800w&quot;
        sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The decision regarding the path to follow is made based on a Boolean value.&lt;/p&gt;
&lt;p&gt;In an editor, it may look like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; myBool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;myBool&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Executed if myBool is truthy.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Executed if myBool is falsy.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As we can see, the developer can associate some behavior with &lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt; and a different behavior with &lt;code class=&quot;language-text&quot;&gt;false&lt;/code&gt;, but they can&apos;t associate different behaviors with, let&apos;s say, &lt;code class=&quot;language-text&quot;&gt;4&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;2&lt;/code&gt;, and &lt;code class=&quot;language-text&quot;&gt;5&lt;/code&gt; using just one &lt;code class=&quot;language-text&quot;&gt;IF&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There are multiple ways to avoid &lt;em&gt;IF&lt;/em&gt;s. Some of them are covered in previous blog posts like &lt;a href=&quot;https://coder.earth/post/programming-without-boolean-values-todo-app&quot;&gt;Programming without boolean values: To-Do App&lt;/a&gt; and &lt;a href=&quot;https://coder.earth/post/less-if&quot;&gt;Unnecessary IF statements&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Switch&lt;/h2&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/switch-308f211e6073810277d0ad31ecfb4d0e-0b32a.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 677px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 73.85524372230428%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAQACBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe6gNqP/xAAZEAACAwEAAAAAAAAAAAAAAAAAARASIUH/2gAIAQEAAQUC6aNFY//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEABj8CX//EABsQAAICAwEAAAAAAAAAAAAAAAARATEQIXFB/9oACAEBAAE/IYuS1qyNLGdErzuP/9oADAMBAAIAAwAAABDjz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABwQAAIDAAMBAAAAAAAAAAAAAAEhABExEEFRYf/aAAgBAQABPxAiy6hgkH6g7A/QxBu6Y4uwPTWcf//Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Switch&quot;
        title=&quot;&quot;
        src=&quot;/static/switch-308f211e6073810277d0ad31ecfb4d0e-0b32a.jpg&quot;
        srcset=&quot;/static/switch-308f211e6073810277d0ad31ecfb4d0e-3ad9f.jpg 300w,
/static/switch-308f211e6073810277d0ad31ecfb4d0e-f4f5b.jpg 600w,
/static/switch-308f211e6073810277d0ad31ecfb4d0e-0b32a.jpg 677w&quot;
        sizes=&quot;(max-width: 677px) 100vw, 677px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;I believe that the difference between &lt;em&gt;IF&lt;/em&gt; and &lt;em&gt;Switch&lt;/em&gt; is so subtle, yet important, that it deserves a separate blog post - &lt;a href=&quot;https://coder.earth/post/if-vs-switch&quot;&gt;If vs. Switch&lt;/a&gt;. Long story short, &lt;em&gt;Switch&lt;/em&gt; is about &lt;strong&gt;matching the control value against multiple programmer-supplied values&lt;/strong&gt;, as opposed to always matching against just &lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is how it looks in an editor:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;loading&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;loaded&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Instead of casting &lt;code class=&quot;language-text&quot;&gt;state&lt;/code&gt; to either &lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;false&lt;/code&gt;, we match it against a set of possible options: &lt;code class=&quot;language-text&quot;&gt;loading&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;error&lt;/code&gt;, and &lt;code class=&quot;language-text&quot;&gt;loaded&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can add and remove custom branches with ease.&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;Switch&lt;/em&gt; may be simulated using multiple &lt;code class=&quot;language-text&quot;&gt;if else&lt;/code&gt; constructions, like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;loading&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;loaded&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A &lt;em&gt;Switch&lt;/em&gt; is degraded when it can be replaced by just one &lt;em&gt;IF&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;myValue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;myValue &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Object-oriented dispatch&lt;/h2&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/object-oriented-dispatch-3f4ccff38cb7cdb3774e499c9e10f434-3842d.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 636px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 94.33962264150942%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAATABQDASIAAhEBAxEB/8QAGAABAAMBAAAAAAAAAAAAAAAAAAECAwX/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAHu2zg2VEgkH//EABsQAAEEAwAAAAAAAAAAAAAAAAABAhARICFB/9oACAEBAAEFAuw7ZYmH/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAwEBPwEf/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAgEBPwEf/8QAFBABAAAAAAAAAAAAAAAAAAAAMP/aAAgBAQAGPwIf/8QAHRABAAIBBQEAAAAAAAAAAAAAAQARIRAgMUFRYf/aAAgBAQABPyFs+YNlmmSvO4I4gQy27P/aAAwDAQACAAMAAAAQsM8A/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAwEBPxAf/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAgEBPxAf/8QAGxABAAIDAQEAAAAAAAAAAAAAAQARECExUWH/2gAIAQEAAT8QYEeKSASWONgCG7xvwhFVe3ZR8gE9BiCImmABQax//9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Object-oriented dispatch&quot;
        title=&quot;&quot;
        src=&quot;/static/object-oriented-dispatch-3f4ccff38cb7cdb3774e499c9e10f434-3842d.jpg&quot;
        srcset=&quot;/static/object-oriented-dispatch-3f4ccff38cb7cdb3774e499c9e10f434-f1a1f.jpg 300w,
/static/object-oriented-dispatch-3f4ccff38cb7cdb3774e499c9e10f434-9110d.jpg 600w,
/static/object-oriented-dispatch-3f4ccff38cb7cdb3774e499c9e10f434-3842d.jpg 636w&quot;
        sizes=&quot;(max-width: 636px) 100vw, 636px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Even though languages like Python or JavaScript prove that classes and interfaces are not necessary to benefit from object-oriented programming, the illustration visible above depicts a language featuring both classes and interfaces in order to explain the benefits of inversion of control. I strongly believe it&apos;s going to make the example easier to understand, as the concepts of interfaces and concrete implementations always exist in our heads, regardless of whether our language of choice requires their explicit declaration.&lt;/p&gt;
&lt;p&gt;An interface is a type of contract the user of a black-box object may relay on in order to know what are the available methods and what are they supposed to do.&lt;/p&gt;
&lt;p&gt;One interface may have multiple implementations.&lt;/p&gt;
&lt;p&gt;The caller, that is the client of the object, calls a method through the interface. It doesn&apos;t really know what exact implementation is going to handle the method call. It relays on the contract that such a method is going to do such a thing.&lt;/p&gt;
&lt;p&gt;What&apos;s going to happen (assuming that it&apos;s a language with dynamic dispatch), is that &lt;strong&gt;the method call is going to be redirected to a concrete implementation hidden behind this interface&lt;/strong&gt;. The caller will get the result of calling the concrete method. What&apos;s very important is that in order to benefit from this indirection the client is allowed to relay on nothing but the interface. It must not make any assumptions about the concrete implementation that&apos;s going to handle the method calls. Otherwise, it becomes tightly coupled to the callee.&lt;/p&gt;
&lt;p&gt;This indirection is so powerful, because it allows to easily write &lt;strong&gt;code encapsulating high-level ideas that is not dependent on details&lt;/strong&gt;. The place where a concrete implementation is defined may be completely separated from the place where it&apos;s used through an interface.&lt;/p&gt;
&lt;p&gt;For example, a service may need to use a cache. Instead of using a particular implementation like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyService&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; cache&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cache &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RedisCache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It may use it through an interface:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyService&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; cache&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; MyCacheInterface&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That way &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt; doesn&apos;t depend on any particular implementation of the cache. It&apos;s less likely to change when the cache implementation changes. It may be reused, even with a totally different cache implementation. It&apos;s easier to unit test. It&apos;s simpler.&lt;/p&gt;
&lt;p&gt;Depending on the programming language, objects may be simulated with first-class functions or pointers.&lt;/p&gt;
&lt;h2&gt;Automata-based dispatch&lt;/h2&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/automata-based-dispatch-4261209df97433a9d2fecf3fa7487954-b3be4.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1000px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 76.29999999999998%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe5oIo//xAAYEAADAQEAAAAAAAAAAAAAAAAAASExEf/aAAgBAQABBQJswo1OCz//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAY/Al//xAAaEAADAQEBAQAAAAAAAAAAAAAAAREhQVGR/9oACAEBAAE/IWWL74NvXBNt4Ug0lRJFp//aAAwDAQACAAMAAAAQAM//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAcEAEAAwACAwAAAAAAAAAAAAABABExQVEhYbH/2gAIAQEAAT8Q6GWkF4lRrl5z3AaULL6gICua7iDbPsUlYc1s/9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Automata-based dispatch&quot;
        title=&quot;&quot;
        src=&quot;/static/automata-based-dispatch-4261209df97433a9d2fecf3fa7487954-b3be4.jpg&quot;
        srcset=&quot;/static/automata-based-dispatch-4261209df97433a9d2fecf3fa7487954-27d6e.jpg 300w,
/static/automata-based-dispatch-4261209df97433a9d2fecf3fa7487954-5d038.jpg 600w,
/static/automata-based-dispatch-4261209df97433a9d2fecf3fa7487954-b3be4.jpg 1000w&quot;
        sizes=&quot;(max-width: 1000px) 100vw, 1000px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Automata-based dispatch is great at addressing cases where the concrete implementation we want to use changes during the program execution.&lt;/p&gt;
&lt;p&gt;When compared to object-oriented programming, the biggest difference is that &lt;strong&gt;instead of always dispatching methods to the same concrete class, it allows to jump from one set of concrete implementations to another&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Different sets of implementations are connected by named arrows. They make a &lt;a href=&quot;https://en.wikipedia.org/wiki/Finite-state_machine&quot;&gt;state machine&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For instance, in the illustration visible above, &lt;code class=&quot;language-text&quot;&gt;A&lt;/code&gt; returns both &lt;code class=&quot;language-text&quot;&gt;A&amp;#39;s result&lt;/code&gt; and an arrow called &lt;code class=&quot;language-text&quot;&gt;x&lt;/code&gt;. Following this arrow changes the current state of the state machine from &lt;code class=&quot;language-text&quot;&gt;A&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;B&lt;/code&gt;, so the next time there&apos;s an action to handle, it&apos;s &lt;code class=&quot;language-text&quot;&gt;B&lt;/code&gt; that&apos;s going to handle it, not &lt;code class=&quot;language-text&quot;&gt;A&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let&apos;s take a look at an example of a model of a cursed prince. Below we can see that as soon as he eats a pizza, he turns into a frog.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;INTRODUCE_YOURSELF&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &apos;I am The Prince of Rosmaro!&apos;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;EAT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dish&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;yakisoba&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// undefined&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;INTRODUCE_YOURSELF&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &apos;I am The Prince of Rosmaro!&apos;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;EAT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dish&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pizza&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// undefined&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;INTRODUCE_YOURSELF&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &apos;Ribbit! Ribbit!&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;action &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The high level part of the model, that is the state machine, looks like this when opened in the editor:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/automata-based-programming-editor-902497ae82be18f756fbb3df6505ee32-dcbb0.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 72.8643216080402%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAACnUlEQVQ4y6WSz2sTQRTHozfvXgr+A9KGtGm7UMGDgsf4Z3gVPPQsvQheROmtDUISWg+CSjFeWkELadMgTRrT3WyyGzc/dpPdbYdmA9kfmXnOTLbStNWLD747w5u3n/fezItoe/t35J/f70lNedE0TKFeq3O1tJbQ1JpC8bAo5PfzgngsCu1Wm59VxapQKpYEVVEFpaYIYkUUdr/t3oowO87l3nRbIsha3dPbOqY/YUM3MDpFuN/v467RxdovDesdnft6vR7utDuYJsO9bg9bpjVqqA1IriUFDiweHSVtG4FclYNKpQK2bcNoNALP82B5eRlWVlYACAGMMVw2Qv2EfailUqkHHCiJ4rrvujAYDPzA9wkFcVEA2draItlsliCEiGmaxDAMQuOI67okCAJCEzMYz5TJZMbAYqm0rpsWnJ2dBTSYgcFxHBgOhxPVsAqZj8KhXC5DoVBgYgnwRIXVWm3dpw6fpmStnosBzvdhV3+MXYckSaDrOuuGA9Pp9BhYo8AwKGCBvu/zHyj/4j1NAOnD8Dh2fKXli0AWdB2QGfNblgWyLIOqqnw/PibXA92wwnNdBjKj98za5Pvw/O8V0vKCEQ3CVLx1ujIYDkfGpBWxx7g0NleBVVleYw7kDPyTvoNPHAf77KLHg8dlmybO53JYURQ8fnA6U7TVUKOJRzmSpLebcgs2DyskWSjD8+0c7NQ18DABa+jBqRfA6dAFzTqBf9nGxsZDDjw4OHhdEiUsKardaDbRh/wP9CT1Hr368hU9e/cJPd38iF5md9CLz9uoreuoaxjIuKr+6urqfQ6cnp6+u7SwkJifjSUW43OJpYV5vs7FYon47FhsH4tGE9GZmUSUrZN6HI/HH01NTd2OhHaD6uZ/ijEitPPIbwZdiyrfs+qFAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Automata-based programming editor&quot;
        title=&quot;&quot;
        src=&quot;/static/automata-based-programming-editor-902497ae82be18f756fbb3df6505ee32-86d16.png&quot;
        srcset=&quot;/static/automata-based-programming-editor-902497ae82be18f756fbb3df6505ee32-bd9cb.png 300w,
/static/automata-based-programming-editor-902497ae82be18f756fbb3df6505ee32-fe5c6.png 600w,
/static/automata-based-programming-editor-902497ae82be18f756fbb3df6505ee32-86d16.png 1200w,
/static/automata-based-programming-editor-902497ae82be18f756fbb3df6505ee32-dcbb0.png 1592w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The concrete implementations, which are the details, are coded:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Prince &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;INTRODUCE_YOURSELF&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;I am The Prince of Rosmaro!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;EAT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dish &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pizza&apos;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ate a pizza&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; undefined
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Frog &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;INTRODUCE_YOURSELF&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Ribbit! Ribbit!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As we can see, &lt;strong&gt;the current behavior is altered by following an arrow&lt;/strong&gt;. Automata-based programming enables thinking in terms of possible states and their behaviors as opposed to toggling Boolean flags. In this example, there&apos;s an &lt;em&gt;IF&lt;/em&gt;, so is there a Boolean value. The thing is that this Boolean is calculated solely based on the input value, without referring to any historical value set in the past. This plays an important role in writing decoupled code, because it makes the code independent from the past.&lt;/p&gt;
&lt;p&gt;The very idea of automata-based programming is nothing new. Personally, as someone coming from the object-oriented background, I first stumbled upon this paradigm when reading about the &lt;a href=&quot;https://en.wikipedia.org/wiki/State_pattern&quot;&gt;State design pattern&lt;/a&gt; in the &quot;Design Patterns: Elements of Reusable Object-Oriented Software&quot; book. This object-oriented pattern may be summed up as a way to change an object&apos;s class on the fly, so that conditional behavior may be modeled in a cohesive manner without &lt;em&gt;IF&lt;/em&gt;s and &lt;em&gt;Switches&lt;/em&gt; being scattered all around the codebase just to check the value of previously set member variables.&lt;/p&gt;
&lt;h2&gt;Multiple dispatch&lt;/h2&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/multiple-dispatch-9401e5272b77a0eba398598ff0283179-8b75e.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 800px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 51.75000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAKABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe7NiKP/xAAYEAACAwAAAAAAAAAAAAAAAAABEQAgIf/aAAgBAQABBQJwHHT/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAVEAEBAAAAAAAAAAAAAAAAAAAgMf/aAAgBAQAGPwKL/8QAGhAAAgMBAQAAAAAAAAAAAAAAAREAEFEhQf/aAAgBAQABPyElqJ6LgbykMFf/2gAMAwEAAgADAAAAEKDP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAHRAAAgEEAwAAAAAAAAAAAAAAAREAECFhcaGx8f/aAAgBAQABPxBE2MsW5gBAhZIfcVbDdPMp/9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Single dispatch and multiple dispatch&quot;
        title=&quot;&quot;
        src=&quot;/static/multiple-dispatch-9401e5272b77a0eba398598ff0283179-8b75e.jpg&quot;
        srcset=&quot;/static/multiple-dispatch-9401e5272b77a0eba398598ff0283179-5df75.jpg 300w,
/static/multiple-dispatch-9401e5272b77a0eba398598ff0283179-dcc9d.jpg 600w,
/static/multiple-dispatch-9401e5272b77a0eba398598ff0283179-8b75e.jpg 800w&quot;
        sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;So far, we&apos;ve been talking about deciding how &lt;code class=&quot;language-text&quot;&gt;X&lt;/code&gt; does &lt;code class=&quot;language-text&quot;&gt;Y&lt;/code&gt;. The challenge was to select the proper &lt;code class=&quot;language-text&quot;&gt;Y&lt;/code&gt; depending on &lt;code class=&quot;language-text&quot;&gt;X&lt;/code&gt;. But what about &lt;code class=&quot;language-text&quot;&gt;X&lt;/code&gt; doing &lt;code class=&quot;language-text&quot;&gt;Y&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;Z&lt;/code&gt;? What if we can tell what&apos;s the correct &lt;code class=&quot;language-text&quot;&gt;Y&lt;/code&gt; only after considering the state or type of both &lt;code class=&quot;language-text&quot;&gt;X&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Z&lt;/code&gt;? This time it&apos;s not just one argument that needs to be taken into account, but two. We call function dispatch based on multiple arguments &lt;em&gt;multiple dispatch&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;In order to illustrate the problem multimethods solve I decided to use Python due to its explicitly passed &lt;code class=&quot;language-text&quot;&gt;self&lt;/code&gt; argument. That way we can clearly see that &lt;code class=&quot;language-text&quot;&gt;self&lt;/code&gt; (or &lt;code class=&quot;language-text&quot;&gt;this&lt;/code&gt; in other languages) is nothing but a method argument. What the language does for us is automatically selecting the method implementation based on the class of &lt;code class=&quot;language-text&quot;&gt;self&lt;/code&gt;, so that we don&apos;t need to do it manually.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Dog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scareOff&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; anotherCreature&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;isinstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;anotherCreature&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Dog&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Grrr!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;isinstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;anotherCreature&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Human&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Woof! Woof!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Human&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scareOff&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; anotherCreature&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;isinstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;anotherCreature&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Dog&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token string&quot;&gt;&quot;GO AWAY {anotherCreature.name}!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;isinstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;anotherCreature&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Human&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token string&quot;&gt;&quot;I&apos;m {self.name} and I&apos;d like to tell you a programming joke!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

rex &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Dog&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Rex&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
rocky &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Dog&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Rocky&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
john &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Human&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
anna &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Human&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Anna&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

rex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scareOff&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rocky&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# &quot;Grrr!&quot;&lt;/span&gt;
rex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scareOff&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;john&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# &quot;Woof! Woof!&quot;&lt;/span&gt;
john&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scareOff&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rex&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# &quot;GO AWAY Rex!&quot;&lt;/span&gt;
john&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scareOff&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;anna&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# &quot;I&apos;m John and I&apos;d like to tell you a programming joke!&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As we can see, the &lt;code class=&quot;language-text&quot;&gt;scareOff&lt;/code&gt; implementation is selected based upon the class of the object. So it&apos;s either &lt;code class=&quot;language-text&quot;&gt;Dog&lt;/code&gt;&apos;s &lt;code class=&quot;language-text&quot;&gt;scareOff&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;Human&lt;/code&gt;&apos;s &lt;code class=&quot;language-text&quot;&gt;scareOff&lt;/code&gt;. Vanilla Python doesn&apos;t give us a way to select the proper method implementation based on any other argument than &lt;code class=&quot;language-text&quot;&gt;self&lt;/code&gt; and that&apos;s why there are &lt;em&gt;IF&lt;/em&gt;s checking the class of the second argument.&lt;/p&gt;
&lt;p&gt;Below is the same example implemented in Clojure. It makes use of &lt;a href=&quot;https://clojure.org/reference/multimethods&quot;&gt;multimethods&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;clojure&quot;&gt;&lt;pre class=&quot;language-clojure&quot;&gt;&lt;code class=&quot;language-clojure&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;; A multimethod selecting the proper implementation&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;; based on the species of the creatures.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defmulti&lt;/span&gt; scare-off &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;self another-creature&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
                      &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:species&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:species&lt;/span&gt; another-creature&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;; When a Dog wants to scare off another Dog.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defmethod&lt;/span&gt; scare-off &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:Dog&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:Dog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;self another-creature&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;Grrr!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;; When a Dog wants to scare off a Human.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defmethod&lt;/span&gt; scare-off &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:Dog&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:Human&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;self another-creature&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;Woof! Woof!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;; When a Human wants to scare off a Dog.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defmethod&lt;/span&gt; scare-off &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:Human&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:Dog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;self another-creature&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;GO AWAY &quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:name&lt;/span&gt; another-creature&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;; When a Human wants to scare off another Human.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defmethod&lt;/span&gt; scare-off &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:Human&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:Human&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;self another-creature&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;I&apos;m &quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:name&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; and I&apos;d like to tell you a programming joke!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;; Defining Rex, Rocky, John, and Anna.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; rex &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:species&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:Dog&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:name&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Rex&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; rocky &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:species&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:Dog&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:name&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Rocky&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; john &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:species&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:Human&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:name&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; anna &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:species&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:Human&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:name&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Anna&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;; Function calls.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;scare-off rex rocky&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;; &quot;Grrr!&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;scare-off rex john&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;; &quot;Woof! Woof!&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;scare-off john rex&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;; &quot;GO AWAY Rex!&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;scare-off john anna&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;; &quot;I&apos;m John and I&apos;d like to tell you a programming joke!&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This piece of code consists of two important parts crucial to understand multimethods. The first one is the &lt;em&gt;dispatching function&lt;/em&gt;. It takes function arguments and returns a &lt;em&gt;dispatching value&lt;/em&gt;. The proper method is picked based on this value. In this case, the &lt;em&gt;dispatching value&lt;/em&gt; is &lt;code class=&quot;language-text&quot;&gt;[(:species self) (:species another-creature)]&lt;/code&gt;. The second important part is where a concrete function is associated with a &lt;em&gt;dispatching value&lt;/em&gt;. For example, when a &lt;code class=&quot;language-text&quot;&gt;Dog&lt;/code&gt; wants to scare off a &lt;code class=&quot;language-text&quot;&gt;Human&lt;/code&gt;, it does it like this: &lt;code class=&quot;language-text&quot;&gt;(defmethod scare-off [:Dog :Human] [self another-creature] &amp;quot;Woof! Woof!&amp;quot;)&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;scare-off&lt;/code&gt; is the function name, &lt;code class=&quot;language-text&quot;&gt;[:Dog :Human]&lt;/code&gt; is the &lt;em&gt;dispatching value&lt;/em&gt;, &lt;code class=&quot;language-text&quot;&gt;[self another-creature]&lt;/code&gt; are the function arguments and &lt;code class=&quot;language-text&quot;&gt;&amp;quot;Woof! Woof!&amp;quot;&lt;/code&gt; is the body of the function.&lt;/p&gt;
&lt;p&gt;There are multiple ways to implement multimethods in languages that don&apos;t support them out of the box. One of the most popular ones (for double dispatch, that is multiple dispatch based on just two arguments) is the &lt;a href=&quot;https://en.wikipedia.org/wiki/Visitor_pattern&quot;&gt;Visitor design pattern&lt;/a&gt;. Another way is to use a library that encapsulates all the manual argument inspections. If you&apos;re interested in this topic, please take a look at the &lt;a href=&quot;https://coder.earth/post/multiple-dispatch-in-java&quot;&gt;Multiple dispatch in Java&lt;/a&gt; post.&lt;/p&gt;
&lt;p&gt;Multiple dispatch may seem exotic, but in fact, it&apos;s quite popular. We can find it with ease even in PHP, where it&apos;s used to build things like message buses. For example, the &lt;a href=&quot;https://symfony.com/doc/current/components/event_dispatcher.html&quot;&gt;EventDispatcher Symfony component&lt;/a&gt; allows to define what a polymorphic &lt;code class=&quot;language-text&quot;&gt;dispatch&lt;/code&gt; method should do when called with a particular &lt;em&gt;dispatcher&lt;/em&gt; and a particular &lt;em&gt;event&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;The described techniques differ in many ways. While some are about very simple choices, like &lt;em&gt;yes&lt;/em&gt; or &lt;em&gt;no&lt;/em&gt; (&lt;em&gt;IF&lt;/em&gt;), some allow to define multiple paths (&lt;em&gt;Switch&lt;/em&gt;). Both &lt;em&gt;IF&lt;/em&gt;s and &lt;em&gt;Switch&lt;/em&gt;es require manual inspection of the arguments every time a function is called, while the other described constructions pick the proper implementation under the hood once they are declared (an object instance in Java, a complete Rosmaro model with bindings in JavaScript or a multimethod with methods installed via &lt;code class=&quot;language-text&quot;&gt;defmethod&lt;/code&gt;). An object doesn&apos;t change its class during the execution of a program, while a &lt;a href=&quot;https://rosmaro.js.org&quot;&gt;Rosmaro&lt;/a&gt; model is all about changing the implementation after consuming an action. Sometimes the concrete implementation is picked based on only one argument (objects in Java), other times multiple values are taken into account (multimethods in Clojure).&lt;/p&gt;
&lt;p&gt;A real life application will usually make use of multiple techniques. For example, a web application may use double dispatch to route events to event handlers. Event handlers may be objects using other objects through their interfaces. Within these objects there may be &lt;em&gt;Switch&lt;/em&gt; statements handling a finite set of states (automata-based programming is sometimes called &quot;Switch technology&quot;). While some mechanisms are implemented in the language, other paradigms are supported through libraries. After all, I believe that the decision how to select the piece of code to run shouldn&apos;t be based solely on the mechanisms natively supported by our language of choice. Instead, we should strive for our implementation to reflect the problem model we have in our heads.&lt;/p&gt;
&lt;p&gt;Thank you for reading this post.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[A JavaScript framework for functions of state and action]]></title><link>https://coder.earth/post/a-javascript-framework-for-functions-of-state-and-action</link><guid isPermaLink="false">https://coder.earth/post/a-javascript-framework-for-functions-of-state-and-action</guid><pubDate>Fri, 21 Sep 2018 20:37:20 GMT</pubDate><content:encoded>&lt;p&gt;A function of state and action is a function that takes two arguments: state and action.&lt;/p&gt;
&lt;p&gt;Functions like that are very common in the JavaScript ecosystem. For example, the &lt;strong&gt;reducer function&lt;/strong&gt; used to build a Redux store is a function that takes the current state and some action and returns nothing but a new state. The &lt;strong&gt;render function&lt;/strong&gt; from React can also be considered a function of state and an implicit &lt;code class=&quot;language-text&quot;&gt;RENDER&lt;/code&gt; action that returns a view and doesn&apos;t change the state. Thus, the fundamentals of React and Redux may be summed up as writing functions of state and action that return a new state and some result.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a-function-of-state-and-action-e755f87667f2430e9ae1eb3b5c62f1e9-fe57b.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 964px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.788381742738586%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAABXklEQVQoz9WR0U7CMBSGt9Nxi3eCMLKtW9eOAoojkjgkeuEthPgQPoAXMp5QfCMWm3o6GM4LTYze2OTL+U/b/9/Jall/vWIeHKuBC3qs31G/W88ol35+/PVgEfP2otc7q+9DxTXzIJIUOEfEBzjFQQfHvcrc6ZxaZmzbNO2oN54P+OviNt7KO7aNBd2iCaFfELxUmsV+ajLK8OoLLa+zzAZc32dMC4SJUDNuoBqn0rFAjI6pRg/WsOyN9gN3ZTJEUgt03dYqGQk9nSTq5sJX6XmksktfzaeJGqdDlaYjdZUlajIL1WjMVJpRNZ3JtyF6um7rYR8YgoXjloG4ucBJlOwHhUz8Qoig6AuvkH1acBGWCDwT0keNte/vEkl3xtN128vDK4PlOE75QwkBSgh5soFskDUQktvEyW2AHM9yMADJwSbYE6PXYMPGeBBqMhoN59PLm66JnPyQ5sH7T9Y7FtZwPlHZ0K8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A function of state and action&quot;
        title=&quot;&quot;
        src=&quot;/static/a-function-of-state-and-action-e755f87667f2430e9ae1eb3b5c62f1e9-fe57b.png&quot;
        srcset=&quot;/static/a-function-of-state-and-action-e755f87667f2430e9ae1eb3b5c62f1e9-d42c7.png 300w,
/static/a-function-of-state-and-action-e755f87667f2430e9ae1eb3b5c62f1e9-ffd59.png 600w,
/static/a-function-of-state-and-action-e755f87667f2430e9ae1eb3b5c62f1e9-fe57b.png 964w&quot;
        sizes=&quot;(max-width: 964px) 100vw, 964px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Writing such functions is easy when the state is always interpreted in the same way. That is, when the reducer never checks the contents of the state before applying a transformation to it and the render function is free of conditionals. An example reducer could always append an item to an array, regardless its previous contents. An example render function could always map over some array items, even when there are none. However, transforming the state becomes &lt;strong&gt;a great challenge as soon as events from the past must be taken into account&lt;/strong&gt;. It&apos;s usually manifested in numerous Boolean flags and &lt;code class=&quot;language-text&quot;&gt;if&lt;/code&gt; statements or expressions.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/logo-fabd92b648ca0659eb9108ca05326198-844e5.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 192px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAC4jAAAuIwF4pT92AAADMklEQVQ4y32TSUwTYRSAhy2e9OAaDyJhkWDUuIQEcEWQQLBYjGVpaVlswcKU0nW6UKDMdJkCDqUWO0DpgghWRIwXEz2ZaIye3GIwejRy8AJRiZTOc6aK0UT4kz/v5S3fe////h/ZvXMbIlK5EhB2FVR15vimbz+j3B7oH6Dg2ggN/DrVac4nkpsSA2QnclnAQzZc00MEIm63xYHlYlPW4DD9pU2hglaFanlo+DoIayRVnM+iUaVw8vEtGkElgo2huKo5kZNaqfCoD9czLrUUBjH56qARBVzZ9OoSr3QH5w+4LMmcfPNgClGsB9XJ6pDnM3Qc6LF0TES8DvDhuqjfaQbahq2O9HSA32l6jTbU7uJiJqne5LXcx9M0wis68S/QqpTGj9ujQTMmSOO3KZqCsIdkpv1eJuy2w3Bn20qINML90YEPrWJBBhcLS+8TfYQhcY2hviz86w7deLzimNPcPuvphXGyMxoa6GFCFM4ESBMTtOvApZGu3L1GwJzP9RnXyAvXcucfRf5AD2ZnIPwSdn7w42O8wyBpnrozZIVxmy4acmIQYEEBu54JOjDmKnYFaKsqGqG6ITKEAzvIh5RFfZzL+/TkXtIkZU1+MTuaJK/h/Spg1OlS/HZs/ma/mQPG3KY2ZgzXQshpgN9AZozQcgVi3J7zEnDPR8Kow4z+dzBtYkFa2GX+zgaDo6Mp5lA2MLb2emakVx0Lk0ZmQN8CrA5hp4HrOOYndD/YYsyMh4BQXxcZ7u822tXNgZbq80VxoKy2MmOizxz1WhRAqhrBjTVDv7oJKMMVuNFngj6tjBnEWphxtsugQw8TpAEmWbuf0IC3S8meSs/qWlCKLz5FqsvO5BqbhZTfpgMrKlkgUPGii4U5OxqWsSbBu1FcE6XYO+xpFQGOir+z3S8RCslCt1w0pxDyRKnbt2zNzUnfW3AoO1VaWbwJUdRVvqStavCY0UVJRfHJ3P2Z26tLTxXwz+bHnwihbAyGHBg41TKo55eYWFNy2YljW9b9JcX5RzYfyEzL25++J+d//nN5h7PEvKKIsLywK/fAvl1rdvj6NsEkq0mqv3AuoZFfktDAblRYgfwEpYOHfXn5vEoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Rosmaro logo&quot;
        title=&quot;&quot;
        src=&quot;/static/logo-fabd92b648ca0659eb9108ca05326198-844e5.png&quot;
        srcset=&quot;/static/logo-fabd92b648ca0659eb9108ca05326198-ab421.png 300w,
/static/logo-fabd92b648ca0659eb9108ca05326198-9f536.png 600w,
/static/logo-fabd92b648ca0659eb9108ca05326198-844e5.png 800w&quot;
        sizes=&quot;(max-width: 192px) 100vw, 192px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://rosmaro.js.org&quot;&gt;Rosmaro&lt;/a&gt; is a JavaScript framework for writing functions of state and action.&lt;/strong&gt; Instead of using just one model (like key-value pairs) to express the whole state, it draws a line between &lt;a href=&quot;https://coder.earth/post/behavior-related-state-and-data-related-state&quot;&gt;data-related state and behavior-related state&lt;/a&gt; by making use of finite state machines.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/dispatch-illustration-650402bf6a84ebc53b4bdc9afb9f53cd-ef898.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 42%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAIABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAIF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAB2qAD/8QAFhABAQEAAAAAAAAAAAAAAAAAAREA/9oACAEBAAEFAoSFA3//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAVEAEBAAAAAAAAAAAAAAAAAAABEP/aAAgBAQAGPwJv/8QAGBABAAMBAAAAAAAAAAAAAAAAABEhUdH/2gAIAQEAAT8h0FBE6//aAAwDAQACAAMAAAAQg8//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAWEQADAAAAAAAAAAAAAAAAAAABEBH/2gAIAQIBAT8QgX//xAAaEAEAAwEBAQAAAAAAAAAAAAABESExAFHw/9oACAEBAAE/EIBERiN+1y43ATv3vAetur7/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Automata-based programming&quot;
        title=&quot;&quot;
        src=&quot;/static/dispatch-illustration-650402bf6a84ebc53b4bdc9afb9f53cd-19371.jpg&quot;
        srcset=&quot;/static/dispatch-illustration-650402bf6a84ebc53b4bdc9afb9f53cd-c766d.jpg 300w,
/static/dispatch-illustration-650402bf6a84ebc53b4bdc9afb9f53cd-f0d1c.jpg 600w,
/static/dispatch-illustration-650402bf6a84ebc53b4bdc9afb9f53cd-19371.jpg 1200w,
/static/dispatch-illustration-650402bf6a84ebc53b4bdc9afb9f53cd-ef898.jpg 1500w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;It leverages the power of the &lt;strong&gt;automata-based programming&lt;/strong&gt; paradigm in order to remove the dependency of code on events from the past and provide a graph-based dispatch mechanism.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor-b3a83ebe4769a8a1d28b1ac47bbf0d14-57f14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.560344827586206%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAACPElEQVQoz5VRz28SURDei0f9CzwY04M3xLLFAF5MhJQmHL176D/D+n94x2gPTQukbPkZWIwmAoVdKCyw/Ia3LCzse868alMkHpzky8x7M+9738wIxfjF83JRlqq1G6mpNqMASa2rkklMiRAiGX1Dampw11ClgTGQDMOQ9I4uaQ0N69FH27ftqKZqH8++nB0IaVkOL03C1rbNHho8ZEDI/sey2WxEuLi8fFetVJ3hcGgvl0t7s9kgsx2LxWwo4LHjONyv12t7Pp/z+C+soYYWCoVjISXLwUq1xm7qdQqEdLvdMkop63a7Owrxfjabsel0ytrtNvdAgrUU0giWz+fDQjqTCX6vVFmn26Mb2+YJUMsURWGlksJjNFDO4EMe2zAevL/jYruEqdRV8Fu5zGDolJgmxYd/bLVascFgwHRdZ6qqco95VDsej7nCPcLraznYaKhM0zQKLfKW0X4Xc8PWYZ6guMTbxbNlWTy313IulwtaoAQGThEPidBwlqhssVjsbRW59gjzQOjgYoEJvAMKMXJarZajlMsOkPEzik4kEk4ymXTuGoC1UsqBZ+TlhNlcPtQnJtMXJptYq/vfUZFFdlXhohD/smKxeCJ8PT9/G8sWlp+u0iTzs0aMXo/0+30ymU7JZ+UHqdx2yBzi4WhEYCQcI4hhKfeYTCYL2LoVj8dDwmvR8/hD5MRzGgmL749DovvwUPR6vaJ4dCQ+evpMfPHylfgmEBB9fr/odrs5/BD7fL4dBAIBj8vlevIL83E3C3P5x00AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Rosmaro Visual Editor&quot;
        title=&quot;&quot;
        src=&quot;/static/editor-b3a83ebe4769a8a1d28b1ac47bbf0d14-86d16.png&quot;
        srcset=&quot;/static/editor-b3a83ebe4769a8a1d28b1ac47bbf0d14-bd9cb.png 300w,
/static/editor-b3a83ebe4769a8a1d28b1ac47bbf0d14-fe5c6.png 600w,
/static/editor-b3a83ebe4769a8a1d28b1ac47bbf0d14-86d16.png 1200w,
/static/editor-b3a83ebe4769a8a1d28b1ac47bbf0d14-92b91.png 1800w,
/static/editor-b3a83ebe4769a8a1d28b1ac47bbf0d14-c030b.png 2400w,
/static/editor-b3a83ebe4769a8a1d28b1ac47bbf0d14-57f14.png 2784w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The graph file is a human readable JSON, thus it may be written by hand. However, it&apos;s a lot more fun to use the Rosmaro visual editor that makes Rosmaro &lt;strong&gt;a visual programming framework&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/time-travel-debugging-28fb1e6f650dab024426ba5b1b386797.gif&quot; alt=&quot;Time travel debugging&quot;&gt;&lt;/p&gt;
&lt;p&gt;The framework is functional and stands on the shoulders of giants like &lt;a href=&quot;https://redux-saga.js.org&quot;&gt;Redux Saga&lt;/a&gt; and &lt;a href=&quot;https://redux.js.org&quot;&gt;Redux&lt;/a&gt;, what gives access to all the tools we know and love. &lt;strong&gt;Time travel debugging is a breeze&lt;/strong&gt; even when asynchronous actions are involved.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/cohesion-4078bce91a74f910091ffad8d00c1cfa-74b72.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1024px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 40.13671875%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAIABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAB26FB/8QAFhABAQEAAAAAAAAAAAAAAAAAEQEA/9oACAEBAAEFAqtdE//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABUQAQEAAAAAAAAAAAAAAAAAAAAh/9oACAEBAAY/AkV//8QAFxAAAwEAAAAAAAAAAAAAAAAAAAEhcf/aAAgBAQABPyFGalRsH//aAAwDAQACAAMAAAAQg8//xAAWEQADAAAAAAAAAAAAAAAAAAABECH/2gAIAQMBAT8QEX//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAaEAACAwEBAAAAAAAAAAAAAAABEQAhMWFB/9oACAEBAAE/EDgECCjfAIbnZuqRaquT/9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Cohesion&quot;
        title=&quot;&quot;
        src=&quot;/static/cohesion-4078bce91a74f910091ffad8d00c1cfa-74b72.jpg&quot;
        srcset=&quot;/static/cohesion-4078bce91a74f910091ffad8d00c1cfa-d41b4.jpg 300w,
/static/cohesion-4078bce91a74f910091ffad8d00c1cfa-658df.jpg 600w,
/static/cohesion-4078bce91a74f910091ffad8d00c1cfa-74b72.jpg 1024w&quot;
        sizes=&quot;(max-width: 1024px) 100vw, 1024px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Keeping the reducer, the render function and the code that returns an effect close to each other makes the node code &lt;strong&gt;cohesive&lt;/strong&gt;. Rosmaro doesn&apos;t just output a bunch of data. &lt;strong&gt;It decides which function should handle the current state.&lt;/strong&gt; Yet, thanks to the graph-based dispatch nodes are &lt;strong&gt;totally decoupled&lt;/strong&gt; from each other and even from the past!&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/directory-structure-c3845e376ec7c2d276163e8c7df8478f-54a9d.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 221px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 169.68325791855204%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAiCAYAAABfqvm9AAAACXBIWXMAABYlAAAWJQFJUiTwAAAEM0lEQVRIx4VWV2LqSBD0DdY8B7IQYEBEkTOIDAbePu/e/y61VYPFgkkf7dEIuae6u7p6niLRNFLpIjpdD+VKm+sE680fuG4Lb+8WItEUQuGksXAkdTTtgyH7+JtvT/oTjX3ArXaQyZZRKDbQ7oxh2zn89RzGr5coXl7jeH2L4/lXBIFv02G+01PHT9roxLiVxdhbolrvod4cwpussFjsMF9ssVru4XlrbLdfWH9+8f0WxWL9zOmFw1g8Y1DmCzU4hTrK5SaKpQZq9T5aPCDnVFFx29z3mJoWEokckUaPjnynT6ewOwxVH7c7HkajORGvMBovMOE6GM4Nstl8h8FgZvaz2eYS4emLElFlcxWDUM+lUhP1BhG2DggVgfb6LZ+vmZzfddjteSasNis9JjIhHI+XmEzWGI4WR4RDouv2JmYvllx1+B5MmJx98NQ8EepZSISo0x4RTQXVWgeN5sC8L5IN+u3CoTY+F5Xwaq1rcjibfZoqj4hwyHwulr+xIT/F1xHRKtznQPiyKP6DnKogqnLqo4QWUSn8BvOn96VyCw0iKnPV+5zjmqhu5vDAxQyrNzPO1DXKlRBNpxt0uaqyQqxcX+PgRVGEUrnL5atcmwaZ9q7bMXshaxKx0hK+13o+wmQqb6ghRxU62bArVqvfpqIeu0h5U9upDX1nDxCmDCKHCNWK6hJVUsgqPEQHXivEmcOfJ8mRHCgshTcarzCf77HffaHbn2LK6ktMrjk7Ijw15bFQPHRKzqkdnkstIu2ZPApxNJa+7/AMJS3waiFjRTAqhww3l8yjqitZs8iEWxW+ijAUZteEUkgnEqhm4yR8AS7Dr9Z6xuykc+Tf3ZBPT3sLJpFLWhhWYugxb0In9XFI5hdWWGm5pdoXIQd5+lvQRjIeRykdNh0hGrkslG07hjZScdk16pwhFG0S/CdpoBSn3vKo2Hv0qX+T6Zr9vMeOqj2m+kgLfwrDzZAdap3paeZP62F4eaaPqyS+w3fiq8K+61AfJDiclDf1syiyXP9tlGcqhNS/zeefY17j8Q8W8AFCORX3xLlkqmCmoBAK0eBbWI0KURev8fGiKO8sSN4Oo18MmRm9IkKPyt3rz/BO/j0HIhyrsUdF0ZD6f83YCeSTESIsGrEQonpjgBhb7ifvbuTw4EhWy0XRLljoDlbY7v4xE64/mBoyXxPUG8S2j06dlIVC2sJHpoTKt5TV2X7XKHLV4c+P3EzMIJxyunnkW58VTafzpn8f3WvOB70JyUbWjiGbiJBrjcMsYXWVO787ArR7oZ9NvcVyy3vNCO3eArv9v1jMPzHUzYFIxT/dc5arPbJUbl9xboasUMS1ww3sMJeFUF3jVrtGcSqVw8SzKMKK5qZDIRSJ1a+SqFp9wBvXDjMi0hR8NbyLGf7JHoZ8Opd1Q0jYedSMBnYNIr8Q9/jn239fVtfp1N9tdgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Hierarchical directory structure&quot;
        title=&quot;&quot;
        src=&quot;/static/directory-structure-c3845e376ec7c2d276163e8c7df8478f-54a9d.png&quot;
        srcset=&quot;/static/directory-structure-c3845e376ec7c2d276163e8c7df8478f-f6496.png 300w,
/static/directory-structure-c3845e376ec7c2d276163e8c7df8478f-54a9d.png 442w&quot;
        sizes=&quot;(max-width: 221px) 100vw, 221px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;&lt;a href=&quot;https://github.com/lukaszmakuch/rosmaro-tools&quot;&gt;CLI tool&lt;/a&gt;&lt;/strong&gt; can automatically associate the nodes you draw with the code you write. Additionally, if you decide to use it, it provides a nice &lt;strong&gt;hierarchical directory convention&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/lens-11238937029c7e5fba700f4c8d861f00-eb799.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.6598611678236%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAEEAv/EABUBAQEAAAAAAAAAAAAAAAAAAAIB/9oADAMBAAIQAxAAAAHdTUVBII//xAAbEAACAgMBAAAAAAAAAAAAAAAAAQIRAyExMv/aAAgBAQABBQKUbni82hbGdP/EABURAQEAAAAAAAAAAAAAAAAAAAEQ/9oACAEDAQE/AWf/xAAVEQEBAAAAAAAAAAAAAAAAAAABEP/aAAgBAgEBPwEn/8QAFxABAQEBAAAAAAAAAAAAAAAAAREQAP/aAAgBAQAGPwKqzq5N/8QAGxAAAgMAAwAAAAAAAAAAAAAAABEBITFRYZH/2gAIAQEAAT8hmw3VTXhzj7H6i1sKRIx//9oADAMBAAIAAwAAABCbH//EABYRAQEBAAAAAAAAAAAAAAAAAAARMf/aAAgBAwEBPxDaP//EABYRAQEBAAAAAAAAAAAAAAAAAAARMf/aAAgBAgEBPxDFV//EABsQAQEAAgMBAAAAAAAAAAAAAAERACExQWHh/9oACAEBAAE/EBg1NIIexWSx+YENzdPOVl9mcgh9xeTqHeNQLAWYciGtZ//Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A lens&quot;
        title=&quot;&quot;
        src=&quot;/static/lens-11238937029c7e5fba700f4c8d861f00-19371.jpg&quot;
        srcset=&quot;/static/lens-11238937029c7e5fba700f4c8d861f00-c766d.jpg 300w,
/static/lens-11238937029c7e5fba700f4c8d861f00-f0d1c.jpg 600w,
/static/lens-11238937029c7e5fba700f4c8d861f00-19371.jpg 1200w,
/static/lens-11238937029c7e5fba700f4c8d861f00-228e2.jpg 1800w,
/static/lens-11238937029c7e5fba700f4c8d861f00-c1f63.jpg 2400w,
/static/lens-11238937029c7e5fba700f4c8d861f00-1e45c.jpg 3600w,
/static/lens-11238937029c7e5fba700f4c8d861f00-eb799.jpg 4898w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Selectors we know from Redux are a wonderful way to consume narrow pieces of the state. The code working with it can assume that it is going to be given exactly what it expects in the exact format it expects. Rosmaro takes it one step further and by utilizing &lt;strong&gt;&lt;a href=&quot;https://ramdajs.com&quot;&gt;Ramda&lt;/a&gt; lenses&lt;/strong&gt; allows not only to consume, but also alter a narrow slice of the data-related state.&lt;/p&gt;
&lt;p&gt;Even though Rosmaro opts for the smallest number of building blocks, its state machines support multiple techniques of dealing with composition and state explosion, like &lt;strong&gt;subgraphs, node multiplication, orthogonal regions and entry points&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/todo-c127bc411905f4a0855ab2b8978827ea.gif&quot; alt=&quot;ToDo App without boolean flags&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Don&apos;t fight with Boolean flags! Draw changes of behavior!&lt;/strong&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[FB versus RSS]]></title><link>https://coder.earth/post/fb-vs-rss</link><guid isPermaLink="false">https://coder.earth/post/fb-vs-rss</guid><pubDate>Sun, 26 Aug 2018 20:37:20 GMT</pubDate><content:encoded>&lt;p&gt;Open web feed standards such as RSS are declining in popularity in favor of centralised social media sites like Facebook, which are no longer just a source of entertainment, but also major content publishing platforms. I strongly believe that their centralised architecture and advertising-based business model are an increasing concern for independent creators and free speech in general.&lt;/p&gt;
&lt;p&gt;Due to the fact that what generates profit for all popular social networks is manipulation of public opinion, from adverts to political campaigns, they are built to provide addictive rather than user-friendly experience, in the same way as tobacco products are not user-friendly diet supplements. They successfully created an illusion of freedom to follow whoever you want, while the reality is that their feeds are carefully curated and users&apos; subscriptions are nothing for them but loose hints upon how to achieve their marketing goals. Some users may not be aware that their friends&apos; personal data, including names and pictures, is used to generate personalised adverts which are hard to distinguish from content that actually comes from them. The high effectiveness of advertising through spreading untrue stories about people&apos;s friends is certainly a desirable marketing result, but there is no doubt in my mind that such measures are immoral.&lt;/p&gt;
&lt;p&gt;The monopolistic nature of centralised social networks also has a detrimental effect on publishers, for whom the cost of reaching their subscribers is an arbitrary price set by that one company that is entitled to control content distribution on their website. Because this website is a walled garden, the only way to reach people gathered there is through agreeing to the owners&apos; conditions. There is no way how Facebook users could see post published on MySpace on their Facebook walls. Not only this, the form of the content being published is strictly limited to what a particular platform can support.&lt;/p&gt;
&lt;p&gt;Those looking for a convenient way to keep track of content from multiple sources may use one of the well established open web feed standards such as RSS and its countless clients. All what content consumers need to do in order to get started with it is to set up a news aggregator and because the standard is open, there is a great variety of implementations to pick from: open source, proprietary, for mobile devices, for desktop computers and even web based. Even thought at the first glance a news feed in a news aggregator may look similar to a social network feed, the mechanics under the hood differ significantly, as there is no centralised entity to decide who should see what and when. Instead of that, users pull the feeds directly from the creators. There is no way how a third party company could intervene in this process and stop the feed unless the creator pays them.&lt;/p&gt;
&lt;p&gt;The open nature of RSS makes it the most viable solution for creators who want to be sure that what they publish reaches their subscribers, because they are the ones in control of the feed. What is more, the cost of running an RSS feed is not an artificially set price, but simply the cost of various software and hardware solutions involved in the process which can be provided by one or more independent companies operating in a competitive environment. The fact of the matter is that plenty of the popular blogging and content management systems do already support generating RSS feeds.&lt;/p&gt;
&lt;p&gt;To sum up, I am of the opinion that centralised social media feeds turned out to be a dead end for creative individuals and that it is only through open standards and decentralisation that we can provide a healthy environment for valuable content to rise.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Are injection attacks still a problem in JavaScript?]]></title><link>https://coder.earth/post/injection</link><guid isPermaLink="false">https://coder.earth/post/injection</guid><pubDate>Sat, 30 Jun 2018 07:37:20 GMT</pubDate><content:encoded>&lt;p&gt;Back in the days when web development was all about server-side applications querying relational databases and outputting HTML, we saw many examples of code like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// CAUTION: Bad example!&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;popup&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;msg&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;p class=\&quot;popup\&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; msg &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;/p&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// CAUTION: Bad example!&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;login&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;SELECT name FROM users WHERE login = \&quot;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; login &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;\&quot;&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Since then we learned that there are safer ways to do this. &lt;/p&gt;
&lt;p&gt;Template engines and parameter binding are commonly used tools. It&apos;s rare nowadays to see dangerous string concatenation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this post I&apos;d like to share my observation on injection attacks. It seems they are still a problem in JavaScript!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To understand why let&apos;s break one of the bad examples down into more basic forms. Here it is:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;userInput&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; firstCommand&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; secondCommand&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; firstCommand&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;userInput&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;secondCommand&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As we can see, &lt;strong&gt;the root cause of injection attacks is that for the computer there&apos;s no difference between a command and the user input! That&apos;s why a malicious user is able to enter data which is treated as code.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Of course, as I mentioned earlier, there are well known ways to protect against that type of attacks. Instead of writing this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;SELECT name FROM users WHERE login = \&quot;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; login &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;\&quot;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;we would write something like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;SELECT name FROM users WHERE login = :login&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;login&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That way the command &lt;code class=&quot;language-text&quot;&gt;SELECT name FROM users WHERE login = :login&lt;/code&gt; is clearly separated from the data &lt;code class=&quot;language-text&quot;&gt;{login}&lt;/code&gt;. In the same time the underlaying mechanism makes sure that the data is prepared to be used in an SQL query. There&apos;s no way to escape the quotes and inject any malicious code.&lt;/p&gt;
&lt;p&gt;However, the web development train is moving fast. What we can see more and more often is not only this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  paramA&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;the value of the A parameter&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  paramB&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;the value of the B parameter&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;but also this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  paramA&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;the value of the A parameter&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  paramB&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;the value of the B parameter&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;the value of the C parameter&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The huge difference between these two is that the parameter value is an object which consists of a command!&lt;/p&gt;
&lt;p&gt;Let&apos;s say the values are read from the &lt;code class=&quot;language-text&quot;&gt;userInput&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  paramA&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; userInput&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;paramA&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  paramB&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    userInput&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;paramB&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    userInput&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;paramB&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We don&apos;t need to worry about the user providing a malicious string. It will all be safely handled.&lt;/p&gt;
&lt;p&gt;The problem is that the parameter value doesn&apos;t need to be a simple value like &lt;code class=&quot;language-text&quot;&gt;the value of the A parameter&lt;/code&gt; but it also may be a command like &lt;code class=&quot;language-text&quot;&gt;{$in: [&amp;quot;B&amp;quot;, &amp;quot;C&amp;quot;]}&lt;/code&gt;. Taking into consideration the fact that there are at least few ways how the user may send a request which when decoded gives us an object (a form, JSON or XML payload), the code is vulnerable to injection attacks.&lt;/p&gt;
&lt;p&gt;Let&apos;s say &lt;code class=&quot;language-text&quot;&gt;userInput.paramA&lt;/code&gt; equals &lt;code class=&quot;language-text&quot;&gt;{$empty: false}&lt;/code&gt;. It makes the query look like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  paramA&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$empty&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  paramB&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    userInput&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;paramB&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    userInput&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;paramB&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Again, there&apos;s no way the computer can distinguish trusted commands from untrusted user input. &lt;strong&gt;Just instead of mixing trusted and untrusted strings, we&apos;re mixing trusted and untrusted objects.&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The solution is to always write commands in such a way that they cannot be received from the user.&lt;/strong&gt; One possible way to achieve this is the approach used by &lt;a href=&quot;https://reactjs.org&quot;&gt;React&lt;/a&gt; and &lt;a href=&quot;https://github.com/lukaszmakuch/snabbdom-signature&quot;&gt;Snabbdom-Signature&lt;/a&gt; (a tiny library to &lt;strong&gt;protect against virtual DOM injection attacks&lt;/strong&gt;) - to mark every command object with a &lt;code class=&quot;language-text&quot;&gt;Symbol&lt;/code&gt;, so it cannot be send over the network.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I must admit that I caught myself at least a couple of times thinking that if there&apos;s no SQL database or because I&apos;m using some virtual DOM I&apos;m not vulnerable to injection attacks. Oh how wrong I was!&lt;/strong&gt; &lt;/p&gt;</content:encoded></item><item><title><![CDATA[If vs. Switch]]></title><link>https://coder.earth/post/if-vs-switch</link><guid isPermaLink="false">https://coder.earth/post/if-vs-switch</guid><pubDate>Tue, 05 Jun 2018 07:37:20 GMT</pubDate><content:encoded>&lt;p&gt;Both &lt;code class=&quot;language-text&quot;&gt;ifs&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;switches&lt;/code&gt; are about picking one among few possible pieces of code.&lt;/p&gt;
&lt;p&gt;In the case of an expression, the picked piece of code is evaluated and becomes the result of the expression. When it&apos;s a statement, it&apos;s expected to have some side effects, as the code is simply run.&lt;/p&gt;
&lt;p&gt;Some languages, like Elm, are very strict. When there&apos;s an &lt;code class=&quot;language-text&quot;&gt;if&lt;/code&gt;, there must be an &lt;code class=&quot;language-text&quot;&gt;else&lt;/code&gt;. When there&apos;s a &lt;code class=&quot;language-text&quot;&gt;case&lt;/code&gt; (the Elm&apos;s name for a &lt;code class=&quot;language-text&quot;&gt;switch&lt;/code&gt; expression), it must list all of the possible values. Other languages, like JavaScript, don&apos;t require that.&lt;/p&gt;
&lt;p&gt;There are also times when &lt;code class=&quot;language-text&quot;&gt;switch&lt;/code&gt; is faster than &lt;code class=&quot;language-text&quot;&gt;if&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I must admit that I don&apos;t even remember when did I write my first &lt;code class=&quot;language-text&quot;&gt;ifs&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;switches&lt;/code&gt;. So it&apos;s even more embarrassing to say that &lt;strong&gt;I discovered the most important difference between these two not so long ago. And it&apos;s none of the things I mentioned above.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;If&lt;/code&gt; picks one piece of code when a value is &lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt; (or truthy) and another when it&apos;s &lt;code class=&quot;language-text&quot;&gt;false&lt;/code&gt; (or falsey). There are always only two inspected values: &lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;Switch&lt;/code&gt; associates different pieces of code with different values. There may be many values and they are user defined.&lt;/p&gt;
&lt;p&gt;Let&apos;s take a look at a very simple example. It&apos;s about loading something over the network.
This is the code &lt;code class=&quot;language-text&quot;&gt;ifs&lt;/code&gt; encourage me to write:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isLoaded&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errorOccurred&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If I were writing this in TypeScript, it would be very tempting to define the &lt;code class=&quot;language-text&quot;&gt;state&lt;/code&gt;&apos;s type like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;isLoaded&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;boolean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; errorOccurred&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;boolean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Even though it may look legit at the first glance, it&apos;s not.&lt;/p&gt;
&lt;p&gt;The compiler will never notice that the following state is incorrect:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;isLoaded&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; errorOccurred&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The correct type looks more like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;isLoaded&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; errorOccurred&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;isLoaded&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; errorOccurred&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;isLoaded&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; errorOccurred&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As we can see, what our application logic really cares about are not two boolean values, but three possible states.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;loading&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;loaded&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As soon as we discover all the possible states, we can assign them different behaviors using a &lt;code class=&quot;language-text&quot;&gt;switch&lt;/code&gt;. There&apos;s no need to inspect boolean values anymore.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;loading&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;loaded&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As little sense as it makes, we can bend an &lt;code class=&quot;language-text&quot;&gt;if&lt;/code&gt; to look like a &lt;code class=&quot;language-text&quot;&gt;switch&lt;/code&gt;, and vice versa:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;loading&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;loaded&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isLoaded&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errorOccurred&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;At this point it becomes clear that the difference between &lt;code class=&quot;language-text&quot;&gt;if&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;switch&lt;/code&gt; isn&apos;t about the syntax. It&apos;s about the mental model.&lt;/strong&gt; Do I want to make decisions based on whether some expression evaluates to true, or do I want to discover all the possible states and assign them different behaviors?&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;What&apos;s really fascinating is that the state discovery process is just the first step. Even though &lt;code class=&quot;language-text&quot;&gt;switches&lt;/code&gt; clearly present all the states, they hide state changes.&lt;/p&gt;
&lt;p&gt;If we add the list of possible events which cause state transitions to the list of possible states, we get a state machine. And if we base our programming on a state machine, we are &lt;a href=&quot;https://en.wikipedia.org/wiki/Automata-based_programming&quot;&gt;automata-based programmers&lt;/a&gt;! &lt;/p&gt;</content:encoded></item><item><title><![CDATA[How exceptions broke my middleware]]></title><link>https://coder.earth/post/how-exceptions-broke-my-middleware</link><guid isPermaLink="false">https://coder.earth/post/how-exceptions-broke-my-middleware</guid><pubDate>Mon, 30 Apr 2018 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;Recently I work a lot with a web framework called &lt;a href=&quot;https://laravel.com&quot;&gt;Laravel&lt;/a&gt;. It&apos;s something like the Java ecosystem and Ruby on Rails had a child in the PHP land.&lt;/p&gt;
&lt;p&gt;A couple of weeks ago I was writing some ordinary, boring code. Much to my surprise, it didn&apos;t always work as expected. After quite a long debugging session (shame on me) I managed to track the problem down. My &lt;a href=&quot;https://laravel.com/docs/5.6/middleware&quot;&gt;middleware&lt;/a&gt; was broken. It didn&apos;t run completely. Just the beginning was executed, but not the rest. How was that possible?&lt;/p&gt;
&lt;p&gt;There was an exception which broke the control flow. It was a great reminder why do some new &lt;a href=&quot;https://guide.elm-lang.org/error_handling/&quot;&gt;programming languages (like Elm) have no exceptions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let&apos;s visualize how Laravel middlewares work when there&apos;s a controller &lt;code class=&quot;language-text&quot;&gt;Ctrl&lt;/code&gt; and two middlewares &lt;code class=&quot;language-text&quot;&gt;MidA&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;MidB&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/control.001-b6e0d3b87c442330df71c036050ea05a-81c61.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 23px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 82.842287694974%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAARABQDASIAAhEBAxEB/8QAGAABAAMBAAAAAAAAAAAAAAAAAAEDBAX/xAAXAQADAQAAAAAAAAAAAAAAAAAAAgMB/9oADAMBAAIQAxAAAAHqWZ7mloCVkaSA/8QAHBABAAIBBQAAAAAAAAAAAAAAAQADAgQREiAi/9oACAEBAAEFArrMq4Weh3moHKGDzAOn/8QAGBEAAgMAAAAAAAAAAAAAAAAAAQIREiD/2gAIAQMBAT8BlrHH/8QAGBEAAgMAAAAAAAAAAAAAAAAAAQIRIDL/2gAIAQIBAT8BfIin/8QAHBAAAgICAwAAAAAAAAAAAAAAAAEREgIhIDFB/9oACAEBAAY/AlEFWvDRjVNib6g1w//EABsQAQEBAAIDAAAAAAAAAAAAAAERACFRIDFh/9oACAEBAAE/IeFle9QwWrgFQ7vyes+EcMwMAHzw/9oADAMBAAIAAwAAABDz/wAA/8QAGhEAAQUBAAAAAAAAAAAAAAAAAQAQESFBYf/aAAgBAwEBPxAQWUjx/wD/xAAZEQEAAgMAAAAAAAAAAAAAAAABESEAEDH/2gAIAQIBAT8QAP1N4TF7/8QAHBAAAgIDAQEAAAAAAAAAAAAAAREAITFBUSBx/9oACAEBAAE/EFC7siXS5D0SFmsYiIDoLjoNFiHyEGBAtyVuby0gXj//2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Request handling happy path&quot;
        title=&quot;&quot;
        src=&quot;/static/control.001-b6e0d3b87c442330df71c036050ea05a-81c61.jpeg&quot;
        srcset=&quot;/static/control.001-b6e0d3b87c442330df71c036050ea05a-17a40.jpeg 300w,
/static/control.001-b6e0d3b87c442330df71c036050ea05a-81c61.jpeg 577w&quot;
        sizes=&quot;(max-width: 23px) 100vw, 23px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The simplified flow goes like this. The request is first passed to &lt;code class=&quot;language-text&quot;&gt;MidA&lt;/code&gt;. It&apos;s then passed to &lt;code class=&quot;language-text&quot;&gt;MidB&lt;/code&gt;, which finally passes it to &lt;code class=&quot;language-text&quot;&gt;Ctrl&lt;/code&gt;. The controller produces some response and returns it to &lt;code class=&quot;language-text&quot;&gt;MidB&lt;/code&gt;, which then returns it to &lt;code class=&quot;language-text&quot;&gt;MidA&lt;/code&gt;, which finally sends it to the browser. Easy-peasy!&lt;/p&gt;
&lt;p&gt;Unfortunately, it gets a lot more complicated, not to say unmanageable, as soon as exceptions come into play. It&apos;s because they are often used to control how the application behaves in situations which are not so exceptional. We&apos;re actually talking here about expected, supported events like what happens when the user is not authenticated or when some entity doesn&apos;t exist. &lt;/p&gt;
&lt;p&gt;Let&apos;s consider a case where &lt;code class=&quot;language-text&quot;&gt;Ctrl&lt;/code&gt; throws an exception.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/control.002-935894220a2d68f1cfe53f23b159eb07-66ccb.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 24px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 71.05263157894737%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAOABQDASIAAhEBAxEB/8QAGQAAAQUAAAAAAAAAAAAAAAAAAAECAwQF/8QAFgEBAQEAAAAAAAAAAAAAAAAAAgED/9oADAMBAAIQAxAAAAHZjsJQDwaf/8QAGhAAAgIDAAAAAAAAAAAAAAAAAQIAEgMQEf/aAAgBAQABBQLKSqK78usIldf/xAAXEQADAQAAAAAAAAAAAAAAAAAAAREh/9oACAEDAQE/AY6Yf//EABcRAQADAAAAAAAAAAAAAAAAAAARIUH/2gAIAQIBAT8ByFv/xAAZEAACAwEAAAAAAAAAAAAAAAABMQACESD/2gAIAQEABj8CJq5XQ3Hx/8QAGRAAAwEBAQAAAAAAAAAAAAAAARExABCh/9oACAEBAAE/IfCA9d7GEsCSMwFXCGZz/9oADAMBAAIAAwAAABD0z//EABYRAQEBAAAAAAAAAAAAAAAAAAEQEf/aAAgBAwEBPxBTYx//xAAaEQACAgMAAAAAAAAAAAAAAAABEQAxUZHh/9oACAECAQE/ECWq3cWY12f/xAAcEAEAAwACAwAAAAAAAAAAAAABABEhMWFBUZH/2gAIAQEAAT8Q1rFUdnqMewRCQHGpc6Wpx5g4ou3mAja+QLT9lB4J/9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Exceptions are breaking control flow&quot;
        title=&quot;&quot;
        src=&quot;/static/control.002-935894220a2d68f1cfe53f23b159eb07-66ccb.jpeg&quot;
        srcset=&quot;/static/control.002-935894220a2d68f1cfe53f23b159eb07-9e994.jpeg 300w,
/static/control.002-935894220a2d68f1cfe53f23b159eb07-c6a92.jpeg 600w,
/static/control.002-935894220a2d68f1cfe53f23b159eb07-66ccb.jpeg 608w&quot;
        sizes=&quot;(max-width: 24px) 100vw, 24px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The beginning of &lt;code class=&quot;language-text&quot;&gt;MidA&lt;/code&gt; is executed all the way to the moment when it calls the next middleware, that is &lt;code class=&quot;language-text&quot;&gt;MidB&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;MidB&lt;/code&gt; is executed all the way to the moment when it calls &lt;code class=&quot;language-text&quot;&gt;Ctrl&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;Ctrl&lt;/code&gt; then throws an exception none of the middlewares knows about. The execution never comes back to the middlewares. They are never finished.&lt;/p&gt;
&lt;p&gt;After I faced this problem I decided to take a look at other people&apos;s code in the hope of finding a solution which wouldn&apos;t require rewriting the existing code. The only thing I found was to register an event handler (with the proper priority) and finish the broken control flow within this event handler. To be honest, I find this unbelievably complicated. The flow of control is broken into implicitly connected tiny pieces of code which are scattered all over the codebase. It&apos;s very hard to answer questions which seem to be trivial, like &quot;is the second line of this method going to be executed?&quot; or &quot;which piece of code will run next?&quot;.&lt;/p&gt;
&lt;p&gt;I used to be a big fan of exceptions. I read about them in Java books, learnt how to catch them. But with time I grew to dislike them. I&apos;ve noticed the hidden GOTO. When I&apos;m writing a function which may return 3 different values, I simply make it return 3 different values. I don&apos;t pick my favorite type just to make the two remaining ones jump somewhere else dressed as exceptions. &lt;/p&gt;
&lt;p&gt;I value the explicit, clean control flow exception-less code gives me. It&apos;s simple. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[State management in JavaScript: data-related state and behavior-related state]]></title><link>https://coder.earth/post/behavior-related-state-and-data-related-state</link><guid isPermaLink="false">https://coder.earth/post/behavior-related-state-and-data-related-state</guid><pubDate>Sat, 24 Mar 2018 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/data-related-state-and-behavior-related-state-4f1303f4c045da6d69c00170483e598f-ccf29.jpeg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 51.642857142857146%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAKABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe5dCKP/xAAXEAADAQAAAAAAAAAAAAAAAAABESAh/9oACAEBAAEFAnpn/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAIP/aAAgBAQAGPwJf/8QAHBAAAQMFAAAAAAAAAAAAAAAAAAERQRAhMVHw/9oACAEBAAE/IYGk7cTAyar/AP/aAAwDAQACAAMAAAAQ08//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAZEAEBAQEBAQAAAAAAAAAAAAABESEAQRD/2gAIAQEAAT8QAIbdN6ICK+SOYiXM3tlivs+//9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Data-related state and behavior-related state&quot;
        title=&quot;&quot;
        src=&quot;/static/data-related-state-and-behavior-related-state-4f1303f4c045da6d69c00170483e598f-19371.jpeg&quot;
        srcset=&quot;/static/data-related-state-and-behavior-related-state-4f1303f4c045da6d69c00170483e598f-c766d.jpeg 300w,
/static/data-related-state-and-behavior-related-state-4f1303f4c045da6d69c00170483e598f-f0d1c.jpeg 600w,
/static/data-related-state-and-behavior-related-state-4f1303f4c045da6d69c00170483e598f-19371.jpeg 1200w,
/static/data-related-state-and-behavior-related-state-4f1303f4c045da6d69c00170483e598f-ccf29.jpeg 1400w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;State management is a hot topic in the JavaScript world. &lt;/p&gt;
&lt;p&gt;Some libraries promote the use of immutable data structures, while other allow mutations. &lt;/p&gt;
&lt;p&gt;Sometimes the whole state is stored in one place, other times it&apos;s distributed among many objects.&lt;/p&gt;
&lt;p&gt;Not every state container is about pulling things out of it. There are also Hollywood-like (push) solutions which actually call us. &lt;/p&gt;
&lt;p&gt;We have various ways to transform events into state changes as well.&lt;/p&gt;
&lt;p&gt;And what&apos;s nice is that it&apos;s not just a theoretical thing. It&apos;s not uncommon to find at least few implementations of each combination of these characteristics!&lt;/p&gt;
&lt;p&gt;This wide choice of state management techniques gives us the possibility to pick the one we feel comfortable with. If there&apos;s a tool which helps us turn business requirements into working software without too much struggle, it&apos;s a good tool. It doesn&apos;t necessary need to be the exact same thing other people use.&lt;/p&gt;
&lt;p&gt;I do really love the richness of the JavaScript ecosystem!&lt;/p&gt;
&lt;p&gt;However, all the popular state management solutions I know about, in all their richness, focus solely on dealing with key-value pairs.&lt;/p&gt;
&lt;p&gt;Let&apos;s have a quick look at some key-value pairs. I wrote them on a whiteboard, because the whiteboard doesn&apos;t put many restrictions on the syntax. &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/data-related-state-50f2e9a7f0553e6f88b772ddb307dad6-8b75e.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 800px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 74.125%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAdtIsD//xAAYEAADAQEAAAAAAAAAAAAAAAAAARECIv/aAAgBAQABBQK7vQiEYqf/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAaEAACAgMAAAAAAAAAAAAAAAAAARAxITKR/9oACAEBAAY/AtV0qHkuP//EABwQAQACAwADAAAAAAAAAAAAAAEAESExUUFhgf/aAAgBAQABPyH0C9woWrciXZU5LMpKPPaQAy38n//aAAwDAQACAAMAAAAQcw//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAaEAEBAQEBAQEAAAAAAAAAAAABESEAQVEx/9oACAEBAAE/EIRTyQy/snTlNIoZN4BVYyPvDMPbkxfe2SrUGHzoA39x3//Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Data-related state on a whiteboard&quot;
        title=&quot;&quot;
        src=&quot;/static/data-related-state-50f2e9a7f0553e6f88b772ddb307dad6-8b75e.jpg&quot;
        srcset=&quot;/static/data-related-state-50f2e9a7f0553e6f88b772ddb307dad6-5df75.jpg 300w,
/static/data-related-state-50f2e9a7f0553e6f88b772ddb307dad6-dcc9d.jpg 600w,
/static/data-related-state-50f2e9a7f0553e6f88b772ddb307dad6-8b75e.jpg 800w&quot;
        sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Making it part of a JavaScript program isn&apos;t hard.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Łukasz&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  favDish&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pizza&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&apos;s it! Isn&apos;t it a wonderful example of a readable, easy to understand part of a program?&lt;/p&gt;
&lt;p&gt;I have that feeling that due to their commonness key-value pairs may be underappreciated. All we need to do to leverage their power is to write a bunch of values with their corresponding keys and then refer to them using those keys. &lt;/p&gt;
&lt;p&gt;Let&apos;s say there&apos;s a &lt;em&gt;person&lt;/em&gt;. Discovering the favorite dish is that simple:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; favDish &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; person&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;favDish&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There&apos;s no need to work with pointers, not even numeric indexes! The beginning and the end of data is held under the hood in such a convenient way that in the vast majority of cases we don&apos;t even need to think where exactly the actual data ends and garbage memory starts. So many hardware-related aspects of data access are abstracted away! The actual programming looks very much like taking human-readable notes on a whiteboard!&lt;/p&gt;
&lt;p&gt;It all makes key-value pairs a model suitable for data-related state, that is state which may usually be consumed without using conditionals. As we can see, it plays well with other declarative techniques such as JSX.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;My name is {person.name} and my favorite dish is {person.favDish}.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Even though I do really enjoy using key-value pairs to model data, I must admit that every time I try to use them to describe changes of behavior, they make me struggle. &lt;/p&gt;
&lt;p&gt;In order to illustrate my concerns, I&apos;d like show you yet another whiteboard drawing. In this picture I captured all the main screens of a wizard-like application as well as the events which make one screen change to another. To put it another way, it&apos;s about behavior-related state.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/bunny_graph_whiteboard-9dacc6411fa1e148984dbc2677fffb7b-b3be4.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1000px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 64.3%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAEDBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAey0FUf/xAAYEAEAAwEAAAAAAAAAAAAAAAABABARMf/aAAgBAQABBQJnAdE2ZX//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAYEAACAwAAAAAAAAAAAAAAAAAAIQERIP/aAAgBAQAGPwJlws//xAAcEAEAAgMAAwAAAAAAAAAAAAABACExQVERcYH/2gAIAQEAAT8hflSn2OxZplxOpPUytU5KME//2gAMAwEAAgADAAAAELAP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGxABAAMBAQEBAAAAAAAAAAAAAQARITFRQWH/2gAIAQEAAT8Q1iDABv7DeILY2J32UCEfsJCN9XZtKgq3IGIB3Cf/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Behavior-related state on a whiteboard&quot;
        title=&quot;&quot;
        src=&quot;/static/bunny_graph_whiteboard-9dacc6411fa1e148984dbc2677fffb7b-b3be4.jpg&quot;
        srcset=&quot;/static/bunny_graph_whiteboard-9dacc6411fa1e148984dbc2677fffb7b-27d6e.jpg 300w,
/static/bunny_graph_whiteboard-9dacc6411fa1e148984dbc2677fffb7b-5d038.jpg 600w,
/static/bunny_graph_whiteboard-9dacc6411fa1e148984dbc2677fffb7b-b3be4.jpg 1000w&quot;
        sizes=&quot;(max-width: 1000px) 100vw, 1000px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;It&apos;s nothing but a directed graph.&lt;/p&gt;
&lt;p&gt;An attempt to express it with key-value pairs shows that the graph is completely lost.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; someState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
  isABunnyOwner&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  enteredTheWholeName&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  hasACarrot&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  finishedFeeding&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;repeat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;prevState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
  isABunnyOwner&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; undefined&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  enteredTheWholeName&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  hasACarrot&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; prevState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hasACarrot&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  finishedFeeding&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;isABunnyOwner &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; enteredTheWholeName &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;finishedFeeding&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What we can see here are not boxes and arrows, but boolean flags and IF statements.&lt;/p&gt;
&lt;p&gt;Listing all the possible screens or discovering how the user may go from one screen to another becomes a challenge. It&apos;s not so easy anymore like it was when key-value pairs were used to model just data. Now there are boolean flags and IFs to think about. &lt;/p&gt;
&lt;p&gt;Some of these problems may be mitigated by extracting functions and grouping them together so they are easier to find. But is it the way to go, or maybe just an attempt to bend an inappropriate model to our needs?&lt;/p&gt;
&lt;p&gt;They say that if all you have is a hammer, everything looks like a nail. It seems that it applies to state management as well. If all we have are key-value pairs, everything looks like a value or a key.&lt;/p&gt;
&lt;p&gt;Let&apos;s step back and try to find a more suitable model. How can we make the drawing visible below part of the program?&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/bunny_graph_whiteboard-9dacc6411fa1e148984dbc2677fffb7b-b3be4.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1000px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 64.3%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAEDBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAey0FUf/xAAYEAEAAwEAAAAAAAAAAAAAAAABABARMf/aAAgBAQABBQJnAdE2ZX//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAYEAACAwAAAAAAAAAAAAAAAAAAIQERIP/aAAgBAQAGPwJlws//xAAcEAEAAgMAAwAAAAAAAAAAAAABACExQVERcYH/2gAIAQEAAT8hflSn2OxZplxOpPUytU5KME//2gAMAwEAAgADAAAAELAP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGxABAAMBAQEBAAAAAAAAAAAAAQARITFRQWH/2gAIAQEAAT8Q1iDABv7DeILY2J32UCEfsJCN9XZtKgq3IGIB3Cf/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Behavior-related state on a whiteboard&quot;
        title=&quot;&quot;
        src=&quot;/static/bunny_graph_whiteboard-9dacc6411fa1e148984dbc2677fffb7b-b3be4.jpg&quot;
        srcset=&quot;/static/bunny_graph_whiteboard-9dacc6411fa1e148984dbc2677fffb7b-27d6e.jpg 300w,
/static/bunny_graph_whiteboard-9dacc6411fa1e148984dbc2677fffb7b-5d038.jpg 600w,
/static/bunny_graph_whiteboard-9dacc6411fa1e148984dbc2677fffb7b-b3be4.jpg 1000w&quot;
        sizes=&quot;(max-width: 1000px) 100vw, 1000px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;What if we could just open an editor and draw it like this?

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/bunny_graph_editor-8f72254778245a0e1e6cf45d0c4e689e-596bb.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.97920277296361%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsSAAALEgHS3X78AAABdUlEQVQoz41TW4rCQBCcW3sE7+CXR1lRPxSji36o5EEwCJrE9yPRJNamep2QHVh2C5rJkJnq6uoehTder1e1MvI8R5ZleD6feDwesv4Hqk6igzifz/jodNDv9zEYDDAejxEEAfb7PeI4xna7xXK5hOu68DwPjuPger1CaQKNolQWRRE2mw0mk08kSVKqLUQtldZjvV7DLolmsxls28HtdvtWWBSFkDCz7/uYz+dIS6K/QFuoOAxDqYhJlfaLWbrdLkajEabTKU6nE3a7nQQvcX+5XHC/30Vdmqbia1YGy6Y6cimdbbVa4XA4yCGq5SUqZzKWTfVUwTNMwpVJbNtGr9eT/9IUmttut8VkDRLS5DiK5dJvYKlyriRL3hYpym02m9Ih0x8SM+qgcnabXieGzz9K1lgsFhgOh9X+eDyKR7SCatlZeqmng7bUx61qCn8QrVYLjUajOsAZ4yxaliXzyL35GOrfyhxoE+wm7aAqBkuuPwaT+AsH+0oLwngELwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Behavior-related state on a whiteboard&quot;
        title=&quot;&quot;
        src=&quot;/static/bunny_graph_editor-8f72254778245a0e1e6cf45d0c4e689e-86d16.png&quot;
        srcset=&quot;/static/bunny_graph_editor-8f72254778245a0e1e6cf45d0c4e689e-bd9cb.png 300w,
/static/bunny_graph_editor-8f72254778245a0e1e6cf45d0c4e689e-fe5c6.png 600w,
/static/bunny_graph_editor-8f72254778245a0e1e6cf45d0c4e689e-86d16.png 1200w,
/static/bunny_graph_editor-8f72254778245a0e1e6cf45d0c4e689e-596bb.png 1731w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The code could then forget about the past. There would be no boolean flags at all! IF statements would be unnecessary. This approach could make the complicated code we&apos;ve seen totally disappear. &lt;/p&gt;
&lt;p&gt;Well, it&apos;s actually possible! A directed graph like that is a representation of a finite automaton, that is one of the fundamental concepts in computer science. Method calls may be dispatched based upon the current state of the state machine. Thanks to the development of Graphical User Interfaces, we&apos;re not tied to text-based interfaces. We can simply draw our graph using a visual editor. This is how we get into the world of visual automata-based programming, where drawings of graphs are not less important than key-value pairs.&lt;/p&gt;
&lt;p&gt;The editor screenshot visible above comes from an article about &lt;a href=&quot;/post/react-and-visual-automata-based-programming&quot;&gt;React and visual automata-based programming&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[An introduction to visual automata-based programming in Rosmaro]]></title><link>https://coder.earth/post/an-introduction-to-visual-automata-based-programming-in-rosmaro</link><guid isPermaLink="false">https://coder.earth/post/an-introduction-to-visual-automata-based-programming-in-rosmaro</guid><pubDate>Fri, 02 Mar 2018 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/logo-fabd92b648ca0659eb9108ca05326198-844e5.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 192px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAC4jAAAuIwF4pT92AAADMklEQVQ4y32TSUwTYRSAhy2e9OAaDyJhkWDUuIQEcEWQQLBYjGVpaVlswcKU0nW6UKDMdJkCDqUWO0DpgghWRIwXEz2ZaIye3GIwejRy8AJRiZTOc6aK0UT4kz/v5S3fe////h/ZvXMbIlK5EhB2FVR15vimbz+j3B7oH6Dg2ggN/DrVac4nkpsSA2QnclnAQzZc00MEIm63xYHlYlPW4DD9pU2hglaFanlo+DoIayRVnM+iUaVw8vEtGkElgo2huKo5kZNaqfCoD9czLrUUBjH56qARBVzZ9OoSr3QH5w+4LMmcfPNgClGsB9XJ6pDnM3Qc6LF0TES8DvDhuqjfaQbahq2O9HSA32l6jTbU7uJiJqne5LXcx9M0wis68S/QqpTGj9ujQTMmSOO3KZqCsIdkpv1eJuy2w3Bn20qINML90YEPrWJBBhcLS+8TfYQhcY2hviz86w7deLzimNPcPuvphXGyMxoa6GFCFM4ESBMTtOvApZGu3L1GwJzP9RnXyAvXcucfRf5AD2ZnIPwSdn7w42O8wyBpnrozZIVxmy4acmIQYEEBu54JOjDmKnYFaKsqGqG6ITKEAzvIh5RFfZzL+/TkXtIkZU1+MTuaJK/h/Spg1OlS/HZs/ma/mQPG3KY2ZgzXQshpgN9AZozQcgVi3J7zEnDPR8Kow4z+dzBtYkFa2GX+zgaDo6Mp5lA2MLb2emakVx0Lk0ZmQN8CrA5hp4HrOOYndD/YYsyMh4BQXxcZ7u822tXNgZbq80VxoKy2MmOizxz1WhRAqhrBjTVDv7oJKMMVuNFngj6tjBnEWphxtsugQw8TpAEmWbuf0IC3S8meSs/qWlCKLz5FqsvO5BqbhZTfpgMrKlkgUPGii4U5OxqWsSbBu1FcE6XYO+xpFQGOir+z3S8RCslCt1w0pxDyRKnbt2zNzUnfW3AoO1VaWbwJUdRVvqStavCY0UVJRfHJ3P2Z26tLTxXwz+bHnwihbAyGHBg41TKo55eYWFNy2YljW9b9JcX5RzYfyEzL25++J+d//nN5h7PEvKKIsLywK/fAvl1rdvj6NsEkq0mqv3AuoZFfktDAblRYgfwEpYOHfXn5vEoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The Rosmaro mascot&quot;
        title=&quot;&quot;
        src=&quot;/static/logo-fabd92b648ca0659eb9108ca05326198-844e5.png&quot;
        srcset=&quot;/static/logo-fabd92b648ca0659eb9108ca05326198-ab421.png 300w,
/static/logo-fabd92b648ca0659eb9108ca05326198-9f536.png 600w,
/static/logo-fabd92b648ca0659eb9108ca05326198-844e5.png 800w&quot;
        sizes=&quot;(max-width: 192px) 100vw, 192px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;To do automata-based programming is to program with states and transitions. States correspond to different behaviors. Transitions are named after events and describe how those behaviors change.
The easiest way to think about this is a directed graph. Here’s an example of a cursed prince:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/directed_graph-7315623d2bb2e05f4e26d41771101dd1-0a4b0.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 394px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 11.928934010152284%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAiUlEQVQI1x2NOwqEMAAFvZh7PA/gWSxTq52FiBsLw2oUNLIpAsEfzLopHlO8gYn6XpGmKXmec10X+77jvWdZFsZxRGuNtZbzPMP+zn3fgcdxBHeeZ5RSfB8vyrKMOH6RJAnOOaZJh1MIgZSSpmlo2zfbtjEMH6YnsK4mhIwxVFVFWRbUdU3XdfwApImPCRFJwvUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A very simlpe, directed graph&quot;
        title=&quot;&quot;
        src=&quot;/static/directed_graph-7315623d2bb2e05f4e26d41771101dd1-0a4b0.png&quot;
        srcset=&quot;/static/directed_graph-7315623d2bb2e05f4e26d41771101dd1-99e1d.png 300w,
/static/directed_graph-7315623d2bb2e05f4e26d41771101dd1-0a4b0.png 394w&quot;
        sizes=&quot;(max-width: 394px) 100vw, 394px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;It may be either a Prince or a Frog. The Prince eating a pizza is an event which causes a transition from the Prince state to the Frog state.&lt;/p&gt;
&lt;p&gt;I’m going to show you how to do (visual) automata-based programming in Rosmaro.&lt;/p&gt;
&lt;p&gt;Rosmaro is a JavaScript library which allows you to build stateful objects.&lt;/p&gt;
&lt;p&gt;An object is stateful when two identical method calls may produce different results.&lt;/p&gt;
&lt;p&gt;Here’s an example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;introduceYourself&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;token string&quot;&gt;&apos;I am The Prince of Rosmaro!&apos;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;dish&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;yakisoba&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
undefined
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;introduceYourself&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token string&quot;&gt;&apos;I am The Prince of Rosmaro!&apos;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;dish&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pizza&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
undefined
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;introduceYourself&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token string&quot;&gt;&apos;Ribbit! Ribbit!&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Another great example of stateful objects is a Graphical User Interface. Think of an ATM. You can look twice at its screen and see different messages and fields. Your eyes are the same. The way you look at the screen hasn’t changed. It’s the state of the ATM that changed. Maybe you selected some option by clicking a button, or maybe some timer kicked in. Something caused a transition from one state to another.&lt;/p&gt;
&lt;p&gt;Below are few examples of front-end applications built using visual automata-based programming.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/todo-c127bc411905f4a0855ab2b8978827ea.gif&quot;&gt;&lt;/p&gt;
&lt;p&gt;The codebase of this To-Do application consists of no boolean values.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/bunny_app-ef71f5ae611c7b18df837a3e041d9244.gif&quot;&gt;&lt;/p&gt;
&lt;p&gt;This wizard has two paths. There’s no IF for that.&lt;/p&gt;
&lt;p&gt;The Rosmaro way of building stateful objects is to &lt;strong&gt;combine a drawn graph with some written code&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The graph shows all the possible behaviors and what makes them change. The fact that it’s drawn using a visual editor makes it a visual programming tool.&lt;/p&gt;
&lt;p&gt;Each behavior is expressed as a bunch of pure functions. A function may return some result as well as a request to follow an arrow.&lt;/p&gt;
&lt;p&gt;Rosmaro stores the whole state of a model in a pluggable storage mechanism. It may be everything from a plain-old JavaScript object to a NoSQL database. It also uses pessimistic locking to prevent going into an inconsistent state.&lt;/p&gt;
&lt;p&gt;The example I want to show you concerns a prince who turns into a frog when he eats a pizza.&lt;/p&gt;
&lt;p&gt;First, open the &lt;a href=&quot;https://rosmaro.js.org/editor&quot;&gt;Rosmaro editor&lt;/a&gt;. Then, click the &lt;em&gt;LOAD&lt;/em&gt; button to start a new project.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/new_graph_project-50ac4a3f8cc862fd1468c5edd02d92e1-2fec7.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 700px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAABz0lEQVQ4y6WTXW7TQBDHA7fgCByAW9RCHIGHwBO1VNWJ2iBeeOAsHCIpDwhVUZ1KGKigTt243mLXrNvYrj/XM+wOxIpEEioY6a/Zmdn9aVY723GOjx+dnBw9uWBsy3M97cw+09xzVwuvQi3wA212PqOcd+FRzDym2d9szf5qa87Uofz0dPr48MPhg44y95M1jNPvGHKO85s5RjwiJUmCt+ktRlGEEk61LMswjmPkPzjpOrqmfDyPcTQcPSVgEIYHKG1imrU5MeGjZYElNRyOYOa60DQNVFVFKsuyXf9WIyXo/GTyjIC+749UIgiCmjEGnHOQnYDsBPI8XweCqmzXBDRNswVShxIi0jRFCSEVRYFCCASATQK5p1kJlFcTy5tlTP4vthm48sSGDu8EXHPwl1dLwLsD6aog/rjqP3UoazW2PSCUQr50HkFRZxQrxHJ9IaFebhkox4WASV7VNxkH6/I9uOEpOFdfyBdVoR6T5nGVFsB2Di8Ze6cSb48smPoeOv5njJM5lkWFompofBajtErq9ygbj8fPCWgYxtb+3v6O9NuDvZf661dvdBnrvZ6hG8au9D293++v07aqDwaDF91u92Fnye7/p+4piGy08xNXU3sch18JxAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;new graph project&quot;
        title=&quot;&quot;
        src=&quot;/static/new_graph_project-50ac4a3f8cc862fd1468c5edd02d92e1-2fec7.png&quot;
        srcset=&quot;/static/new_graph_project-50ac4a3f8cc862fd1468c5edd02d92e1-e3f4e.png 300w,
/static/new_graph_project-50ac4a3f8cc862fd1468c5edd02d92e1-e6afe.png 600w,
/static/new_graph_project-50ac4a3f8cc862fd1468c5edd02d92e1-2fec7.png 700w&quot;
        sizes=&quot;(max-width: 700px) 100vw, 700px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Add the main graph.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/adding_first_node-6a15be722af7d5560427d71e8c6c94b2-2fec7.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 700px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAABu0lEQVQ4y62T3UrDMBSAp2/hI/gAvoVFfARh6JUOhA1lOsQLQfBNBO8FNUORgUN0FXXadvZna+pcf3SFtuvPMYmb04o60APfRU6aLyenSUa7upqSJH4WP7anH7HBNcQGJzdkDuuYIT/InCRInKZqnEHmm1qTE+4ETqgL7FuaF+/FmcppZSJDo3F5cfjUkaFlGNB56oBlWuDYDniex3AcB8yOCd2XLvi+D67rgm3ZjGfnmeXdrgtlVJ5jQkEUkWXaoChKiDFOwjBkDAIA3kmPCTEhIgDP8/NM2G63j2gijuMwiqIkCAIm/ChJy1M5JqzVam9CwzAQTZDjREQGFCKkq0ZhUOVQqGMd0U2IKOr1hsJBsDXpgw7nvgq1loKsQCei3j8JdRXZAe5X2BtJmPSt31SoItNvgUd66PkB6eWfe6igB6dC2hiEbP84Skilyajx5S+f1e/RvijCiaSEe3w9OVd1Io3TXfuJz/fw7Pq2fCypcMDfJLvVS6hpOoSkl37/Cv0GfT00qtXqAhOWVlemt0try5urK0s7G+u5rdJ6Ll8o5AqjsZTP53PFYnExm81OZj7E+B8ZoxJSaOYVell9b5exOUAAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;adding first node&quot;
        title=&quot;&quot;
        src=&quot;/static/adding_first_node-6a15be722af7d5560427d71e8c6c94b2-2fec7.png&quot;
        srcset=&quot;/static/adding_first_node-6a15be722af7d5560427d71e8c6c94b2-e3f4e.png 300w,
/static/adding_first_node-6a15be722af7d5560427d71e8c6c94b2-e6afe.png 600w,
/static/adding_first_node-6a15be722af7d5560427d71e8c6c94b2-2fec7.png 700w&quot;
        sizes=&quot;(max-width: 700px) 100vw, 700px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/adding_main-0b668c5ba03d67baf1c0b965d2713c1f-2fec7.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 700px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB70lEQVQ4y6WTy27TQBSGA2/BI/AAvEUtxIo1UqCr1hIoSd0UuigrNjwAz0B37IBESCGAFyUpVGl9iUOceur6Fmzq2GPPYWZyIbgKVOqRPlnz+/jTmbFdGh4e3tG07j3rzF47s5Cgq7pg6IZgnVoco28ImqIJwx9DAdH75tAUlGNFUHoK72W5eqLebbfat0qs9K8H784dA0YIgXPugOd6EPgBxHHMCYIAXMeF8GcIk8kEoigC3/M542DM8yiMoNloPuBCRVUbnuvDYDDAlmURjDFnXgCwoLim5JSMAt1u9xEX2rb9ngV5nuMsy0iSJFy4LCnKCxkXdjqdqRAh1GAB3U5GZcCgQvbUVZhPeVlIRVmapjNhCtNemF6LG53Vf4V/JswWsmsJcYqBEScXtDlfOSEBslpoLYQ480IHxpEPI0+DGP8qTHnFM3RtuzHbAUZej2TpBRl5fZLgmM+Tk3/XpbcsHyuNlunC2xMZv/r4hhxZEemhNkGhUTy5Vfz9HX75ftT8oJ3CvrxPXh+04JvpQH/UA+SakNPWz30bPukDYAv2p8xf3ByWsZJleZ0Ln0nS2ovdp493azubL/eei3s7klh9IolSbVusVmvi/YcblHVxe2tLrFQqNKsus8myer2+US6Xb5eW6uY1ucEkdNDSb6wTevP1nPp0AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;adding main&quot;
        title=&quot;&quot;
        src=&quot;/static/adding_main-0b668c5ba03d67baf1c0b965d2713c1f-2fec7.png&quot;
        srcset=&quot;/static/adding_main-0b668c5ba03d67baf1c0b965d2713c1f-e3f4e.png 300w,
/static/adding_main-0b668c5ba03d67baf1c0b965d2713c1f-e6afe.png 600w,
/static/adding_main-0b668c5ba03d67baf1c0b965d2713c1f-2fec7.png 700w&quot;
        sizes=&quot;(max-width: 700px) 100vw, 700px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Click &lt;em&gt;NEW NODE&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/clicking_new_node-90c9663eeaf34dd8b4d8eaf24f1d6b1a-2fec7.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 700px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAACG0lEQVQ4y6WSy27TQBSGA2/BI/AArFh1H6tCSCyKhLiEsqIWSLlIEbRih5AQLwDLLAsrdiURFUpRKrVOCk1sx3HjEE9ujkss5WJ7DmcmTmpXLRLil37N+Pj4m3OOJ9asVG6o9fIts9ONd0wiaKom6JoumG2TW2/oQl2pC0bTEAi+bxktQakpglJVeC6Lq7K6WvxWvBZj0g4PdvoDHX4RAv1eH6yBBfbQhvF4zG3bNgz6Axj9HsFkMgHHcWBoDblP7VMed0YOFPKFBxxYVZR8t2dB8+TEJYRQ13Wp53l0IQBY+vwz2kd7aCiXy+scaLTNLzCXy5IYzPf9JSCsMDgkDpQkaQ7sEJJnAWzHm06nwIxVQlhz1nwN70NVngFJAESQN5vNIkB8x2cYgdGzAzCXYo4fafkiILbNnU6nIZfL8Y9xDEsg2zPJskwxx2c/q1arXQ5kazCG5f6iCtmsMSfashkAxzhDNFuxZazQd4MR/eMMB91ufp4REHyKV8enWu8HnbnTgPFXRf/yvqzmd40OfFV1d1uqUqnVpkftAnXG1vk7d5mj9/D70c/CbsOAotqgn6RjePbxM7zb2YYPe4fwfu8AcvsVdhgbGJ/p4motzGJMpVLpCQe+yKTjb7Y2n7/efLnx9tWWGL//WFx9KIo376yh74ora/fE24/WxWwmIyaTSTGVSoW9wWLZbPZpIpG4Hgvp6n/6CoNgobE/BTZyFJRzQI8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;clicking new node&quot;
        title=&quot;&quot;
        src=&quot;/static/clicking_new_node-90c9663eeaf34dd8b4d8eaf24f1d6b1a-2fec7.png&quot;
        srcset=&quot;/static/clicking_new_node-90c9663eeaf34dd8b4d8eaf24f1d6b1a-e3f4e.png 300w,
/static/clicking_new_node-90c9663eeaf34dd8b4d8eaf24f1d6b1a-e6afe.png 600w,
/static/clicking_new_node-90c9663eeaf34dd8b4d8eaf24f1d6b1a-2fec7.png 700w&quot;
        sizes=&quot;(max-width: 700px) 100vw, 700px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Add a local node called &lt;em&gt;Prince&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/adding_the_prince-c1cc8a1950f41e35d31e9da027a7bbc5-2fec7.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 700px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB+0lEQVQ4y6WS3YrTQBTHq2/hI/gA3vgMG8QbQbwSisteuBGhzUKR6pXg+gxeFrxxr7wRuu3NskLBtlmUzUfTtKmbaZukWVtsmo85npl2u0mxyOIf/mQyc+Y355yZXP/s7J7ekR/aw9HO0CaCoRuCaZiCfWFzm11T6GgdwepbAsH1gTUQNEUTtHONx7J5XdUfnJ6c3skxGa1m1XFN+EkIOGMHPNcDf+LDfD7n9n0fXMeF6a8pBEEAs9kMJt6E+9K/5POz6QzqtfpTDjzXtNpo7EG/14sIITSKIhrHMb0SAKy9+Y9O0DEaZFl+xoHWhX0MS0UsiMGSJFkD0kqDU+LAdru9BA4JqbEJLCdeLBbAjFlCWkvW8psep7K8BpIVEEFxGIYZIK7xHmZg9PoAjKUYk2RK/hsQy+aWJAkqlQrfjG1YA9mYSVVVijEJuyxFUTaBWHKYLZkFskO2Zch6jTGbJQ850HL1+DcCghXwatONe+iNHQ4c+V1+y5DEdBGG9AbK3vI3rVs77hnwsXkUHckqbQ/szbf2L2ffYeO7Uq+qKnxufaGfWj/gXfUEPnxtYgsmkGDpweopbTPrM1Oj0djlwFcH0s5hufzy8PXb/fdvyuLj3T3x/qMn4p74QjyQJLFQLIrF7d4vFApiqVR6ns/n7+ZSuv2fvsUgmGjuD96idiHqDi25AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;adding the prince&quot;
        title=&quot;&quot;
        src=&quot;/static/adding_the_prince-c1cc8a1950f41e35d31e9da027a7bbc5-2fec7.png&quot;
        srcset=&quot;/static/adding_the_prince-c1cc8a1950f41e35d31e9da027a7bbc5-e3f4e.png 300w,
/static/adding_the_prince-c1cc8a1950f41e35d31e9da027a7bbc5-e6afe.png 600w,
/static/adding_the_prince-c1cc8a1950f41e35d31e9da027a7bbc5-2fec7.png 700w&quot;
        sizes=&quot;(max-width: 700px) 100vw, 700px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Then, add a local node called &lt;em&gt;Frog&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/adding_the_frog-ae2271927119687cadd9b6e56a7ceea1-2fec7.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 700px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAACB0lEQVQ4y6WST4vTQBjGq9/Cj+AH8OJn2CBeBPEkFJc9uBGh3YUiXS8eVj+DZ08SwUth1/ayRCh0+wexm7TZNKnNpJs0WZv+STLJ68w0Kc2ui4oPPAwzmfzmed+ZnNbp3Ov12w8Nc7xlGohTegqnKipnjAxm9Vzl+nKf0zWdQ+T7UB9y8pnMyV2Z7aXrPan3QDwR7+SolObpsWWr8AMhsC4smNgTcB0XFosFs+u6YFs2TH9OYblcgud54Ewc5kv3kq17Uw9q1dpTBuzKcnV8MQFtMAgRQnEYhjHGOE4FAGtfnRNHxJgY2u32MwbUR8YXWCmkmygsiqI14C/EgK1WawU0EarSBVIO9n0fqElK2BQNtgqXnSeJowwQJUACwkEQrIF0bzqmMNrD+Xy+CY1ns1mUKfl3QFI2+1nTdDamQFEUoVKprIG0NYIgRPQQSZKywMAPsB/4mYSbpiIAdlgKTHqeLdk0xww4cgYEiGFBEjFgtovXepiM13voWDYDmo7CbhlwGPtBEP+DsrfckNXq0XkfPjQ+h0JHjpvD0dW39idn32H921ntSOqC0PgUf2x+h8PjE3j/9RR024GIlL5MntJNppdGVa/Xtxnw1X5x6+1B+eVh+c3uu9dl/vH2Dn//0RN+h3/B7+/t8YVikS/e7N1CocCXSqXn+Xz+bm5Dt//TtyiEBM39AoqUeHTOXkFFAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;adding the frog&quot;
        title=&quot;&quot;
        src=&quot;/static/adding_the_frog-ae2271927119687cadd9b6e56a7ceea1-2fec7.png&quot;
        srcset=&quot;/static/adding_the_frog-ae2271927119687cadd9b6e56a7ceea1-e3f4e.png 300w,
/static/adding_the_frog-ae2271927119687cadd9b6e56a7ceea1-e6afe.png 600w,
/static/adding_the_frog-ae2271927119687cadd9b6e56a7ceea1-2fec7.png 700w&quot;
        sizes=&quot;(max-width: 700px) 100vw, 700px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Put your mouse cursor over the &lt;em&gt;start&lt;/em&gt; entry point and draw an arrow to the &lt;em&gt;Prince&lt;/em&gt; node. Then, draw an arrow from the &lt;em&gt;Prince&lt;/em&gt; to the &lt;em&gt;Frog&lt;/em&gt; and call it &lt;em&gt;ate pizza&lt;/em&gt;. Finally, click &lt;em&gt;ADD NODE&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/drawing_an_arrow_from_start-372db0d30371a7c238c10dee28c2e993-ccd31.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 151px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 80.13245033112582%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABYlAAAWJQFJUiTwAAABi0lEQVQ4y62UsWvCQBTGs7laXWstMYOzg5PF3cFuLRTrX2DIJG4VBJ0Edx3ESRCCW0DQTSc3B3FzcBKDICqIifnaO7hgjJ4GevBy5L673717790J+OcmkI9lWWD9LTvXz9e4gF5ghmHgdDrxgTyRtUudB3V4uFqtsF6vsdvtqC2XS2y3W6qTcVVVMRwObSgXSACDwQDlchm5XA6KoqDZbGIymVC90+lAEAT0+336b5omP4aHwwGtVosuYpZMJrFYLDAajdButzEej3E8Hl0JcgGZUKvVKMjn89E+Fouh0Wig2+1yY+oAMten0yne02mHh4FAALIs25NJlu+WDQtwpVJBNBpF6OUVodAzRFGEJElIpVJ2IsjmDwE3mw1KpRLEiISPzy9ks99/SZEhRUS8JRLo9Xou4M0js5oiWcxkMgiHwwgGg3jy+xGPx1EoFDCfzx31xwWyHclkTdNQrVaRz+fxUyyiXq9jNps9DLt6U/b7PS1oXdev3oy7Rz4P8mWxkjEvsIdeGy8w0n4BndeFjVknkq0AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;drawing an arrow from start&quot;
        title=&quot;&quot;
        src=&quot;/static/drawing_an_arrow_from_start-372db0d30371a7c238c10dee28c2e993-ccd31.png&quot;
        srcset=&quot;/static/drawing_an_arrow_from_start-372db0d30371a7c238c10dee28c2e993-e52ca.png 300w,
/static/drawing_an_arrow_from_start-372db0d30371a7c238c10dee28c2e993-ccd31.png 302w&quot;
        sizes=&quot;(max-width: 151px) 100vw, 151px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ate_pizza_arrow_and_new_node-1ae333f397d8023e0de8a66d8a76d848-2fec7.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 700px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAACgElEQVQ4y6WTzW7TQBDHA2/BI/AA8BSxEOLCDYEiOCDqhiROUSrKFYlrOZQrB25w6wEVRypVBVEL+WiT1vlq0sR2Yid2nNixd73D7qYJLW1P/KXRemdnf96Z2Y20isU71Vrhvqr3orqqCfVqXWjWm4LaVbk1G02hptSEdqstaHT9tH0qKEeKoFQUHsv81ePqvd2d3VsRpvrvX1uG2YSOpoHRN2BgDsAaWuB5HniuB5ZlgWmY4IwcmE6nMB6PYTgYcrMtm/vHzhiycvYxB1YURe71B9A6OUGaphGEEMEYk7kAYGFX+EJqmBoUCoWnHNjuqt9gJsSCGCwMwwsgDvtnfs44MJ/Pz4C6psnMQdPBvu/ztJh6vR6sr78H0zT5d6lUgtNOBxzHgYnj8TSpn5TL5dB1XaDjDKjNgf4UB0EADEpPycGKovA5M7Yp8AMWB0f6Hh09Nie01uGFlHVd50DHtTAKEN/MwNcJhQEUOzsQEp7pvI5/U+7rfRmDD6ajY4wwPwGtIUwmE5CzWbBtm4MI4fsgwFPQR60zH9dFYE83ZJeMYOiYtIYIvKnHAnntNjY+QLfb5ZvZT5h85IFqNRbASyd0Bo5sowbY4y7vMoSYYHT1daFegkNEvGCy8F/q8r7SkDdrFdg6PkJfisdkv60S2+2Toatfd02uvDaLpvwoHWa3a234mj8gn/cO4OPPT5Cvf4e+YcDo7HUg2qjNQwXWt3Og0dcRIkRrPev+/JrlcrlnHPj61Ur07drqyzdpaend2qoYX46JqURaTMQTIlMymRSlVEqMPnoi3n3wUHy+HBdX0mkxJUmiJElLKbqWyWRexGKx25FzuvmfdoNB6EEjfwBTLnDbYXwUWAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;ate pizza arrow and new node&quot;
        title=&quot;&quot;
        src=&quot;/static/ate_pizza_arrow_and_new_node-1ae333f397d8023e0de8a66d8a76d848-2fec7.png&quot;
        srcset=&quot;/static/ate_pizza_arrow_and_new_node-1ae333f397d8023e0de8a66d8a76d848-e3f4e.png 300w,
/static/ate_pizza_arrow_and_new_node-1ae333f397d8023e0de8a66d8a76d848-e6afe.png 600w,
/static/ate_pizza_arrow_and_new_node-1ae333f397d8023e0de8a66d8a76d848-2fec7.png 700w&quot;
        sizes=&quot;(max-width: 700px) 100vw, 700px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Add a leaf called &lt;em&gt;Prince&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/prince_leaf-35f57ed3e81e35634da24e27e86c9147-2fec7.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 700px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB9klEQVQ4y6WTy27TQBRAA3/BJ/AB/EUtxIo1UqCr1hVSUlMLkKAsWPY7WPEB1BYPteAi6lTqI3YcO3FqO36mNjjxYy4zE9ymRq0q9UpHlu/MPbp3PG4MDg4eqL3OI8sZLzmWzWiqxuiazlinFkXv60xP6THDwZCx8bo5NBnlRGGUY4XuJXm1qz7c+bZzr0FCk/c/eb4OI9sGz/Ug8AOIwgjSNKVEUQS+50N8FsN0OoUkSSAMQsokmtB8EicgCuITKjzudgUXiwzDyC3LQnmeU6oAgHPq75gSU2Cg0+k8o8LhYLAN8915URRoNptR4aKkLq/lqFCW5bnQcRyBJPA4BZYBAQtJ1U2ourwQ2rZNhVhUZFlGheRZBa2pD3qxdr2QymYZlEU5F91WSDpLp38g+u2eyyoWhQjQ1ULrnzClZ5hDmHhwNNqDZDa5JIWbnqHvjqkQz5mTejvUkRUYaBSptJ+yLNF18d9Xlk5U4avpwJeemX/Yl9BndRsFyRj9MoX6yV3F5Xv44/BIFJU+iIcq+ij/hD1tF86iGOJkAnlWwve+C7uaQSagf0p1tSpIjoQkSctU+HrjxdL7Vy+fb/Lc6tbmO/YN/5ZdW2NZbp1j2+119vHTFcwyu8FxbKvVwrn2Iqskx/P8SrPZvN9YiLu35A6R4EYbfwH5sXrc/KNgrwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;prince leaf&quot;
        title=&quot;&quot;
        src=&quot;/static/prince_leaf-35f57ed3e81e35634da24e27e86c9147-2fec7.png&quot;
        srcset=&quot;/static/prince_leaf-35f57ed3e81e35634da24e27e86c9147-e3f4e.png 300w,
/static/prince_leaf-35f57ed3e81e35634da24e27e86c9147-e6afe.png 600w,
/static/prince_leaf-35f57ed3e81e35634da24e27e86c9147-2fec7.png 700w&quot;
        sizes=&quot;(max-width: 700px) 100vw, 700px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Then, add a leaf called &lt;em&gt;Frog&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/frog_leaf-19a5a72997b81ba7b3cd01821f3b158d-2fec7.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 700px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB+0lEQVQ4y6WSTU7bQBSA096iR+gBegusilXXldKyAktFCT9WhVRYsepFumFbgQ1qS0sWJaZNSOwYxwnYTuzYITbxz2ReZ8Z1CQEqJJ70aTRvxp/fm5mCcXLyQm3J86bdm7NNi9NUjdM1nTMvTIZ+pnMtpcV1jA5nkfVup8spDYVTThW2l+bVpvry8OvhswIN7fjnbt/R4dyywOk7MHAH4Hs+jMdjhu/74DoujC5HEEURBEEA3sBjDP0hywejACRRes2ETUUVXWcAhmGklmXhNE0xQgjnAQD/mJ0TJgREAFmW32bCZmPv6iqEJElTUgEOwxDTcVoyK5/JMWG1Ws2EpDKRVEVbQUQGFNoa3fsA8iqvhbZtizSRJAki0BHoD/Jg38w2er12W0jOjQnjOEYEOjJhtveRQlpdJkT3y1gK3y80/wrHUYSiOIHLcAiKfXyjwkz8wDN0ez0mhAmiB4e9kYV/d49wnGY3PcH/j1u3XGmo4peuDQdqO/1UrePdhoTr1jdseKd3NHsnN9/hUa0uSYoO+zUF78i/YK/2GS7sNrjDHqAUw4+zPnzX2rQD9pzyi8uhORqVSmWBCTfW1ua2N96/2xLWlz5ufeA3hU2+tLzCr68KfLm8wr96s0hYIPNVvlQqkVx5miWaEwRhsVgsPi9MxdNH8oRKSKGFP5OjenZiGrv6AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;frog leaf&quot;
        title=&quot;&quot;
        src=&quot;/static/frog_leaf-19a5a72997b81ba7b3cd01821f3b158d-2fec7.png&quot;
        srcset=&quot;/static/frog_leaf-19a5a72997b81ba7b3cd01821f3b158d-e3f4e.png 300w,
/static/frog_leaf-19a5a72997b81ba7b3cd01821f3b158d-e6afe.png 600w,
/static/frog_leaf-19a5a72997b81ba7b3cd01821f3b158d-2fec7.png 700w&quot;
        sizes=&quot;(max-width: 700px) 100vw, 700px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;To complete the main graph, associate local nodes with the recently added leaves.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/wiring_up_the_prince-ea72200fe85b6fcc12f216c5e92f0e24-2fec7.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 700px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAACj0lEQVQ4y6WSzW4SURTH0bfwEVwbd+7ddGJ004VxYWx0YWSottAKJSa6684H8AVMunZTqVVTLdHykVLmA0rvQAfKDDAMzAzMvfd47wXaYuzKQ/65wzn//ObcMyeCisXbeqVw32ydLbTMplTVq1KtWpPMU1Nq1BtS7bgm6VpFQidIarJ63ahLmqJJWlkTXgMZkqZq9/a+792I8KjmDrbbVg0aTROstgUduwO9bg+CIIDxaAy9Xg9sywbXdUVu4A6ga3eFuM/tuyK3k9l5LICKXslYrIgQCpvNJsUYU0IIDcOQDodDCgBChP14zP5PRZgwExQKhacCqB/XPnshBkJwyCG+7wtzqVSiG6kNats2bbfb9OhQoUpZoaxj2ut2qeM44rlYLGIDIcjlchOgqioZt98Hz/Mw6wi4+NUYXFyTnwQTODrNgjPoAGbP4/FY5NnJG+BdQj6fnwBN08zwBCtibpyZLwehGPL1XcBkPn/p2hdANjcBHI1GmImfAsjHNRkZgOPb0O43pnByXpvO9Gog724GFK+nwgv1jgb+aDDNXbzon0BzCvSDADMBm4kwG4YBiUQCVFWFgAxhEDhzwCs7tM/OMhOnGBBlX4CGbHX41y6Xy9T3AtpyEXW8ztz6zGK2NufArKJnvtVb8LWCwq1Cmf5GpwxK5vbtF/pEQ+L9vYMzze/h/uHRzhf9BLYLJfpx/wByqAEhm2OfrZJl22B1unBoWLCVV+H97k/48OMABp4vtiFgPr5iPLLZ7DMBTK+vLWy+Sb98u74W3Uyn5HeppLyysiIvLy/L0WhUjsVi8vPYa/nuoyfyrQeL8p3Fh/IrVk/E43I8Ho+urq7KyWTyxdLS0s3Ipbj+n7rGIazRyB9pM245VclUPwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;wiring up the prince&quot;
        title=&quot;&quot;
        src=&quot;/static/wiring_up_the_prince-ea72200fe85b6fcc12f216c5e92f0e24-2fec7.png&quot;
        srcset=&quot;/static/wiring_up_the_prince-ea72200fe85b6fcc12f216c5e92f0e24-e3f4e.png 300w,
/static/wiring_up_the_prince-ea72200fe85b6fcc12f216c5e92f0e24-e6afe.png 600w,
/static/wiring_up_the_prince-ea72200fe85b6fcc12f216c5e92f0e24-2fec7.png 700w&quot;
        sizes=&quot;(max-width: 700px) 100vw, 700px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/wiring_up_the_frog_and_generating_the_code-091e59bc22cff06b02e152e037cb3294-2fec7.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 700px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAACpUlEQVQ4y6WTzW7TQBSFA2/BI7BFYscLINVCsIAFEhJSVVbElLZJq7SlUpddsmePEG8ApEChqKkax6FpnLhuaic4P3bt2ImT2ON7mZkk/WGBkLjK0cQzJ9+cmVwn9GLxtnos3zdb7ZmW2RQ0VRNqWk0wf5lCo94Qaic1Qa0eC/qpLjTpet2oC1WlKlTLVe41dEOoVqr3dr/t3kiw0qT8x45Vw0bTRKtj4Zl9hq7j4nA4xHAUouu6aFs2+r7P53p+Dx3b4WI+3/P53HZ2+ykHKupx1qKLuq5HzWYTCCEQxzFEUQT9fh8QkWta0+eJYkAgdERZluc4UD2pfQoignFMIgYZDAbcXCqVYG11DWzbhk6nA8ViEcrlMnRdF1zHgW63C47rQLmkEHoNKEnSGFipKFnf8zAIAkITIRM7GoXzY7KRic1N58MwxDAKMY4A5PpOPCR9PPqpjIGmaWZZZGoizDgF/GPBkblHjx1dAOm9ceBoNCLDEb30wONAdl1/Ew9BhtDy9Jh9lwrSVWAURqQ38LBxpmFMYLI/TAa4iHQJGIQ9MJwKB+alg8mRzxOGxOt3sW6fcLNh6JhOp1FRyvy57dVxFA2ubBCSEXQDe5xQyo+BdrudnWweBYMWaJ0DGgEhCPqgKApvnRgI1KwyDxfDRTEf/R1vm0KhMAbmFDW7U2/hjmZE76QifNfUqfFch82vYPX0P3twqqt9uHd4tP1ZPcUPcgne78soGyZ9Q0bo0VayLIu+KT7uaxq+PSji6y97+OZHnv5xA946Q+pjrcQql8s948D1leWZrY31l5sry8mtV6vi5mpGXFxcFOfn58VkMimKL+hnYUO8+2ROvPXgoXjn0WNxga6nUykxlUoll5aWxEwm83x2dvZm4lJd/09dYxAaNPEbkUVs5yfl/5IAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;wiring up the frog and generating the code&quot;
        title=&quot;&quot;
        src=&quot;/static/wiring_up_the_frog_and_generating_the_code-091e59bc22cff06b02e152e037cb3294-2fec7.png&quot;
        srcset=&quot;/static/wiring_up_the_frog_and_generating_the_code-091e59bc22cff06b02e152e037cb3294-e3f4e.png 300w,
/static/wiring_up_the_frog_and_generating_the_code-091e59bc22cff06b02e152e037cb3294-e6afe.png 600w,
/static/wiring_up_the_frog_and_generating_the_code-091e59bc22cff06b02e152e037cb3294-2fec7.png 700w&quot;
        sizes=&quot;(max-width: 700px) 100vw, 700px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The graph is ready. Click the button called &lt;em&gt;GENERATE CODE&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/generated_graph-6ad80143d1a72234417cdc9ce8233fe7-2fec7.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 700px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAABw0lEQVQ4y6WTXW7aQBSFaXeRJXQB3UWsKkvoA+1TE6mSQSkb6iagfaoiFIiEK6wWY4J/amxjux5iGzzjubkzIVb+Ckg90pHHd8afzp0ZN2ZXV291/fLEdt1jx3IU0zAV69pSwiBU/IWvzK/nsubYjnx3HVcxfhuK8ctQZtOZrE8n03cXPy6OGkLWT61LbjwIowjSvynEUSy9Wq0gu8kgjmNAuJzL8xwIIRAtI+kkTmSdpAR63d57CfTD8BugBoMBRfORNuKapvFut8fnlsWrquJlWUpvNpt6vHWFZuL74XD4QQIXi0VPFIIgoJ7n8SiOeFHknJAVPot/gXi5qcdsG6gGyoTYChPtMCbna3HOd5nj+uoJ0KuBuq4DpoSypDVsj14C3iVcr9fMtm3wfR+yLDsk3W4g7hebTCaQJMmjdu8Gj30QEMVM04TxeAx+EACldG/KnUBGS1rkBZ5oyREmr8vzbM/NtqdYA3HPJDBMUxosl3hdCL+XgO7zPbC+h39c97sofL0ccR9vfIWt4n4ebPH3CPX7/Y8SqKrq8Zfz88/4PG2p6lmr1Tprt9uH+lSs73Q6n5rN5pvGA73+T78SEAzauAUOpXlz6NHTmQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;generated graph&quot;
        title=&quot;&quot;
        src=&quot;/static/generated_graph-6ad80143d1a72234417cdc9ce8233fe7-2fec7.png&quot;
        srcset=&quot;/static/generated_graph-6ad80143d1a72234417cdc9ce8233fe7-e3f4e.png 300w,
/static/generated_graph-6ad80143d1a72234417cdc9ce8233fe7-e6afe.png 600w,
/static/generated_graph-6ad80143d1a72234417cdc9ce8233fe7-2fec7.png 700w&quot;
        sizes=&quot;(max-width: 700px) 100vw, 700px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;It’s time to write some JavaScript. First, you need to get all the dependencies.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;npm i rosmaro rosmaro-in-memory-storage rosmaro-process-wide-lock --save&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, you need to import and call them.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; makeStorage &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rosmaro-in-memory-storage&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; makeLock &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rosmaro-process-wide-lock&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; rosmaro &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rosmaro&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// The model is going to be built here.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; storage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeStorage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; lock &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rosmaro&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;graph&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; handlers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; storage&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lock&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// The model is going to be used here.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The generated graph may be either imported as a JSON file, or pasted directly into the code. To keep this example as simple as possible, I suggest pasting it into the code.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; graph &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;graph&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;nodes&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;Prince&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Prince&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;Frog&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Frog&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;arrows&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;Prince&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;ate pizza&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token string&quot;&gt;&quot;target&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Frog&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token string&quot;&gt;&quot;entryPoint&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;start&quot;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;entryPoints&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;start&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;target&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Prince&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;entryPoint&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;start&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;Prince&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;leaf&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;Frog&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;leaf&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A frog is certainly a simpler creature than a prince. Implementing its behavior is easy. Every time we ask the frog to introduce itself, it says “Ribbit! Ribbit!”.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;const Frog = {
  introduceYourself: () =&amp;gt; &amp;quot;Ribbit! Ribbit!&amp;quot;
};&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The prince not only introduces himself, but also pays attention to the things he eats. He may eat a yakisoba and everything is fine. But as soon as he eats a pizza, he follows the arrow called &lt;em&gt;ate pizza&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;const Prince = {
  introduceYourself: () =&amp;gt; &amp;quot;I am The Prince of Rosmaro!&amp;quot;,
  eat: ({dish}) =&amp;gt; {
    if (dish === &amp;#39;pizza&amp;#39;) return {arrow: &amp;#39;ate pizza&amp;#39;};
  }
};&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It’s time to put the handlers all together.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;const handlers = {Frog, Prince};&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The model is ready. Here’s the complete code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; makeStorage &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rosmaro-in-memory-storage&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; makeLock &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rosmaro-process-wide-lock&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; rosmaro &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rosmaro&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; graph &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;graph&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;nodes&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;Prince&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Prince&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;Frog&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Frog&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;arrows&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;Prince&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;ate pizza&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token string&quot;&gt;&quot;target&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Frog&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token string&quot;&gt;&quot;entryPoint&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;start&quot;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;entryPoints&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;start&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;target&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Prince&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;entryPoint&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;start&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;Prince&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;leaf&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;Frog&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;leaf&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Frog &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  introduceYourself&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Ribbit! Ribbit!&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Prince &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  introduceYourself&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;I am The Prince of Rosmaro!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  eat&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;dish&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dish &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pizza&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ate pizza&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; handlers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;Frog&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Prince&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; storage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeStorage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; lock &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rosmaro&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;graph&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; handlers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; storage&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lock&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Identical calls to the &lt;em&gt;introduceYourself&lt;/em&gt; method return different values. The returned value depends on events which occurred in the past. It proves that the model object is stateful.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;introduceYourself&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// I am The Prince of Rosmaro!&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;dish&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;yakisoba&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// undefined&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;introduceYourself&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// I am The Prince of Rosmaro!&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;eat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;dish&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pizza&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// undefined&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;introduceYourself&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Ribbit! Ribbit!&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/lukaszmakuch/cursed-prince&quot;&gt;code of The Cursed Prince&lt;/a&gt; is on GitHub. It makes use of only basic Rosmaro features. When working on real apps, you’ll want to use more advanced techniques. Some of them include subgraphs, dynamic orthogonal regions, and the context object.&lt;/p&gt;
&lt;p&gt;You can learn more about Rosmaro from its &lt;a href=&quot;https://rosmaro.js.org/doc/&quot;&gt;official documentation&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Programming without boolean values: To-Do App]]></title><link>https://coder.earth/post/programming-without-boolean-values-todo-app</link><guid isPermaLink="false">https://coder.earth/post/programming-without-boolean-values-todo-app</guid><pubDate>Sun, 25 Feb 2018 10:37:20 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;/todo-c127bc411905f4a0855ab2b8978827ea.gif&quot; alt=&quot;An application implemented without booleans&quot;&gt;&lt;/p&gt;
&lt;p&gt;Since I discovered functional programming, I knew I could build a To-Do app without writing my own variables. I did some tutorials and got a working app.&lt;/p&gt;
&lt;p&gt;Since I discovered automata-based programming, I knew I could build a To-Do app without writing my own IFs or booleans. Well, theoretically. I hadn&apos;t done it before. &lt;/p&gt;
&lt;p&gt;I started to wonder if I could actually build a To-Do app not only without variables, but also without writing any code resembling the fragments visible below.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;if (isDone)
isDone ? ... : ...
value || defaultValue
showIf=&amp;quot;model.isDone&amp;quot;
selected === &amp;quot;all&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It turns out that with &lt;a href=&quot;https://rosmaro.js.org&quot;&gt;Rosmaro&lt;/a&gt; it&apos;s possible!&lt;/p&gt;
&lt;p&gt;In this post I&apos;m going to present the solutions to some of the challenges I faced. To keep this post short, I&apos;m not going to cover basics of Rosmaro. If you would like to learn more about it, please take a look at the &lt;a href=&quot;https://rosmaro.js.org/doc&quot;&gt;official documentation&lt;/a&gt; or my other posts, like the one about &lt;a href=&quot;/post/react-and-visual-automata-based-programming&quot;&gt;react and visual automata-based programming&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The whole &lt;a href=&quot;https://github.com/lukaszmakuch/bool-less-todo&quot;&gt;code of the bool-less To-Do app&lt;/a&gt; is on GitHub. You&apos;ll also find there a &lt;a href=&quot;https://lukaszmakuch.github.io/bool-less-todo&quot;&gt;demo&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The main node - graph&lt;/h2&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/main_node-6262560ef5bcd18f357abf225faff774-4e8db.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 70.91584158415841%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsSAAALEgHS3X78AAACYUlEQVQ4y5VSPW/TUBQ1leCfwA9gRaolGMvKAgMSQswwJm6ipgu0ExIDO0MVq0IMDEyphBAoramTkLh2bCdOYjvf3863k3e5z62jkAJVr3R0n6/fO+++cy7DYJgn8duaLjywKpXNRq3B5rQca+QN1jZttmgU2PSvNCueiqyaVdkCfsuS7EFVVDafy2/qqn5fFMQ7jB/y928fSpYEumHMS8USlO0yNBtN6PV60Ol0wDItsC0b+r0+jIYj6LQ7UKvWoFqpQrPZXNCacCIcLAlT6QzfqDdB13RXVVVwBgOYzWbgui4sFgug0e12oVAogGmaXnYcx6vj/znNtm1/XBJmFYVvt1u06OIGMplMyHg8JvP5nOBeD+VymcTjcSKKIhEEgbRaLa+O4V4iTCQSvGVZYBiGS585wA5pB7RDOD8F60FrF7jcYTKZ5Ov1On2W6zgDGA6HHuk6IX3+qgz/JEylUjzVBbNbq9UBn/sHoU9A9xzFjqBarV5NqOs6dcrFtecu7XK9Q3oJauldeCUh6gdJ7NBELfuo31Ua/pcwq2l8D2+fDBzXd5U6PEfHF+ds6PqEyGdnBMeKaJq2nIC/unwqK/znvA1flNzsQMyQaEIio8l0OTIUOJdElmUiSRJBeSiR/88jRClWxiYjHcZLZTjOF+Fn0Ya92A94+/UYDpMyxFSD9gHYkWfOaqaYTqe+YZ98vhvbweDWu73X4f3dSPD9/hvu+ctX3N1HT7h7j59yW89ecLs7O9x2KMSFEOFw2IO/xhyMRCLhQCDwELk2GCWZYLwFw9xE3LrI14F/ZiMajTK/AS8NPzvfH7Y0AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The main node&quot;
        title=&quot;&quot;
        src=&quot;/static/main_node-6262560ef5bcd18f357abf225faff774-86d16.png&quot;
        srcset=&quot;/static/main_node-6262560ef5bcd18f357abf225faff774-bd9cb.png 300w,
/static/main_node-6262560ef5bcd18f357abf225faff774-fe5c6.png 600w,
/static/main_node-6262560ef5bcd18f357abf225faff774-86d16.png 1200w,
/static/main_node-6262560ef5bcd18f357abf225faff774-4e8db.png 1616w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;There are some things that never change. At the top of the screen, there&apos;s always the form. It&apos;s followed by the list of items to do. The navigation comes last. That&apos;s what makes a composite a perfect candidate for the main node. It reflects the intended behavior - few simultaneously working areas which never change from one to another.&lt;/p&gt;
&lt;p&gt;We&apos;ll come back to the code handling the main node at the end, because it&apos;s necessary to know how do &lt;em&gt;Items&lt;/em&gt; and &lt;em&gt;Navigation&lt;/em&gt; render.&lt;/p&gt;
&lt;h2&gt;The form - graph and code&lt;/h2&gt;
&lt;p&gt;
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 70.91584158415841%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsSAAALEgHS3X78AAACw0lEQVQ4y5WSz2sTURDH14L+J/WuV6ErelS89VIFEbwIHvTYbNJYrEiEgvTiuT2ULFLEuwhtESVp0k1226S7zW6Sze7m988mTbK7b5z3mvSHPTkw7Oz78ZnvzDyOQzNjf2a1472HpXJ5rlap8Tktxxu6wVumxReMPC+nZV7aT/F6TudLxRKvqRqfPczyR5kjujZ3rB4/SMaTt7mpZX7tbhTMA9B03SvmC2BZNtRrdeh2utBqtqBklsAsmtBoNKDT6UC1UgXHdqDslOk5f9AfQDwW3zwHppUDsdVsg6Hrbi6Xg97JCYxGI3DHLvi+D0CAGY0Jmfyg0RjXPBpblrV1DlRVVWwjxDBLruU4pN/vE9d1CTm7fcUxEWm1WsTzPHLGJO41YAaBdrsLWdN261im506Uoa2urkIkEmExVV0ul2E4HEKlUoFut0uXrytMp1KigaUeKop7OhgAKoRer8eg2WwWFEVhQMdxwLZtBmo2m2AYBhSLRW+ydwFMSZLYbrcpxKX9O5k4lgX1ep0loEbh2Aq2h5Nme9VqlQFR+QVwP5kU8/k86DiUDmYfoEqqkFo4HIb19XUWm6bJgNSmZeO/R9dQ+aWS5bRoIHAvkXRVTQMKpSqml2u1GhQKBWhgmZeNnqEKaWv+6aEk2giUk0k3r6nEH56ySY/GY+JPJi1JEtne3ibYO4KlEnwZRNM0GrOsVxTGZEUUZRW2EvJ4IyaRzYRMugi88mQ8lziWRfBxs6czpsl8n+5dB6YOM193tDz8kBRIFC349PM3rO3E4Lt8BGu7cYjuH8BGQoZs7axkOixaJv3SXlLDGXyb8m4EA4FHnz+sLK2EhMCXyEfh5Zu3wp35p8L9Zy+E2Sfzwr2F58Ld+QVh4dVr4f27sBAMBoVQKDT1wPLy8tLi4uJjZM1walriWMBxN9FvTb7/49M7M9FolPsLtZ0zSedhEE0AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The form used to add new items&quot;
        title=&quot;&quot;
        src=&quot;/static/NewItemForm-0540ebe50c73daacff35c7902801fee8-86d16.png&quot;
        srcset=&quot;/static/NewItemForm-0540ebe50c73daacff35c7902801fee8-bd9cb.png 300w,
/static/NewItemForm-0540ebe50c73daacff35c7902801fee8-fe5c6.png 600w,
/static/NewItemForm-0540ebe50c73daacff35c7902801fee8-86d16.png 1200w,
/static/NewItemForm-0540ebe50c73daacff35c7902801fee8-4e8db.png 1616w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
The form is simple. It doesn&apos;t differ from the one described in the &lt;a href=&quot;/post/react-and-visual-automata-based-programming&quot;&gt;react and visual automata-based programming post&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;It&apos;s built using two nodes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a graph called NewItemForm&lt;/li&gt;
&lt;li&gt;a leaf called NewItemFormView&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;em&gt;NewItemForm&lt;/em&gt; graph exists only to handle loops from &lt;em&gt;NewItemFormView&lt;/em&gt; back to &lt;em&gt;NewItemFormView&lt;/em&gt;. It makes it possible to update the context when the user types the content of a new item or adds a new item.&lt;/p&gt;
&lt;p&gt;Here&apos;s the code of the view:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; NewItemFormView &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; newItemText&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;typed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ctx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; newItemText&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  addItem&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;item added&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ctx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      newItemText&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      items&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;items&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;newItemText&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  render&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; 
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
        type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;text&quot;&lt;/span&gt;
        className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;item-form-field&quot;&lt;/span&gt;
        value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;newItemText&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        onChange&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;e &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;newItemText&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;target&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
        type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;button&quot;&lt;/span&gt;
        className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;item-form-button&quot;&lt;/span&gt;
        value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Add&quot;&lt;/span&gt;
        onClick&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addItem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;form&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As we can see, this handler works with a context shaped like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  newItemText&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;what is the user typing&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  items&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;the first thing to do&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;the second thing to do&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What&apos;s very important to notice is that &lt;strong&gt;new items are always added at the end of the array&lt;/strong&gt;. That way &lt;strong&gt;the index of an item never changes&lt;/strong&gt;. If it was added at the third position, it stays at the third position. I promise you that soon it will become clear why does it matter.&lt;/p&gt;
&lt;h2&gt;How does the navigation work without booleans?&lt;/h2&gt;
&lt;p&gt;There are no IFs. There are no filters. How does it work then? &lt;/p&gt;
&lt;p&gt;It involves three nodes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Navigation&lt;/li&gt;
&lt;li&gt;Items&lt;/li&gt;
&lt;li&gt;main&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When &lt;em&gt;Items&lt;/em&gt; are rendered, they produce an array like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    all&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; somehowRenderedItem&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    done&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; somehowRenderedItem&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    undone&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; somehowRenderedItem&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    all&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; somehowRenderedItem&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    done&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; somehowRenderedItem&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    undone&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; somehowRenderedItem&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each element of this array corresponds to one item to do. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keys &lt;em&gt;all&lt;/em&gt;, &lt;em&gt;done&lt;/em&gt;, and &lt;em&gt;undone&lt;/em&gt; correspond to filter settings.&lt;/strong&gt; Values are views. When the current navigation settings indicate that the user wants to see just undone items, the proper way to display the list of items is to display the values stored under &lt;em&gt;undone&lt;/em&gt; keys. Some values will be fully rendered views, and some will be nulls (so they simply won&apos;t show).&lt;/p&gt;
&lt;p&gt;But how do we know which key should be displayed?&lt;/p&gt;
&lt;p&gt;When the &lt;em&gt;Navigation&lt;/em&gt; is rendered, it doesn&apos;t return just the view. It returns a structure shaped like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;UI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; show&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Under the &lt;em&gt;UI&lt;/em&gt; key, there&apos;s the view. &lt;strong&gt;The value under the &lt;em&gt;show&lt;/em&gt; key is a map function&lt;/strong&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;show&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    all&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; somehowRenderedItem&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    done&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; somehowRenderedItem&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    undone&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; somehowRenderedItem&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    all&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; somehowRenderedItem&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    done&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; somehowRenderedItem&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    undone&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; somehowRenderedItem&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// =&gt; [somehowRenderedItem, somehowRenderedItem]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The common ancestor of &lt;em&gt;Items&lt;/em&gt; and &lt;em&gt;Navigation&lt;/em&gt;, that is the main node, passes the result of the &lt;em&gt;Items&apos;&lt;/em&gt; render function to the &lt;em&gt;show&lt;/em&gt; function returned by the &lt;em&gt;Navigation&lt;/em&gt; node.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; main &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  initCtx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;newItemText&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; items&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  afterRender&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; 
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;NewItemForm&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ul className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;todos&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Here the *show* function picks proper views.&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Navigation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;show&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Items&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;ul&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Navigation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;UI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;How do navigation buttons change?&lt;/h2&gt;
&lt;p&gt;The navigation may be in one of the following states:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;showing all items&lt;/li&gt;
&lt;li&gt;showing only done items&lt;/li&gt;
&lt;li&gt;showing only undone items&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They all may be the children of one graph. The only problematic thing are the transitions. Each node must be connected with every other node. In order to limit the number of required arrows, I used custom entry points and loops.&lt;/p&gt;
&lt;p&gt;This is what does the &lt;em&gt;Navigation&lt;/em&gt; node look like:

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/Navigation-112f3e25f60fa7e07106602705b0a3a9-82c84.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 58.883720930232556%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAACdElEQVQoz6VSTWsTURQdBUVduZF07x/xT9RVwYWNHQtuRFNqQ3RRLSgiRYoSBFeik0hVpKFpmhARswm1ifmapkmaGZtkpp18JyYzfTPXe4cmFBQ3HjjMx3vv3HPPfZzP/fpMKRmbKlUKs4eqNlMsFPndnV1elmReURReVVSe/uWyOX5/v8Jrhxqv1lR+r7hn7yvkC7xclmcKu4Vb0Uj0Mue5u3BJTCe7yoECeBgMwwB2xOAkTNMEQzfsd8YYdDodGA6GABauMdMmIfYtdoNzue5M7JWlarlcBlmWDV3XmWmZpPgHsRhTD1Q2HA5Zt9tl/X5/tKaTYCqVmuaWHi46EomEsr2dAE2rm71ezxoMBlgbrBHQof1dqVQsTdMs2lOr1Sw0YVWrVavVah2RYDqddnLuhXuOHVFUEYAVSRDQgd0Cao15fACLaoDZQqlUAhQDSZJI2M4IjTm5+TmXI5/Pq7QRxf4qSEAXkM1m7TV6okOKCLB1q9FosLHD+x63AzeoP5JJkGR5LEiDoAGMBJvNJlAXo8HgtKkjGpB1nCWIoujkFh94HJlsTv2OgrIkmZgfEEcYCVIRcnkS9Xqd2qdcbcFMJuPklubnHImdfFWs4rVptowOTo9MrH36yCIbG/Y7CjHMh21tbbF2u80wPxaPxxkKMBSkqevHGU5zH5afTEQyYu/LTwU+58vgzxahgabebIRhNfoVDnV7gPALXdMd/Rcww5vc1cnJiz6/f0UQfO/XAoF31x8vC1OPngrXnr0QZldeCbefvxTCm5tCJBIRwuGwEAwGx1xfXxcCeAb5NhQKrXq93isc4hTyLPIC8vx/8Bzy9G9mzf0R2SDN3AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Navigation&quot;
        title=&quot;&quot;
        src=&quot;/static/Navigation-112f3e25f60fa7e07106602705b0a3a9-86d16.png&quot;
        srcset=&quot;/static/Navigation-112f3e25f60fa7e07106602705b0a3a9-bd9cb.png 300w,
/static/Navigation-112f3e25f60fa7e07106602705b0a3a9-fe5c6.png 600w,
/static/Navigation-112f3e25f60fa7e07106602705b0a3a9-86d16.png 1200w,
/static/Navigation-112f3e25f60fa7e07106602705b0a3a9-92b91.png 1800w,
/static/Navigation-112f3e25f60fa7e07106602705b0a3a9-82c84.png 2150w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    
And here&apos;s the view:

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/NavigationView-af385f3ec93febc85736c790391c0cf8-82c84.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 58.883720930232556%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAACcklEQVQoz6VSS2sTURQeBUVduZF07x9x4bb/wGXHjoI7baiNrYKSIG6EtkgpCDHQTBtLLCQlBEJtSVd5TZo2bTJJk+kjM0lIYpvXPHJPz720kYIuxA8+7jn3nvvNOd8dbtnx9VZR2n5SPJGf17T6eEEuCPmDvKCUFEGtqIKmagLdy+5lhZPjE5YfKUeCnJOHxNpxOS+/2IhsPOSmX0092M9I52pVBSwGwzDAMi0ghMAVLNMEQzeGOT0jA8Lq6D5dKbaj20+5iYmXI4el8mmpVAJFOTL6um7hBVrxL9SpYCaTGeOcH97bUqmUmkymoF6vD9rtNtF1nbhcLuLxeEiv12NxtVqlLZPFxUWW0zgWixG73U42NzdNKhiPx3nOMfXadrC/ryGg0+lQQTBxRLfbDWtra4CCMDc7C81mk43l9Xphfn6exVtbW8DzPAmFQmzmRCLBc5P2CVsul9OwO0AxJtjv99mFRqMBlUoFzs7Ohv7RM1pzhVarRS7HBkmSeG5m2mHL7u1paUlCD5UBdnlNMBwOQ61WGwqk02lGCjoJdkW63e5vQdfbadtB8VDbkYtwrGkDMhiAhaRALyEajVJvWd7pdiGeSFDzWV4ulyESiZDd3V0miG/Bc86ZN7bkTuY0V1ZAbf0yqo2mhR0OXxA7xr/GvPaqFHRFKyz8mIWT6JeCY5zvk3NkI5tv/zyugj9bgKTWgD+hgyyc96BmEvgbsPNn3Ojo6H2/3z+3vLLi+7666g0EAmIwGBR9Pp+Ie6LXuyT6fwREx5dv4uPJd+LYx89iOBQSg+vrrA5J7yyh16sLCwuPOMQN5G3kPeTd/+Ad5M0LoTbyEY0je6AAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;NavigationView&quot;
        title=&quot;&quot;
        src=&quot;/static/NavigationView-af385f3ec93febc85736c790391c0cf8-86d16.png&quot;
        srcset=&quot;/static/NavigationView-af385f3ec93febc85736c790391c0cf8-bd9cb.png 300w,
/static/NavigationView-af385f3ec93febc85736c790391c0cf8-fe5c6.png 600w,
/static/NavigationView-af385f3ec93febc85736c790391c0cf8-86d16.png 1200w,
/static/NavigationView-af385f3ec93febc85736c790391c0cf8-92b91.png 1800w,
/static/NavigationView-af385f3ec93febc85736c790391c0cf8-82c84.png 2150w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Every time the user clicks the &lt;em&gt;Undone&lt;/em&gt; button, it makes the current node of the view (either &lt;em&gt;All&lt;/em&gt;, &lt;em&gt;Done&lt;/em&gt; or &lt;em&gt;Undone&lt;/em&gt;) follow the &lt;em&gt;navigating to undone&lt;/em&gt; arrow. &lt;/p&gt;
&lt;p&gt;Because there&apos;s no such arrow within the &lt;em&gt;NavigationView&lt;/em&gt; graph, it makes the &lt;em&gt;Navigation&apos;s&lt;/em&gt; &lt;em&gt;View&lt;/em&gt; local node follow this arrow. It&apos;s similar to event bubbling. &lt;/p&gt;
&lt;p&gt;When the &lt;em&gt;View&lt;/em&gt; node follows the arrow called &lt;em&gt;navigating to undone&lt;/em&gt;, it makes a loop entering through the &lt;em&gt;undone&lt;/em&gt; entry point.&lt;/p&gt;
&lt;p&gt;When the &lt;em&gt;View&lt;/em&gt; graph is entered through the &lt;em&gt;undone&lt;/em&gt; entry point, the &lt;em&gt;Undone&lt;/em&gt; child becomes the active node. &lt;/p&gt;
&lt;p&gt;That way we can &lt;strong&gt;avoid transition explosion&lt;/strong&gt; when we&apos;re adding another navigation state. It will always require no more than 2 arrows.&lt;/p&gt;
&lt;p&gt;Each handler is coded like that:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; NavigationUndone &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;navigationHandlers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  render&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;thisModel&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// How does it *look*.&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;UI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;inactiveButton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;thisModel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;All&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; method&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;navigateToAll&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;inactiveButton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;thisModel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Done&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; method&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;navigateToDone&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;activeButton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Undone&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// This is the map function described above. It&apos;s built using Ramda.&lt;/span&gt;
    show&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;undone&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Is this done? The graph will tell!&lt;/h2&gt;
&lt;p&gt;There&apos;s no boolean value indicating whether an item is done. Instead, it&apos;s expressed by a drawn graph.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/Item-b08704906301d892e4b763c9af5a1465-5aafd.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.12529002320186%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsSAAALEgHS3X78AAACgUlEQVQ4y5WRW2sTURDHW6igX0ff9b0L9sE3v0BRhIYqiBTBb+BbF4ySamuLUBR8EHRNWxJqlMZskqa7SXPP7tnNbi5N0ua6p2ecPWa3gkVw4M/Mnp35nZkzMzNoFVm+fpyXF4hpzpvEEPK5vFAulgUD41KxJCQTspA5zAi1ak0gGhEK+YKQVbJCTs25efOlQmkhcZC4MeNZPn7w2bKLUCMEbMuGZqMJnZMODAYDoA6F4WAIzWYTTnun/Mz912q2oN1qw0n7hOekU2nJ4105PDqSNI2AqqpOsVhkk8mEjcdjBgBsZ2eHBQIBZhgG/z4/P+feE5qDHhqNRhhZcy5wLquqkm3bgDDHNE2GXXC5BZIkscXFRabrugfw/dQ4EOsvgOlUSlIVBQqFAnVHOjs746PB70rodDp+TCkF7BI8w5j+DVQUSa9bUDdNDnQ1HA55geuPczkeVyoV0DTdzQPs2GNeAsQ3bHW6MOj3feBoNOId9Xo9SCaTXG7sdVev10HBqWo1jfb7fbAs6wIoywlJVbNYlKKtdhtOcWRcDHajwbf9fdjd3YNIJALdbtcf1Y3D4TBEo1FaLlfcC/5YinIkGdUq5DIZahOdTUZD1selIBiXQRjBDafTaYZFzHEcLkIIww7ZpSNH4okv299/wnY0Nt6KxalC6vjylE6TfRmGSTVdR29wuWf4LJMp8KsP/KFko/FWD2SrDZ8KNXgeS8KB2YC9qskVIzZkmh34lyFw3weGgi/ufdjcePV+8+3qx3db4p3HT8Xbj1bEmw8eirdQ88tPxLsrz8SNN6/FUCgkrq2t+R61ur6+/jIYDN7nwGfLgdkp+Srq2tT/j7yauaWlpdlfPn764eyXya0AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Item&quot;
        title=&quot;&quot;
        src=&quot;/static/Item-b08704906301d892e4b763c9af5a1465-86d16.png&quot;
        srcset=&quot;/static/Item-b08704906301d892e4b763c9af5a1465-bd9cb.png 300w,
/static/Item-b08704906301d892e4b763c9af5a1465-fe5c6.png 600w,
/static/Item-b08704906301d892e4b763c9af5a1465-86d16.png 1200w,
/static/Item-b08704906301d892e4b763c9af5a1465-5aafd.png 1724w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    
We can clearly see that a new item is not done. Clicking it marks it as done. Clicking it again marks it as undone.&lt;/p&gt;
&lt;p&gt;Handlers of the leaves make use of a feature which hasn&apos;t been mentioned yet - &lt;strong&gt;calling methods of a single node instead of the whole model&lt;/strong&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; UndoneItem &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  render&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; thisModelNode&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; view &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;li className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;undone&quot;&lt;/span&gt; onClick&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; thisModelNode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clickItem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; key&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;li&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      all&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; view&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      done&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      undone&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; view&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  clickItem&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;arrow&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;clicked&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By using &lt;em&gt;thisModelNode&lt;/em&gt; instead of &lt;em&gt;thisModel&lt;/em&gt; we make sure that clicking an item calls the &lt;em&gt;clickItem&lt;/em&gt; method of this very item and not its siblings. &lt;/p&gt;
&lt;p&gt;Here we can also see that when the navigation asks for done items, an undone item doesn&apos;t render (it returns &lt;em&gt;null&lt;/em&gt; instead of its view).&lt;/p&gt;
&lt;h2&gt;How is the list of items created?&lt;/h2&gt;
&lt;p&gt;We saw above that a single item is a graph. It also expects a context like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But there may be many items to do, not just one. And the context of the whole model doesn&apos;t look like this. &lt;/p&gt;
&lt;p&gt;How does it work? It makes use of &lt;strong&gt;dynamic composites&lt;/strong&gt; and &lt;strong&gt;context lenses&lt;/strong&gt;. You can find &lt;a href=&quot;https://rosmaro.js.org/doc/#graphs-dynamic-composites&quot;&gt;more information about dynamic composites in the documentation of Rosmaro&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;Items&lt;/em&gt; node is a dynamic composite which uses the &lt;em&gt;Item&lt;/em&gt; graph as a template.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/Items-9feb11777e45f44beb84ea2bd216dc68-d9a2d.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 450px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 49.111111111111114%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABpElEQVQoz42Sy27TUBRF84FMKyEk/oNPYNYvYIAoA1QJKBLMqlIeapzYQUrSuMGOWze2Q2KFxI8EvxfHFq1QeShX2vaxfb28t89phUlKz50zizbcrKqq/qrfn/1rtdZhiG5dMrGv8TwP1/Uoy7JRURS3qq93Avr+Aq3bpX12hqZp9HpfWCwWbLdbNpvNrZIk2Q3oTKeoqoqidNBUja7Aa+h6vSYIguZcq4buBFytVgyHQzSB6LqOYZgM+gMMc0KSpqS/lOf5bsCZ56IpCqqoV7sT6fKBOAxItxI3jhqn9S/4X8Nu1FpKnPZozMf+OSPrir5poRoWxtxn5H3DF1iS/Ghc3nVXl6UcCmlYXjeyBmpTj4cv3rJ3cMT+hw6P3r3nwfM33H/2intPDnk9GDcvZ9Lpu2Ml1Z+Rv0cxJ8MLTscTJv6Sc29O+3JKx3Y40Q1Md0Yk8QMZrziOxWnWjFFVFsRJgeFnHA0u2D9V+Gxd08okim2aBMslZS6b04QqS6HICeWe5zjY9lUzo47UURSRZbIvT1kEGcdfEx4ff2Lv6UsO1D4/AYdW8YjPnvs5AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Items&quot;
        title=&quot;&quot;
        src=&quot;/static/Items-9feb11777e45f44beb84ea2bd216dc68-d9a2d.png&quot;
        srcset=&quot;/static/Items-9feb11777e45f44beb84ea2bd216dc68-5d6b3.png 300w,
/static/Items-9feb11777e45f44beb84ea2bd216dc68-891d4.png 600w,
/static/Items-9feb11777e45f44beb84ea2bd216dc68-d9a2d.png 900w&quot;
        sizes=&quot;(max-width: 450px) 100vw, 450px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The handler of &lt;em&gt;Items&lt;/em&gt; provides a function of the context which returns the list of its children&lt;/strong&gt;. In this case, they are named after indexes of the array which stores all the items to do. For the purposes of this simple To-Do app, those indexes serve as unique identifiers of the items. That&apos;s why it&apos;s so important to always add new items at the end of the array - otherwise their identifiers would change. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Items &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  nodes&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;items&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  afterRender&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;reverse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Because we want see the recent items at the top of the list, we reverse the result of rendering all the items.&lt;/p&gt;
&lt;p&gt;OK, so that&apos;s how the list is created. But what about the context? It&apos;s shaped by a lens attached to the handler of the &lt;em&gt;Item&lt;/em&gt; graph.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Item &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  ctxLens&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;localNodeName&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; localNodeName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      title&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;items&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;localNodeName&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
      items&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;localNodeName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; title&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;items&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Under the &lt;em&gt;ctxLens&lt;/em&gt; key there&apos;s a factory function of a &lt;a href=&quot;http://ramdajs.com/docs/#lens&quot;&gt;Ramda lens&lt;/a&gt;. The factory takes the local name of the node. In this case is an index of an item. We know this, because that&apos;s what does the &lt;em&gt;nodes&lt;/em&gt; function of the &lt;em&gt;Items&lt;/em&gt; node handler do.&lt;/p&gt;
&lt;p&gt;Because &lt;em&gt;Item&lt;/em&gt; nodes only read the context and never cause transitions which could update it, the only part of the lens which really matters is the one which zooms the context in. It&apos;s this one:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; localNodeName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  title&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;items&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;localNodeName&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So when the localNodeName equals &quot;1&quot; and the context looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  items&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;first&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;second&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;third&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;em&gt;Item&lt;/em&gt; node is going to see context like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// because node names are always strings based on array indexes starting at 0&lt;/span&gt;
  title&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;second&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In many situations boolean values are not the only way to program conditional logic. With &lt;a href=&quot;https://rosmaro.js.org&quot;&gt;visual automata-based programming&lt;/a&gt; it&apos;s possible to replace them with drawings of boxes connected with arrows and boolean-free code.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Thank you for reading this!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[React and visual automata-based programming]]></title><link>https://coder.earth/post/react-and-visual-automata-based-programming</link><guid isPermaLink="false">https://coder.earth/post/react-and-visual-automata-based-programming</guid><pubDate>Tue, 16 Jan 2018 15:37:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/visual_automata-based_programming-50ecdda147d605fda665a7e40dc24662-b3be4.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1000px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 62.1%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAIBBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe2oUwf/xAAZEAEBAAMBAAAAAAAAAAAAAAABABAREjH/2gAIAQEAAQUCbzHJJuL/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAWEAADAAAAAAAAAAAAAAAAAAAAIDH/2gAIAQEABj8CKv8A/8QAGRAAAwEBAQAAAAAAAAAAAAAAAAERITFx/9oACAEBAAE/IbaexeiqXXouaaUT0JEf/9oADAMBAAIAAwAAABDQz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABoQAQEBAQEBAQAAAAAAAAAAAAERADEhYYH/2gAIAQEAAT8QbFFxOnFrUCwTUiAfjvZ6Fb3PjQnIzBAv7v/Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Visual automata-based programming&quot;
        title=&quot;&quot;
        src=&quot;/static/visual_automata-based_programming-50ecdda147d605fda665a7e40dc24662-b3be4.jpg&quot;
        srcset=&quot;/static/visual_automata-based_programming-50ecdda147d605fda665a7e40dc24662-27d6e.jpg 300w,
/static/visual_automata-based_programming-50ecdda147d605fda665a7e40dc24662-5d038.jpg 600w,
/static/visual_automata-based_programming-50ecdda147d605fda665a7e40dc24662-b3be4.jpg 1000w&quot;
        sizes=&quot;(max-width: 1000px) 100vw, 1000px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p&gt;This post consists of three parts. In the first one I&apos;m telling about my journey to visual automata-based programming. The second one shows the process of building a GUI using visual automata-based programming. The code is written in JavaScript and React is used to render the view. The last part is a summary of my experience with state machines where I explain how did they change the way I think about state management.&lt;/p&gt;
&lt;h1&gt;The problem I had&lt;/h1&gt;
&lt;p&gt;There&apos;s something that used to make me struggle a lot every time I was working on a GUI. It&apos;s the fact that views change. The user clicks a button and BAM! Sometimes just a small part of the view changes, sometimes the whole view is replaced with a new one. Moreover, they not only change, but also depend on each other! It&apos;s not anymore like in the good old days, when we had few static HTML files linking to each other. Every time we visited a particular document, it looked the same (I know, I know, maybe some links were purple and not blue, that&apos;s it). Nowadays in web-applications views often depend on events which occurred in the past. Sometimes they display data entered few steps before. Sometimes clicking the same button causes totally different actions depending on what happened earlier.&lt;/p&gt;
&lt;h1&gt;How was I dealing with it?&lt;/h1&gt;
&lt;p&gt;There was always some map structure, like a database record, a session object or a plain old JavaScript object that was representing the state of the application. I was then putting conditional statements here and there to compute boolean values based on the state and decide which tiny part of the whole code should actually run.&lt;/p&gt;
&lt;p&gt;This approach was good enough, when there were just few screens and they were always changing in the same order, like from &lt;em&gt;A&lt;/em&gt; to &lt;em&gt;B&lt;/em&gt; and then to &lt;em&gt;C&lt;/em&gt;. &lt;/p&gt;
&lt;h1&gt;When things were getting out of control&lt;/h1&gt;
&lt;p&gt;Sadly, every time when the number of views was increasing or there was more than just one path the user could take, I was loosing control of all the IFs. When implementing a new feature, I was constantly asking myself:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Is there any other &lt;em&gt;IF&lt;/em&gt; I need to update after this change?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Answering this question wasn&apos;t so easy, especially when I was working on server-side applications, where forgetting to limit access to some view can potentially lead to &lt;a href=&quot;https://www.owasp.org/index.php/Top_10_2013-A4-Insecure_Direct_Object_References&quot;&gt;insecure direct object references&lt;/a&gt;. My development process felt like a dirty hack. In the end what I was doing was using IFs to tell which part of the code should run and which shouldn&apos;t.&lt;/p&gt;
&lt;p&gt;Moreover, it wasn&apos;t just me who was asking questions about the system. Except the case when I was working on my personal projects, there were always some people I was working for. They were also asking questions like the following two.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What are all the ways a user can go from the screen A to the screen B?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Can we add an intermediate step between &lt;em&gt;A&lt;/em&gt; and &lt;em&gt;B&lt;/em&gt;?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Very often, even though I had the project opened in the editor, I couldn&apos;t quickly answer those questions. In order to reach the IFs responsible for the behavior, I needed to dig deep into the code. It was giving me a headache.&lt;/p&gt;
&lt;h1&gt;From sketching to the discovery of automata-based programming&lt;/h1&gt;
&lt;p&gt;I became a big fan of sketching. Nothing fancy, just some pictures representing the overall behavior of the code I was working on. Like here&apos;s a screen like this, something happens and we get that different screen. Very much like user flows we get from UX experts or... one of the fundamental concepts in computer science - state machines. This is the time when I started wondering if I could make use of state machines in my day to day job. I knew that they could be useful if I were about to do things like parsing a language or drawing a representation of a turnstile. But could they help me to program web applications?&lt;/p&gt;
&lt;p&gt;There&apos;s a wide term called &lt;em&gt;automata-based programming&lt;/em&gt;. The &lt;a href=&quot;https://en.wikipedia.org/wiki/Automata-based_programming&quot;&gt;Wikipedia definition of automata-based programming&lt;/a&gt; goes like this.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Automata-based programming is a programming paradigm in which the program or part of it is thought of as a model of a finite state machine (FSM) or any other (often more complicated) formal automaton (see automata theory).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The idea of making a set of boxes connected with arrows the skeleton of an application always sounds great to me! It&apos;s like bringing my sketches to life, or at least making the gap between the language used to program and the language used to design a lot smaller. So I started with a data structure representing the graph and possible transitions. It was very much like &lt;a href=&quot;https://en.wikipedia.org/wiki/State_transition_table&quot;&gt;transition tables&lt;/a&gt;. Soon it turned out that a simple state machine function, which takes the current state and an event and returns a new state, wasn&apos;t sufficient, because I still needed to use some conditional statements to determine what to do based on its result. So the very next thing I did was using this graph description as a recipe for a stateful object, which responsibility was to call functions based on the current node of the graph. Since then I experimented a lot and changed many details, but this is one of the things I haven&apos;t changed. I really wanted to run away from IFs and method dispatch based on the state of a state machine finally allowed me to do it. It felt like a relief! I got hooked on &lt;em&gt;automata-based programming&lt;/em&gt;.&lt;/p&gt;
&lt;h1&gt;I missed drawing&lt;/h1&gt;
&lt;p&gt;It became clear to me that many of the problems I used to consider hard to code can be easily solved using elegant graphs. I do really enjoy expressing logic as graphs! But I must say that when it comes to transition tables, I like them a lot less. To me, it&apos;s harder to wrap my head around a transition table. When I take a look at simple graph, I can immediately get basic understanding of what&apos;s going on. But when I look at a transition table, it takes me a while. Most of the time I try to imagine a graph in my head. When it&apos;s too complicated, I grab a pen and draw the graph, so I can look at it. I think you already know what I am going to say. Programming by coding graphs is fun, but not that much fun as programming by drawing graphs! That&apos;s why I decided to build a graphical editor that would generate the graph code based on a drawing. This way I could code just what I find handy to code and draw the rest. And that&apos;s how I got into &lt;em&gt;visual automata-based programming&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This is how I was programming a simple graph, when I started playing with the idea of automata-based programming in 2016.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;#39;locked&amp;#39;,
[
    &amp;#39;locked&amp;#39; =&amp;gt; [
        &amp;#39;still_fine&amp;#39; =&amp;gt; &amp;#39;locked&amp;#39;,
        &amp;#39;hit_too_many_times&amp;#39; =&amp;gt; &amp;#39;broken&amp;#39;
    ],
    &amp;#39;broken&amp;#39; =&amp;gt; []
]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And this is how I prefer to program it nowadays.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/box_graph-a4c9e50e71401f76359cc11b13ae037b-1bf36.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 552px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 95.28985507246375%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAABYlAAAWJQFJUiTwAAABoklEQVQ4y6VUSW7CQBD0T3gQz+TMgQdwIEICATmwhWCbzQaB2HfMWnG1MgaME0zS0jBWM1NTXdUzGp7E5XLx5p++b0NDiLjddDqd7vJ+cO0ZkFp8Pp/RbrdlWJaF4/H4UEEohmqhbduYTCbyvVwuUavVsNls7liHYqjmZrPp5dfrNSqVCj6qVRiGjq7dfQ1wPp9jMBh4OZav5nq9ju12+xrgeDzGcDgM1IxgrVbrCsgfasDhbwsyYMxmMwFV5vj/7/V6WK1Wwab4+4phmiZ0XQ+sgkSor+M4V8BkMolYLIbFYiHJ3W4nDpIVgdLpNFKpNxe4IU4zP51O0e/3XVMMb5+UTKrRaBSRSATxeFw2NBoN0aVYLMph5XIZ+XwehcK7aMlBk2iWvzJhSKey2Sz2+/1DSYfDQTYSlKx+a37PlKAFalAbik8ZWB4PZY7uOt8EbkE15VyQywzqxPKtTsdt5ipKpZLkTBd8NBo9GKmFfRRU8C4rR0O/NkFPleo5up5IJERP3umXGAYdwDucyWSQy+Xw6Zr5b0C2C80x/qJhGE39uS9vWMOwduUKQAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The same graph as above, just drawn.&quot;
        title=&quot;&quot;
        src=&quot;/static/box_graph-a4c9e50e71401f76359cc11b13ae037b-1bf36.png&quot;
        srcset=&quot;/static/box_graph-a4c9e50e71401f76359cc11b13ae037b-0f9af.png 300w,
/static/box_graph-a4c9e50e71401f76359cc11b13ae037b-bc72c.png 600w,
/static/box_graph-a4c9e50e71401f76359cc11b13ae037b-1bf36.png 1104w&quot;
        sizes=&quot;(max-width: 552px) 100vw, 552px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;In this post I&apos;d like to show you the whole process of building a GUI, which illustrates all the things I like about state machines applied to web applications.&lt;/p&gt;
&lt;h1&gt;What we&apos;re going to build&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;/bunny_app-ef71f5ae611c7b18df837a3e041d9244.gif&quot; alt=&quot;The example application&quot;&gt;&lt;/p&gt;
&lt;p&gt;We&apos;re going to build a client-side application with few screens. At the home screen the user is asked whether she is a bunny owner. The next step is always about entering the user name. Then, bunny owners need to feed their bunnies before they can see the &quot;thank you&quot; message. Those who have no bunnies see &quot;thank you&quot; right after entering their names. It&apos;s important to note that the bunny is hungry every time we see it and that we need to first find a carrot before we can give it to the bunny.&lt;/p&gt;
&lt;p&gt;Here are few whiteboard drawings showing how screens change.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/bunny_app-9dacc6411fa1e148984dbc2677fffb7b-b3be4.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1000px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 64.3%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAEDBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAey0FUf/xAAYEAEAAwEAAAAAAAAAAAAAAAABABARMf/aAAgBAQABBQJnAdE2ZX//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAYEAACAwAAAAAAAAAAAAAAAAAAIQERIP/aAAgBAQAGPwJlws//xAAcEAEAAgMAAwAAAAAAAAAAAAABACExQVERcYH/2gAIAQEAAT8hflSn2OxZplxOpPUytU5KME//2gAMAwEAAgADAAAAELAP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGxABAAMBAQEBAAAAAAAAAAAAAQARITFRQWH/2gAIAQEAAT8Q1iDABv7DeILY2J32UCEfsJCN9XZtKgq3IGIB3Cf/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A whiteboard drawing of the most important screens&quot;
        title=&quot;&quot;
        src=&quot;/static/bunny_app-9dacc6411fa1e148984dbc2677fffb7b-b3be4.jpg&quot;
        srcset=&quot;/static/bunny_app-9dacc6411fa1e148984dbc2677fffb7b-27d6e.jpg 300w,
/static/bunny_app-9dacc6411fa1e148984dbc2677fffb7b-5d038.jpg 600w,
/static/bunny_app-9dacc6411fa1e148984dbc2677fffb7b-b3be4.jpg 1000w&quot;
        sizes=&quot;(max-width: 1000px) 100vw, 1000px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/the_bunny-bb8bd968c185e1174de22043ac72debb-b3be4.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1000px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 61.9%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAIBBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe3tggf/xAAYEAACAwAAAAAAAAAAAAAAAAAAEgERIP/aAAgBAQABBQJaGxB//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFxAAAwEAAAAAAAAAAAAAAAAAACAhMf/aAAgBAQAGPwKFiaf/xAAbEAACAgMBAAAAAAAAAAAAAAABEQBBECFxUf/aAAgBAQABPyHYzXsWh6yQ4Csez//aAAwDAQACAAMAAAAQo8//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAcEAEBAAICAwAAAAAAAAAAAAABEQAhEDFBUWH/2gAIAQEAAT8QtLi0O78vjCk2sPbBEEaPACJiFO12rn//2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A whiteboard drawing of the bunny itself&quot;
        title=&quot;&quot;
        src=&quot;/static/the_bunny-bb8bd968c185e1174de22043ac72debb-b3be4.jpg&quot;
        srcset=&quot;/static/the_bunny-bb8bd968c185e1174de22043ac72debb-27d6e.jpg 300w,
/static/the_bunny-bb8bd968c185e1174de22043ac72debb-5d038.jpg 600w,
/static/the_bunny-bb8bd968c185e1174de22043ac72debb-b3be4.jpg 1000w&quot;
        sizes=&quot;(max-width: 1000px) 100vw, 1000px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h1&gt;The toolbox&lt;/h1&gt;
&lt;p&gt;The two most important libraries used to implement the application are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://reactjs.org&quot;&gt;React&lt;/a&gt; to render the UI&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rosmaro.js.org&quot;&gt;Rosmaro&lt;/a&gt; to model changes of the UI&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For testing purposes we&apos;re going to use the following tools:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://airbnb.io/enzyme/&quot;&gt;Enzyme&lt;/a&gt; (to make assertions easier)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://facebook.github.io/jest/&quot;&gt;Jest&lt;/a&gt; (it allows to run our tests and ships with useful matchers)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://sinonjs.org&quot;&gt;Sinon&lt;/a&gt; (to make sure the UI makes proper function calls)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All the packages are going to be installed using &lt;a href=&quot;https://www.npmjs.com&quot;&gt;npm&lt;/a&gt; and the project is going to be bootstrapped with &lt;a href=&quot;https://github.com/facebookincubator/create-react-app&quot;&gt;Create React App&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;React&lt;/em&gt; is going to be used mostly as a &lt;em&gt;Virtual DOM&lt;/em&gt; library and a convenient starter kit thanks to &lt;em&gt;Create React App&lt;/em&gt;, while both the data-related state and behavior-related state are going to be managed using &lt;em&gt;Rosmaro&lt;/em&gt;.&lt;/p&gt;
&lt;h1&gt;Setting up the environment&lt;/h1&gt;
&lt;p&gt;Let&apos;s fire up the terminal and use &lt;em&gt;Create React App&lt;/em&gt; to bootstrap our project. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;create-react-app bunny-app
cd bunny-app&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Please bear in mind that in order for this command to work, you&apos;ll need to have &lt;em&gt;node, npm and create-react-app&lt;/em&gt; installed. &lt;/p&gt;
&lt;p&gt;The generated index.js file looks like this.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; ReactDOM &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react-dom&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./index.css&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; App &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./App&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; registerServiceWorker &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./registerServiceWorker&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

ReactDOM&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;App &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;registerServiceWorker&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we&apos;re going to install packages related to Rosmaro.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;npm install --save rosmaro rosmaro-in-memory-storage rosmaro-process-wide-lock rosmaro-react&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, the &lt;em&gt;App&lt;/em&gt; element is going to be replaced with the &lt;em&gt;RosmaroReact&lt;/em&gt; element. Because we won&apos;t need &lt;em&gt;App.css, App.js, App.test.js&lt;/em&gt;, we can safely remove those files together with their imports.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;index.js&lt;/em&gt; file should now look like this.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; ReactDOM &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react-dom&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./index.css&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; makeStorage &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rosmaro-in-memory-storage&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; makeLock &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rosmaro-process-wide-lock&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; RosmaroReact &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rosmaro-react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; graph &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./graph.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// The generated graph&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; handlers &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./handlers/all&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; registerServiceWorker &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./registerServiceWorker&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; rosmaroOpts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  graph&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  handlers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  storage&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeStorage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  lock&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

ReactDOM&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;RosmaroReact &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;rosmaroOpts&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;registerServiceWorker&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let&apos;s go step by step through the modified file.&lt;/p&gt;
&lt;p&gt;Rosmaro-related packages are imported.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; makeStorage &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rosmaro-in-memory-storage&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; makeLock &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rosmaro-process-wide-lock&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; RosmaroReact &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rosmaro-react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The rosmaro package itself is not being imported, because it&apos;s already a peer dependency of rosmaro-react&lt;/p&gt;
&lt;p&gt;We&apos;ve replaced the &lt;em&gt;App&lt;/em&gt; element with the &lt;em&gt;RosmaroReact&lt;/em&gt; element.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; rosmaroOpts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  graph&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  handlers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  storage&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeStorage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  lock&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeLock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

ReactDOM&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;RosmaroReact &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;rosmaroOpts&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For better understanding of &lt;em&gt;rosmaroOpts&lt;/em&gt; please take a look at the &lt;a href=&quot;https://rosmaro.js.org/doc/#building-a-model-introduction&quot;&gt;Building a model&lt;/a&gt; chapter of the Rosmaro documentation.&lt;/p&gt;
&lt;p&gt;As you may have noticed, there are two extra imports.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; graph &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./graph.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// The generated graph&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; handlers &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./handlers/all&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;They are the two main ingredients of a &lt;em&gt;Rosmaro model&lt;/em&gt; we haven&apos;t created yet: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a graph describing changes of behavior&lt;/li&gt;
&lt;li&gt;pieces of code handling different behaviors &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&apos;s start by creating empty files:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;mkdir src/handlers &amp;amp;&amp;amp; touch src/handlers/all.js &amp;amp;&amp;amp; touch src/graph.json&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At this point only test libraries are missing.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;npm install --save sinon enzyme enzyme-adapter-react-16 react-test-renderer&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;According to &lt;a href=&quot;http://airbnb.io/enzyme/docs/installation/react-16.html&quot;&gt;the documentation of Enzyme&lt;/a&gt; this is how we setup the tests.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/setupTests.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; configure &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;enzyme&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Adapter &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;enzyme-adapter-react-16&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; adapter&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Adapter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&apos;s pretty much it! The environment is ready.&lt;/p&gt;
&lt;p&gt;This command, provided by &lt;em&gt;Create React App&lt;/em&gt;, starts a dev server.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;npm run start&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And this is how we run the tests&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;npm run test&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;Modeling changes of behavior using the Rosmaro Editor&lt;/h1&gt;
&lt;p&gt;It&apos;s time to fire up the &lt;a href=&quot;https://rosmaro.js.org/editor/&quot;&gt;Rosmaro editor&lt;/a&gt;. Because our &lt;em&gt;graph.json&lt;/em&gt; file is empty, there&apos;s nothing to import. We can simply click &lt;em&gt;LOAD&lt;/em&gt; to start drawing a new graph.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_new_project-0c5d5f8515e233865bdeb94680f11dfc-57f14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.560344827586206%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAABW0lEQVQoz6WT3UrDQBCF8wL6EOIDtNAgtW2wohZb8MG6vo69q8UL26QU9bIgxNj8mP9STU12k806aZMrEdI6cDjD7PLtHEi4l4fR0ev8GekfJnJtp29oBtJVHVmmhWzbRo7toHdFQbIsb/pMhm4gRVaQ8qZk3tcWWh/628Hd4JiTJpMug8KEMFVVmWlaIJPtU+PH8Q0nSdIlxpiug4AYhkF83yer1YrEcUwopSRJko0XfaFils9xFEWpKIrX3HQ6vcI4YnCQwiPpHoulAEwJJARgNwdilg3z2t4CL6MCCIl+A7eclO2i0sBiyz9zlgFuaez/kcMwBGBM4ZDCJRDNvZwARrOlJvAJcrPZrFPEWCefbB0v2b4Fy/W4+9Ho3Hed7/lCC8T5U+C6VuC5HrhbWp7nfcFfFQ6Hww5XrVYPBEGondTr/EW7x58Jbb7ROOWbzeZOarVatUqlcvgDDgpIGBsswmUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Starting a new Rosmaro project&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_new_project-0c5d5f8515e233865bdeb94680f11dfc-86d16.png&quot;
        srcset=&quot;/static/editor_new_project-0c5d5f8515e233865bdeb94680f11dfc-bd9cb.png 300w,
/static/editor_new_project-0c5d5f8515e233865bdeb94680f11dfc-fe5c6.png 600w,
/static/editor_new_project-0c5d5f8515e233865bdeb94680f11dfc-86d16.png 1200w,
/static/editor_new_project-0c5d5f8515e233865bdeb94680f11dfc-92b91.png 1800w,
/static/editor_new_project-0c5d5f8515e233865bdeb94680f11dfc-c030b.png 2400w,
/static/editor_new_project-0c5d5f8515e233865bdeb94680f11dfc-57f14.png 2784w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Every &lt;em&gt;Rosmaro model&lt;/em&gt; must have a &lt;em&gt;main&lt;/em&gt; node. In our case it&apos;s the following graph.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/bunny_app-9dacc6411fa1e148984dbc2677fffb7b-b3be4.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1000px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 64.3%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAEDBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAey0FUf/xAAYEAEAAwEAAAAAAAAAAAAAAAABABARMf/aAAgBAQABBQJnAdE2ZX//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAYEAACAwAAAAAAAAAAAAAAAAAAIQERIP/aAAgBAQAGPwJlws//xAAcEAEAAgMAAwAAAAAAAAAAAAABACExQVERcYH/2gAIAQEAAT8hflSn2OxZplxOpPUytU5KME//2gAMAwEAAgADAAAAELAP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGxABAAMBAQEBAAAAAAAAAAAAAQARITFRQWH/2gAIAQEAAT8Q1iDABv7DeILY2J32UCEfsJCN9XZtKgq3IGIB3Cf/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A whiteboard drawing of the most important screens&quot;
        title=&quot;&quot;
        src=&quot;/static/bunny_app-9dacc6411fa1e148984dbc2677fffb7b-b3be4.jpg&quot;
        srcset=&quot;/static/bunny_app-9dacc6411fa1e148984dbc2677fffb7b-27d6e.jpg 300w,
/static/bunny_app-9dacc6411fa1e148984dbc2677fffb7b-5d038.jpg 600w,
/static/bunny_app-9dacc6411fa1e148984dbc2677fffb7b-b3be4.jpg 1000w&quot;
        sizes=&quot;(max-width: 1000px) 100vw, 1000px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;We add it by clicking &lt;em&gt;ADD NODE&lt;/em&gt; and typing its name.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_typing_main_name-4b3c7f91a393d082e8d764edb0289087-47fb1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 400px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 21.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA7klEQVQY022NyUrDcBDG84iK6EGfxEfwKVrQmxYCLuBF8eJBxAVTpYuFlsSaWmPabP8lyc8xCiI48DHMt41zPQ7Y2HVZaR2wfXzOztkl6+0Om8KtCre15zJfJtRlSVVV/E4N/1xOuFji3nXp3Hpc9J65mQQcej1OHgfNPn0akmQZaZYTJwWLVJEqyzytGb7FHHX7RKLV8sxai1MaQzwLSaJ3wsBH5zlUJZT2G3XFIo4YTV4YjKeM/BkfmcF9gNZVn7X2Pl7w2mSUUjhaa7SUKtlKGwoh86L4AyO6aTzmx6MFhijJuPen5JKxon91fQLskyZHpGJCFAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Typing the name of the main node&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_typing_main_name-4b3c7f91a393d082e8d764edb0289087-47fb1.png&quot;
        srcset=&quot;/static/editor_typing_main_name-4b3c7f91a393d082e8d764edb0289087-05471.png 300w,
/static/editor_typing_main_name-4b3c7f91a393d082e8d764edb0289087-47fb1.png 400w&quot;
        sizes=&quot;(max-width: 400px) 100vw, 400px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Now we&apos;re going to add the first graph child.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_new_main-bf64d9ab77a43ae7844500e9ebfa2eec-57f14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.560344827586206%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAABmElEQVQoz6WSz0sCQRTH91DH+geioPASBIK5HtRTUJJReOhP6NSf4kb/gucO0SUxQfCUsju6UniIDF1pSVfFLXd13XVnppn1BwliWg++zHvMdz68mTeMmE7tPIuP3GvpjatWpKhUkTiqeq3ONRtNR1WpylXKlUld+6hxUlki/ipdo/K7TM9dJeIJF5PNZMK6rmHTNPF/g+f5MybLC4fdvglJbdm2bSGMLJovKRNCiHK53DEDBOGIdkeEqMgGpkIILSonaIcEGGaEEdCyLAc42nPiZz4rxkCa0pqwpoGDwQAZhoFjsRjudDpzoeMOaUr8KJ/PY0VRpoEjKJZlGdN1USDxI9pAsVgcAvv0Dedcedbb/fBMrkymHHaGAi0yKDKJgWVCw+xBGw6DeJcRBgCEGR6AkKJ1cV0zsKI1MMTan/+hKIonzP1D8iAOCr078KRfJ1P6LRD1G76gZ15K+tenqrfb7V+lqqrWarWMdDodYnz7nrWLyKn38jzCenwBdnXLxa5sbrMbu3tsMBBg/X7/QgoGg163273+DdLcQsF91AvpAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Adding a new child&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_new_main-bf64d9ab77a43ae7844500e9ebfa2eec-86d16.png&quot;
        srcset=&quot;/static/editor_new_main-bf64d9ab77a43ae7844500e9ebfa2eec-bd9cb.png 300w,
/static/editor_new_main-bf64d9ab77a43ae7844500e9ebfa2eec-fe5c6.png 600w,
/static/editor_new_main-bf64d9ab77a43ae7844500e9ebfa2eec-86d16.png 1200w,
/static/editor_new_main-bf64d9ab77a43ae7844500e9ebfa2eec-92b91.png 1800w,
/static/editor_new_main-bf64d9ab77a43ae7844500e9ebfa2eec-c030b.png 2400w,
/static/editor_new_main-bf64d9ab77a43ae7844500e9ebfa2eec-57f14.png 2784w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;In order to make binding handlers convenient, we&apos;re going to use &lt;em&gt;CamelCase&lt;/em&gt; node names. That&apos;s why we&apos;re adding a local node called &lt;em&gt;IsABunnyOwner&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_adding_is_a_bunny_owner_local_node-0cf558a3c54f2f159aeea6ee2eb50233-47fb1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 400px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 35.75000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAAsTAAALEwEAmpwYAAABgklEQVQoz21RyU4CQRSc3/PkCXGJSwiJXNSbiX6LMVFQBAxbAIEYMXpmCQoEGDY1CDgEGGZAZgbK1w0aDnbSqa55r+t11QiTyQSGrmNm6JgukHFN0zifGkt7qc7usR6GOvHfJej0caCO0O7LkOQhWoSMs+bOQEZ7sdn5i9cH6Cvqn9iy4Gw2g6COxzjyx2G2+2G69GGd8DTyiPtiFesOP3acQWxfB7F1FcAa1RlaXWEaOhcdjb/xzVxOp3NBNm3fE+FCpgsvNu0+HPricKdzMJOAxRXC3k2I11fPPTjwxmCj/h7d+29xy6n3T8RKNSTEBqLFGrLNNlRNxwPxu4KISK6EKGE0X+ZujkMPkIYKnql+lXyBM/XKHWlkXTAMA0qvi3wmjWwyhWa9gnIhj0w6xVHt9/+mdyhDC9ndpRg8mTxst3fYcASwQ5GsnLl41gILVOpKKIsVlEQR9UYdlWoVjbcGRMJWpwOZXqMoQ3x0e9y+mWJ5Eus4CSf4meVsdYf5z/oB2zXoautqsFcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Adding the IsABunnyOwner local node&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_adding_is_a_bunny_owner_local_node-0cf558a3c54f2f159aeea6ee2eb50233-47fb1.png&quot;
        srcset=&quot;/static/editor_adding_is_a_bunny_owner_local_node-0cf558a3c54f2f159aeea6ee2eb50233-05471.png 300w,
/static/editor_adding_is_a_bunny_owner_local_node-0cf558a3c54f2f159aeea6ee2eb50233-47fb1.png 400w&quot;
        sizes=&quot;(max-width: 400px) 100vw, 400px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Local nodes are what we draw as children of composites and graphs. Handlers cannot be associated with local nodes.
Actual nodes are used as underlaying nodes for local nodes. They may be associated with handlers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the whiteboard drawing there are two nodes called &lt;em&gt;ENTERING THE NAME&lt;/em&gt;. Because &lt;em&gt;Rosmaro local nodes&lt;/em&gt; must have unique names, we&apos;re simply going to call them &lt;em&gt;EnteringTheName #1&lt;/em&gt; and &lt;em&gt;EnteringTheName #2&lt;/em&gt;.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_added_entering_the_name_nodes-50d02cec85264be8b398a957b79c8144-e0ba3.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 6.512820512820514%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAAAsSAAALEgHS3X78AAAAQUlEQVQI1z3IMQoAMQgF0dz/XF7APrGyUAQ7wUL4ywZ2Xzez3B1nb2QmXlUFEYGqYmbui4j7uhsfIoK7/W1mYGY89YdLgr0ETPkAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Added both EnteringTheName nodes&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_added_entering_the_name_nodes-50d02cec85264be8b398a957b79c8144-86d16.png&quot;
        srcset=&quot;/static/editor_added_entering_the_name_nodes-50d02cec85264be8b398a957b79c8144-bd9cb.png 300w,
/static/editor_added_entering_the_name_nodes-50d02cec85264be8b398a957b79c8144-fe5c6.png 600w,
/static/editor_added_entering_the_name_nodes-50d02cec85264be8b398a957b79c8144-86d16.png 1200w,
/static/editor_added_entering_the_name_nodes-50d02cec85264be8b398a957b79c8144-92b91.png 1800w,
/static/editor_added_entering_the_name_nodes-50d02cec85264be8b398a957b79c8144-e0ba3.png 1950w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Then, we add the remaining local nodes: &lt;em&gt;FeedingTheBunny&lt;/em&gt; and &lt;em&gt;Thanks&lt;/em&gt; in the same way.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_added_all_main_nodes-1a5d547c39452ceceef7463cd4a8a54f-57f14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.560344827586206%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAAB60lEQVQoz6WRzW7TQBDHLSGO8AIIpFZckECRIO4hzQkJKopAIPEInPooWW490zsXuKQqSJVyQKRyHBloD4mCie3GUT6c2Eq8xvba62HHCYhSUIsY6e/1zsz+ZnZH0mr7q4faB9L5ohPLsCpm1yQ9q0fiMCLTyZQ4Y4dYpkk6nU7+j+rbfdL92iWYK1Sxe3bFNMwXe7t716WDen2TUh/iOIZfzbIs+FdTFOWxdKA07gVRzMWeJUnCcJ3NZuzlzk6+4j4MQ1atVpkoyjjnzDRNZhgGo0GQx4Vi4c+azeYDSW007mN3QhmKp/xUZZEMIhkYY5CmKYzHYxiNRiAKYThbClRV3ZQaS6BIXgD5AhhFUX5oOByC4zi5D4Htdht0Xc+fJMuy8wPRZ9s2HB/3YDAY5F0iAP1YDFfcZwvq2cBl9RP2F99pYIRv+BvQ931otVpweHT088qu64IYxo/O/twhDoXjcAUpYYyzJMWBcfyKAeTiiypcXJXP53MuGCeEMeTmQEVVN0Y0gP6cQsAY/I9pmvZQqr59d3dX/fjttfqJbu+/p2+an+krRaP1tk5nnkenrkvdM+R5nj+ZTMJarbYhrd25fen5k0fFrWdP5VtFWb5wdUW+eG1VvnLjplxeX5dLpdK5VC6Xi4VC4fJ3QdU8JGpWnQ4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;All main nodes are added&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_added_all_main_nodes-1a5d547c39452ceceef7463cd4a8a54f-86d16.png&quot;
        srcset=&quot;/static/editor_added_all_main_nodes-1a5d547c39452ceceef7463cd4a8a54f-bd9cb.png 300w,
/static/editor_added_all_main_nodes-1a5d547c39452ceceef7463cd4a8a54f-fe5c6.png 600w,
/static/editor_added_all_main_nodes-1a5d547c39452ceceef7463cd4a8a54f-86d16.png 1200w,
/static/editor_added_all_main_nodes-1a5d547c39452ceceef7463cd4a8a54f-92b91.png 1800w,
/static/editor_added_all_main_nodes-1a5d547c39452ceceef7463cd4a8a54f-c030b.png 2400w,
/static/editor_added_all_main_nodes-1a5d547c39452ceceef7463cd4a8a54f-57f14.png 2784w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Now it&apos;s time to add arrows. In order to do it, we need to put the cursor over some node, aim the square handler displayed on it and drag a line from it to another node.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_drawing_an_edge_from_is_a_bunny_owner-3a83194dd9c588cf5ea3b14121416f81-6b5da.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 57.14843750000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABX0lEQVQoz4VSwU7CQBDtD3vQr/Ei8WL04s0QjuqBxKQmhKWxYpAUQqGtbW0KbbctPHYWlmxBwyQvm52deTPzZo0wSZEkCYqiwGazgW50P/adM4OXJeq6RlVVEopEJ/oJQ7iuC8/zdnEiJ45jCc55o7hRCgffg4LVozLy+76P2WyGxWIhY7Isg+M4EqvVqklICaWoqAjVQ5qmaLVaME3z7Jh6AwaR6YTK8jzHdDqVY6mEKIowGo0Od10adTYISUtCu93Gcrk86YDeaHnr9bqhtU5s8CMNKdi2bZkcimXM5/OTsf4bt9FhuddSD+h2u7JblUhFSIbxeCyXRMX10eVSCkGUF7sOcebPUQJ1HQSB1PbPf/j2PUHHGuLhneHLCzCJfuGEMZIsRy0kUFIc/qlGrvsVjBcxVq/Xw/VTBxc3d7i8vceVwOPzK4afNphl4UNoSmDWAH3G0B8QBhJsfypsAcjTTepAamBtAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Drawing an edge&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_drawing_an_edge_from_is_a_bunny_owner-3a83194dd9c588cf5ea3b14121416f81-86d16.png&quot;
        srcset=&quot;/static/editor_drawing_an_edge_from_is_a_bunny_owner-3a83194dd9c588cf5ea3b14121416f81-bd9cb.png 300w,
/static/editor_drawing_an_edge_from_is_a_bunny_owner-3a83194dd9c588cf5ea3b14121416f81-fe5c6.png 600w,
/static/editor_drawing_an_edge_from_is_a_bunny_owner-3a83194dd9c588cf5ea3b14121416f81-86d16.png 1200w,
/static/editor_drawing_an_edge_from_is_a_bunny_owner-3a83194dd9c588cf5ea3b14121416f81-92b91.png 1800w,
/static/editor_drawing_an_edge_from_is_a_bunny_owner-3a83194dd9c588cf5ea3b14121416f81-c030b.png 2400w,
/static/editor_drawing_an_edge_from_is_a_bunny_owner-3a83194dd9c588cf5ea3b14121416f81-6b5da.png 2560w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;At this point, the newly created arrow can be customized. All we need to do is to click it and then enter its new name. This one is going to be called &lt;em&gt;has a bunny&lt;/em&gt; and will tell us what happens when the user has a bunny - she goes from the home screen to the screen where she&apos;s supposed to enter her name.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_the_edge_from_is_a_bunny_owner_is_renamed-e1fe72beefc1c742260975b3b9c975d5-57f14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.560344827586206%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAAB6klEQVQoz6VS3WoTQRTey97oKxS0ULwKaqZN0q2gotUIvehjdfoEfQXxshQhNBBpa3bDIosk5Md02jRrspvdBDNxd5OdHedMk7W22JsOfOycv+98c84qRrHwyDSOcaPZwudnZJecEQzo/exhx3aw4ziYEILbP9rYtm3ps7oWJm0i8s/hu3vZuYS6vcODwxXl9OQkT+mYh2HI73vK5fK2clrW3kyCkAl7GkXRNObxFO6AOL66w5lMJhJgM8akD/LnuaHwxZVK5b2ia9pbUCcQA0SAC6J/OrdaLV6r1bhlWdIeDAa8Xq/zbrcLZjwH13U9r2hzQtEwIYTj+74sgMLhcAhx6YdmN/B/QoB4RlIolsBd102UigUtVCWvuJMwCIJFgFer1YRoUQzNFg2vqb1NGMAMgVA8GQKgilLKPc/jpmneVMSvz/kWISyFwXxYxNhsymazCIYocdHpsFKplNhirqzZbLJGo8HEYqSPXQ2dAa8k/KppWzb1eW/s85F/v3/RMIwPyufC0auPx19+7xcOaOm7SZ1+n/YFnIFLP+nfaJVc0F+jEXU9j4oRULHxBN5f31go9ovF4pbyIrPxYOd1Jv1uY3Ut/zKDnqcRWl9fQ5lsFi0tP0ZPnj5Dm6qKsrkcyt0BVVXTqVTq4R/naz5M9V0hmQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Giving a name to the edge from the IsABunnyOwner node&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_the_edge_from_is_a_bunny_owner_is_renamed-e1fe72beefc1c742260975b3b9c975d5-86d16.png&quot;
        srcset=&quot;/static/editor_the_edge_from_is_a_bunny_owner_is_renamed-e1fe72beefc1c742260975b3b9c975d5-bd9cb.png 300w,
/static/editor_the_edge_from_is_a_bunny_owner_is_renamed-e1fe72beefc1c742260975b3b9c975d5-fe5c6.png 600w,
/static/editor_the_edge_from_is_a_bunny_owner_is_renamed-e1fe72beefc1c742260975b3b9c975d5-86d16.png 1200w,
/static/editor_the_edge_from_is_a_bunny_owner_is_renamed-e1fe72beefc1c742260975b3b9c975d5-92b91.png 1800w,
/static/editor_the_edge_from_is_a_bunny_owner_is_renamed-e1fe72beefc1c742260975b3b9c975d5-c030b.png 2400w,
/static/editor_the_edge_from_is_a_bunny_owner_is_renamed-e1fe72beefc1c742260975b3b9c975d5-57f14.png 2784w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Let&apos;s draw all the remaining arrows and call them after events which cause behavior changes.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_all_main_edges_are_ready-f0147f0ac1cee569ea351748d1f0fddd-99d65.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.034324942791756%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsSAAALEgHS3X78AAABZ0lEQVQoz41S7Y7BUBDto/u5/tin8QbbRFARYpVIKFpaX6VotTjrTPY2V9lkJ5nMtLlz5syZMfBr9/s9j/Tr9ZpH5f8xQwdRTlutVjBNE1arhdbDu90uNpsN1uu1RN/34TiOxOVyiSAIkGUZDAWgjD/3+z1c10W9Xpf8cDjgdDohTVNcLheJ5/MZw+EQnU5HfDwey39heLvdsFgspItt2xiNRojjGMVmRWOT2WwmDKMokvcCmCSJdOn1vtFsNjEYDBCGYT4icxaTFRvxPUkoaTzPk+8cULfj8ZjrwQd8yJF9P8B2u5Umu90ud8uyRBpKIUvh7NVq9Wk8AjqTCcJHAVm9M7LkUubzuTSkfgLYaDRQ/ii/nAWBvMdiyEI/KxZPp1PRTo2tn97LyO12G/1+/4ktiykB9eICyE4H0c/NUMerrFQqoVL5lDxNM9m6+WVKo1qtJjrqQMXcKHYojsDt8iQ4qq7VX3U/ZKVLldCoaFsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;All main edges are drawn&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_all_main_edges_are_ready-f0147f0ac1cee569ea351748d1f0fddd-86d16.png&quot;
        srcset=&quot;/static/editor_all_main_edges_are_ready-f0147f0ac1cee569ea351748d1f0fddd-bd9cb.png 300w,
/static/editor_all_main_edges_are_ready-f0147f0ac1cee569ea351748d1f0fddd-fe5c6.png 600w,
/static/editor_all_main_edges_are_ready-f0147f0ac1cee569ea351748d1f0fddd-86d16.png 1200w,
/static/editor_all_main_edges_are_ready-f0147f0ac1cee569ea351748d1f0fddd-99d65.png 1748w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;This graph isn&apos;t finished yet. The whiteboard drawing wasn&apos;t perfectly detailed. There are at least two missing elements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the initial node&lt;/li&gt;
&lt;li&gt;underlaying nodes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We need to specify that this graph starts from the &lt;em&gt;IsABunnyOwner&lt;/em&gt; node. All we need to do is to draw an arrow from the &lt;em&gt;start entry point&lt;/em&gt; to the &lt;em&gt;IsABunnyOwner&lt;/em&gt; node.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_entry_point_of_main-8f72254778245a0e1e6cf45d0c4e689e-596bb.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.97920277296361%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsSAAALEgHS3X78AAABdUlEQVQoz41TW4rCQBCcW3sE7+CXR1lRPxSji36o5EEwCJrE9yPRJNamep2QHVh2C5rJkJnq6uoehTder1e1MvI8R5ZleD6feDwesv4Hqk6igzifz/jodNDv9zEYDDAejxEEAfb7PeI4xna7xXK5hOu68DwPjuPger1CaQKNolQWRRE2mw0mk08kSVKqLUQtldZjvV7DLolmsxls28HtdvtWWBSFkDCz7/uYz+dIS6K/QFuoOAxDqYhJlfaLWbrdLkajEabTKU6nE3a7nQQvcX+5XHC/30Vdmqbia1YGy6Y6cimdbbVa4XA4yCGq5SUqZzKWTfVUwTNMwpVJbNtGr9eT/9IUmttut8VkDRLS5DiK5dJvYKlyriRL3hYpym02m9Ih0x8SM+qgcnabXieGzz9K1lgsFhgOh9X+eDyKR7SCatlZeqmng7bUx61qCn8QrVYLjUajOsAZ4yxaliXzyL35GOrfyhxoE+wm7aAqBkuuPwaT+AsH+0oLwngELwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The main graph got an initial node&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_entry_point_of_main-8f72254778245a0e1e6cf45d0c4e689e-86d16.png&quot;
        srcset=&quot;/static/editor_entry_point_of_main-8f72254778245a0e1e6cf45d0c4e689e-bd9cb.png 300w,
/static/editor_entry_point_of_main-8f72254778245a0e1e6cf45d0c4e689e-fe5c6.png 600w,
/static/editor_entry_point_of_main-8f72254778245a0e1e6cf45d0c4e689e-86d16.png 1200w,
/static/editor_entry_point_of_main-8f72254778245a0e1e6cf45d0c4e689e-596bb.png 1731w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Selecting underlaying nodes means specifying which graph node actually lays under a local graph node. For example, there&apos;s the &lt;em&gt;IsABunnyOwner&lt;/em&gt; local node. But what&apos;s its type? Is this a leaf? Or maybe it&apos;s a subgraph? In order to make it clear, we need to add an actual node and wire it with the local node. It may sound a bit complicated, but it&apos;s actually pretty simple. Here&apos;s how we do it. &lt;/p&gt;
&lt;p&gt;First, we need to create the actual node. We do it exactly in the same way the &lt;em&gt;main&lt;/em&gt; node was created, because &lt;em&gt;main&lt;/em&gt; is an actual node as well.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_adding_is_a_bunny_owner_actual_node-3d1674cf6b26647860f582f6ded0c355-47fb1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 400px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 31.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAABO0lEQVQY03VRXU/CMBTdTzQkxvjgX/D3+KYYfTAR0CW84KMxvqEJGBFhjLEEHAzZBu3abj3eFiG+2OS0vben99wPR0oJlAWhBIoChVLbu/VtYThCCHomm5bW+l84ORFHiyX6X3NMlt+Is7W9D6KFhTePwfMcknjKiO0DkhZtBYkbe+d3KIg+vrrHwXlNnzZaOHtuo1Kt4+TaReWihqPLBnqziNgl1D5Du+Pv2gV1MsbR7Lzru9c3PHQ/8OIHqLc7cMludvto9YaI0wycMTDCtnSFhJcYxylc+jNNUtsmU4GjpNRpvMB6GevAGyIYeZiOfUwnAQrObWZZmiAMQ0RRhNUqIZfC40Djpu3jsHqLJy+wPNMaZ8MYN6XkQmpJCgbCDIFOQ2AU1AzFqBvsBiSExJqq+5zNsSGO+vX/AGdRwpLS8VVAAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Adding a new actual node - IsABunnyOwner&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_adding_is_a_bunny_owner_actual_node-3d1674cf6b26647860f582f6ded0c355-47fb1.png&quot;
        srcset=&quot;/static/editor_adding_is_a_bunny_owner_actual_node-3d1674cf6b26647860f582f6ded0c355-05471.png 300w,
/static/editor_adding_is_a_bunny_owner_actual_node-3d1674cf6b26647860f582f6ded0c355-47fb1.png 400w&quot;
        sizes=&quot;(max-width: 400px) 100vw, 400px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Then, we go back to the &lt;em&gt;main&lt;/em&gt; node, select the &lt;em&gt;IsABunnyOwner&lt;/em&gt; local node and select the &lt;em&gt;IsABunnyOwner&lt;/em&gt; actual node as its underlaying node. That&apos;s it!&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;Thanks&lt;/em&gt; node is a leaf as well. We add and wire it in the same way as we did it with the &lt;em&gt;IsABunnyOwner&lt;/em&gt; node. &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_Thanks_node_added_and_wired-daaa79a558699e9428c2cdbf36d5e340-6ab73.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 15.840000000000002%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAAsSAAALEgHS3X78AAAAqUlEQVQI122OsQrCMBiE+6SCm4urPoDvoOADiIsIpYN0cCsuQlcHdWjaQgm1VlNDkjZnkroofnDczw13v0cfT6S3Ctbz6g5S9rcUAl3XwaK1/pLL8B9vHh0x3oZYHmJMgj1Gmx0WJmuVQvsp/KUv1eBSoRESzIy/pHS5R8sS1yQByXLjBKfzBTVj4Jw7FUWBNMucW1FKocxYTARmYYTBysdwHWBqnqmbBm+n8t8EDXdAuwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Thanks added and wired&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_Thanks_node_added_and_wired-daaa79a558699e9428c2cdbf36d5e340-86d16.png&quot;
        srcset=&quot;/static/editor_Thanks_node_added_and_wired-daaa79a558699e9428c2cdbf36d5e340-bd9cb.png 300w,
/static/editor_Thanks_node_added_and_wired-daaa79a558699e9428c2cdbf36d5e340-fe5c6.png 600w,
/static/editor_Thanks_node_added_and_wired-daaa79a558699e9428c2cdbf36d5e340-86d16.png 1200w,
/static/editor_Thanks_node_added_and_wired-daaa79a558699e9428c2cdbf36d5e340-6ab73.png 1250w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Nodes &lt;em&gt;EnteringTheName #1&lt;/em&gt; and &lt;em&gt;EnteringTheName #2&lt;/em&gt; are a bit more interesting, because even though they are two separated local nodes from the point of view of the &lt;em&gt;main&lt;/em&gt; node, they utilize the exact same actual node as their underlaying nodes. That&apos;s why we add just one actual node &lt;em&gt;EnteringTheName&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_adding_entering_the_name_leaf-739d6c37b3ed37165ab9652cf044fdbd-7c91f.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 39.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABO0lEQVQoz62PzU4CMRSF5yl9BRYGo0ZijK59BPe6VlFADCKwYaEYE1csBCkzMPzNjFMSUWbazvG2BmNIjCxscnp/cvv1XCuOY6yqKIoghIA+SZIYLR9LD62ifwcu9CdQ0UAiBSRFJb9y3TP1QtQTvzhclvXouNjIlpDJ3eKgWEOx2cJuvoK9QhU71NvM3uCwXEf4NjPQOBbfbrRB9cOkTq37bh+psxLSF2VkCjUUmm1s5SrYzleRviwjdXqN/asa+OzdEKSU5rFUim5lMEIqzPVH2qFew+n30RsM0e31MHBdtBnD80sHLdbF2A8Q0ZrT6RTD0Qichwg5NzAnFLizFY4bT1gnU27ICTifwxuP4U8mcAnICObYNmyKnQ6D53nQMyGBNNCn2g8CJCICm3ygwRSO6g9YOzmH+8rxCT1ZWTGNBSv+AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Adding EnteringTheName&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_adding_entering_the_name_leaf-739d6c37b3ed37165ab9652cf044fdbd-7c91f.png&quot;
        srcset=&quot;/static/editor_adding_entering_the_name_leaf-739d6c37b3ed37165ab9652cf044fdbd-035b7.png 300w,
/static/editor_adding_entering_the_name_leaf-739d6c37b3ed37165ab9652cf044fdbd-7c91f.png 400w&quot;
        sizes=&quot;(max-width: 200px) 100vw, 200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Then we pick it as the underlaying node for both &lt;em&gt;EnteringTheName #1&lt;/em&gt; and &lt;em&gt;EnteringTheName #2&lt;/em&gt;.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_selecting_entering_the_name_1_underlaying_node-4ed41f36a3eaeafbf77867c1d84daec1-1a185.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 12.873563218390805%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAAsSAAALEgHS3X78AAAAwklEQVQI15WJzWrCUBgF87btxpfoulA3PoCbgqXgQtGViKVitaIYFH/SaxINKrdIMNSbXMn5TvMKLoYZGKfurqQ2XUjlcywvvaH0fgKhiOR5LiTvxnn9nrH6NeFzp8+nVpctd0lrDO3tRmstTdFZltKklsk1Y/KXFhheDKjOCT9UyL6/L7zj/KjpxFrj8qtxPh5wCgPstgobz0Mcx9DF84MAUbRHGJ2w9iOsVAhP+RhvDaojD49vDZTe23ioNVHuDvAPXe/aGRWnqA8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The EnteringTheName #1 local node uses the EnteringTheName actual node as its underlaying node&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_selecting_entering_the_name_1_underlaying_node-4ed41f36a3eaeafbf77867c1d84daec1-86d16.png&quot;
        srcset=&quot;/static/editor_selecting_entering_the_name_1_underlaying_node-4ed41f36a3eaeafbf77867c1d84daec1-bd9cb.png 300w,
/static/editor_selecting_entering_the_name_1_underlaying_node-4ed41f36a3eaeafbf77867c1d84daec1-fe5c6.png 600w,
/static/editor_selecting_entering_the_name_1_underlaying_node-4ed41f36a3eaeafbf77867c1d84daec1-86d16.png 1200w,
/static/editor_selecting_entering_the_name_1_underlaying_node-4ed41f36a3eaeafbf77867c1d84daec1-1a185.png 1305w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_selecting_entering_the_name_2_underlaying_node-832e69cdfe5476358c7374c3cd0b7eed-89abb.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 14.263803680981596%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAAsSAAALEgHS3X78AAAAvklEQVQI15XHsU7CUBiG4V4uCTsJkyMj4SYcjJMGCcRYgwODiy6KPbSlDdSeAtZIpP9p8/0fvQWGJ29e7+HD6NvmW1/CRGfLUH0T67+IAlCSF/P694+8fn3n6HnBq/ETB9M5s/2BTV2zaRqKCJ1zFFfzJI6nStrWPAoY7n8YFAd+tTa/f1RVekWeo7A5dtYiiWOsowgrY5C3X5Yl0jRFlmVIthZmvUUQpfiMLfzgiN7dDN3bCTo3Ywz9BaqqwhksdNwTqUv8WgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The EnteringTheName #2 local node uses the EnteringTheName actual node as its underlaying node&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_selecting_entering_the_name_2_underlaying_node-832e69cdfe5476358c7374c3cd0b7eed-86d16.png&quot;
        srcset=&quot;/static/editor_selecting_entering_the_name_2_underlaying_node-832e69cdfe5476358c7374c3cd0b7eed-bd9cb.png 300w,
/static/editor_selecting_entering_the_name_2_underlaying_node-832e69cdfe5476358c7374c3cd0b7eed-fe5c6.png 600w,
/static/editor_selecting_entering_the_name_2_underlaying_node-832e69cdfe5476358c7374c3cd0b7eed-86d16.png 1200w,
/static/editor_selecting_entering_the_name_2_underlaying_node-832e69cdfe5476358c7374c3cd0b7eed-89abb.png 1304w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;em&gt;FeedingTheBunny&lt;/em&gt; is going to be far more complicated. Here&apos;s how we decided that it has two regions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the bunny itself&lt;/li&gt;
&lt;li&gt;controls for carrots (looking for carrots and giving them to the bunny)

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/feeding_the_bunny-eea3bdd163f2a2a717352a7df70e0ccc-9c3b0.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 400px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 63.74999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe9LDQP/xAAYEAADAQEAAAAAAAAAAAAAAAAAARARIf/aAAgBAQABBQJnY1pk/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFxAAAwEAAAAAAAAAAAAAAAAAABAxAf/aAAgBAQAGPwIrur//xAAcEAACAgIDAAAAAAAAAAAAAAABEQAQMYEhYXH/2gAIAQEAAT8hArgrUAfBeUDJ6M6ir//aAAwDAQACAAMAAAAQA8//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAfEAEAAgEDBQAAAAAAAAAAAAABABEhEDFRQXGRobH/2gAIAQEAAT8Qbv53SjbG3TVrzoadDkPkVZiDmz3DbOZ//9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A whiteboard drawing of FeedingTheBunny&quot;
        title=&quot;&quot;
        src=&quot;/static/feeding_the_bunny-eea3bdd163f2a2a717352a7df70e0ccc-9c3b0.jpg&quot;
        srcset=&quot;/static/feeding_the_bunny-eea3bdd163f2a2a717352a7df70e0ccc-0ff67.jpg 300w,
/static/feeding_the_bunny-eea3bdd163f2a2a717352a7df70e0ccc-9c3b0.jpg 400w&quot;
        sizes=&quot;(max-width: 400px) 100vw, 400px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It makes it a composite with two children.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_creating_feeding_the_bunny_composite-53b5fff1909c9d1ecdf1c4aac18c267e-47fb1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 400px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 22.749999999999996%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAABKklEQVQY022PTUsCURSG5x9Gy1pZv6Bd0EYCobb9gVoUGBQkGEGWlUYJQasWkU7OOF/OjNrkxzhqM/N0vUqrDrw83Hsuzz1H6Q5HdAdDeoLT6VSyszz3ZG9ENJkym81kP0kS5pWm6b9RVg7PWD8psJkvkn99IyO4IbJ2fCHvV4/OKb2rUjKeTEilMF0GkgX+Stm5eiB7XWX/rkalabAnmLt9Jlt6ZFdku1jmRTfl44mYchanzJWxFC3kI7FBPxKfpQmKaZj4vo+u67RaLTRNQ23UBXX8Tpc4jvkRIssyMdwvdMen3jQxLZv7j5ByIyZXqpA5vcQOvlE81yUIAhzH5rOpSalpLOSu5xGGIVEU4bptbD+g1e6h6g5W2+NJHVPTEg6qNbYKN3j9Ab8aDmjlRVtczgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Adding the FeedingTheBunny composite&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_creating_feeding_the_bunny_composite-53b5fff1909c9d1ecdf1c4aac18c267e-47fb1.png&quot;
        srcset=&quot;/static/editor_creating_feeding_the_bunny_composite-53b5fff1909c9d1ecdf1c4aac18c267e-05471.png 300w,
/static/editor_creating_feeding_the_bunny_composite-53b5fff1909c9d1ecdf1c4aac18c267e-47fb1.png 400w&quot;
        sizes=&quot;(max-width: 400px) 100vw, 400px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_feeding_the_bunny_composite-a8b599ebcd73ad436bd6af5fb50d9730-57f14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.560344827586206%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAABoUlEQVQoz6WRy07CQBSGu3Olr2Ci7lywkKpcViYWhYRXcOXLUDc+hUtXhA0GkiIpBSHFBAhSKOEaIJDItPRCZ5xphLRqAsST/DnT0/98c3pKvaVejsqlLPshSWy71Y7JLZklGg6G7Hg0ttWW22yr2Vo/D/oDVm7KxE/qsW6nG8Pnh0Q8cULx2WwYzD/RYrFA/41cLhelOI67FkXRqtVqhqqqhmVZBn63q3TcBwuFwi2VyWSYSqWCer0exEBomqZ9G4TQFgnDMJCu6666Q8RkG/P5fJhMyJRFEUmNBgQAQHO5XDeusiRJqFqtumqr+AXkeZ6pSk3U6HShpusQj+5qIhMTYL1eR4qibAam02lmOBohVdPsT17+MaFTG4H4zzCappEdQZxdEzobHYCfF7mBeUFgLLx0hEmmYVh4hxb27CTMIvl7h4IQGgEV9ecKUgj4H1EsFiNUIpm8en7NqU8cDx6THIiX3sFwPAGz2QxMp9OthL3zyWSySKVSIcp3Tu/fRW6899EIfXpG03uHx/TFpY8OBAK03+/fWsFg0OvxeA6+ANE0Qd570mTCAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The FeedingTheBunny composite with its children&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_feeding_the_bunny_composite-a8b599ebcd73ad436bd6af5fb50d9730-86d16.png&quot;
        srcset=&quot;/static/editor_feeding_the_bunny_composite-a8b599ebcd73ad436bd6af5fb50d9730-bd9cb.png 300w,
/static/editor_feeding_the_bunny_composite-a8b599ebcd73ad436bd6af5fb50d9730-fe5c6.png 600w,
/static/editor_feeding_the_bunny_composite-a8b599ebcd73ad436bd6af5fb50d9730-86d16.png 1200w,
/static/editor_feeding_the_bunny_composite-a8b599ebcd73ad436bd6af5fb50d9730-92b91.png 1800w,
/static/editor_feeding_the_bunny_composite-a8b599ebcd73ad436bd6af5fb50d9730-c030b.png 2400w,
/static/editor_feeding_the_bunny_composite-a8b599ebcd73ad436bd6af5fb50d9730-57f14.png 2784w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Let&apos;s start from the most important part - the bunny. It can be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;hungry&lt;/li&gt;
&lt;li&gt;eating&lt;/li&gt;
&lt;li&gt;full&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&apos;s how does &lt;em&gt;TheBunny&lt;/em&gt; look.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_drawn_the_bunny_graph-3732c8f97a233df92ae01cb6c914a51c-57f14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.560344827586206%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAACFElEQVQoz6WSzW7TQBDH/QJw48IFCSEkxCFS2y2Q5oQgFamAQ98A8TQ1L8GFF0AoB2gjIaw0tkgUCQpNmtpO4uB8OlHWdrLJ7jKz4CoR5dSR/hqPd/c3O7OjlQuHt6tlQ6/Vz3TXdg8c29Hthq37v3y93+sruY6r2+e23uv2VNzxOrpz7uB+9AetZgvPvcl/yN/RioaRi0Iq54zJq1qpVHqhHR4dPa2d1vhgMGBRFLH5fM5830f6mpbLJQuCgMVxzDjnKka/WCzYZDKZw1lRqVSeaYZhZE/rdXnWaIjZbCZgQZbLZQmbVVYhhPJhGMpmsymDYCwBKimlMo5i/C8cxxG4DsCcViwWs9WTH7LleWLBmEgAqzD0eOAyg5sKBufw2zTNnHYMQK/dlqPRSN0QNqjbJTCMoR0S1i7gidCm06mAslVgWVZOMy0riwCQypSUmhi2AEu8DPZ3HYMVoGlmMTs8hkCt9g6afVHqKiwBdrvdf4EWADmODJCWC8ahRCRySMJdt8lj8ABYE/+TlVerVQ4J1TcmUcBj09rt0lB2pqEcx7MrzSFMx56W//jp8Xvza/Tuc5F++XZCg+GAttoebXs+rbf79K1h0cL3n3QyHlN4uDUNh0PlYT6n8HBxoVDY1R4Rcu3Vy72t189zZD/7hJDtB2RjcxNEyP2Nh0S7eYvcuHuPZHZ2SDqd/q8ymcxWKpW6/htXCz6HKY/SRQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;TheBunny graph&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_drawn_the_bunny_graph-3732c8f97a233df92ae01cb6c914a51c-86d16.png&quot;
        srcset=&quot;/static/editor_drawn_the_bunny_graph-3732c8f97a233df92ae01cb6c914a51c-bd9cb.png 300w,
/static/editor_drawn_the_bunny_graph-3732c8f97a233df92ae01cb6c914a51c-fe5c6.png 600w,
/static/editor_drawn_the_bunny_graph-3732c8f97a233df92ae01cb6c914a51c-86d16.png 1200w,
/static/editor_drawn_the_bunny_graph-3732c8f97a233df92ae01cb6c914a51c-92b91.png 1800w,
/static/editor_drawn_the_bunny_graph-3732c8f97a233df92ae01cb6c914a51c-c030b.png 2400w,
/static/editor_drawn_the_bunny_graph-3732c8f97a233df92ae01cb6c914a51c-57f14.png 2784w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;We cannot forget about underlaying nodes. There are three of them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AHungryBunny&lt;/li&gt;
&lt;li&gt;AnEatingBunny&lt;/li&gt;
&lt;li&gt;AFullBunny&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They are simple enough to be leaves. We add them in the same way how we added other leaves.&lt;/p&gt;
&lt;p&gt;This is how &lt;em&gt;CarrotControls&lt;/em&gt; look in the editor.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_drawn_carrot_controls-40bc97a71fe12a9d1dd1d1b1635b6850-57f14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.560344827586206%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAACLUlEQVQoz6VS3W4SURBeH0AT773RNDFeES17IeXCNJHGkuArkCY+A+/Q9TVMTLg0wkUVEgnl120hAQTs/kGX7ZZfOQvsLnvGcw4FMdWrTvLtzpyd+Wa+OcuJ6a9PKmJWaLV/CqqsHiuyIlAYPUMwr0wGVVEFWZKFa/OaQb/UBflCZnmKpBx3O11a9z75ObnD5bLZw5mFwHYcuKsVCoUIl0qlXrdabW8wGDiz2czxPI8yMywWC2c6nW7ibSyXy+3YJnW4XC6/4TKZTKjRaAAhxQghTBKBglo8HodYLMZ8UsBAbTgcQjQahUQiQUNMyahTKpUOCeG3UOX8HFRVxWRC7LouYIw3hZIk3ZJGc2q1GvT7fUZ4gxUh0R1qXEig9QzsOg5eT0HNtm0wTRMmkwkYhsEa0Pe24VX3P4SnudOQrKigqBq2LAuvpZGdgizLUK1Wod1uw3g8ZgR04rOzM+j1eqzZPyecz+d0GrwgoGS0aafTgWazCaIoQj6fZzKpaZoGxUIR6vX6eh1/E5aKxZDnOmzrS9fxyIVQzQyE2FuSc7JfT9d1j0hmPtn15jvFjb8izBdLB1fIAv2XBZOFfaf/kKgJc8mTL/ufCt9nHzN5lBIraGCaqHupI62rox+KgT7kRHRSraPJeIxGoxEiU94COZ+SG5+n0+kD7iXP3z+KhP3vImH+7f4rftfP87vk8fyFn3/m4/l7jx7zD3ee8sG9PT4QCPwXwWDQ7/P5HvwGDTYya6L/MRwAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;CarrotControls graph&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_drawn_carrot_controls-40bc97a71fe12a9d1dd1d1b1635b6850-86d16.png&quot;
        srcset=&quot;/static/editor_drawn_carrot_controls-40bc97a71fe12a9d1dd1d1b1635b6850-bd9cb.png 300w,
/static/editor_drawn_carrot_controls-40bc97a71fe12a9d1dd1d1b1635b6850-fe5c6.png 600w,
/static/editor_drawn_carrot_controls-40bc97a71fe12a9d1dd1d1b1635b6850-86d16.png 1200w,
/static/editor_drawn_carrot_controls-40bc97a71fe12a9d1dd1d1b1635b6850-92b91.png 1800w,
/static/editor_drawn_carrot_controls-40bc97a71fe12a9d1dd1d1b1635b6850-c030b.png 2400w,
/static/editor_drawn_carrot_controls-40bc97a71fe12a9d1dd1d1b1635b6850-57f14.png 2784w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Both &lt;em&gt;LookingForACarrot&lt;/em&gt; and &lt;em&gt;GivingTheCarrot&lt;/em&gt; are leaves. They must be added and have their underlaying nodes selected.&lt;/p&gt;
&lt;p&gt;At this point, all nodes and arrows are drawn. We&apos;re one click away from generating the &lt;em&gt;src/graph.json&lt;/em&gt; file! All we need to do is to click the &lt;em&gt;GENERATE CODE&lt;/em&gt; button.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_generated_code-512a1c3b23a94b9cd4e7870245d8a56c-57f14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.560344827586206%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAABmUlEQVQoz51S60oCQRTeF6iHiB5AQaGLKxKUZNCDOb1O/jPpR95QSlYoSXZnve3V9ceut9GZ6Yy2QkV4GfiYc86c8835Dkd6ey6cfH68or5hItd2soP+APV7fWSZFrJtGzm2g3SMkaqqK1tA5GAVI6xhcWd7nV4W7IfcY+5UqpRKGQ6HEMK73S43DZMbA4MfcoovxXupUqlcz+dzGgQBMU2TjMdjAj5hjBFKKVkul6s7tEOEse/4fDabsXK5fCtVq9UbIBAdslarxYCUj0Yj7nkeh8RdGmOQx4RCIMxsCEVQURRWr9d5u93mzabCfd9fVzD2L0LCxWLxlxAGzzDGq3luvl8X7UcI+sUj03WdNRoNLmSL2A+i3zq3dQjDZaZhMMuyVlJFwja5/xJOp1PxSDu6TjUNU98PKCRSEdsFQEZFUyVYQalWq6VDGbbjcFhmPplMDtpDaO5OeioUrjzXnbzr3UBRtWDoOAGQBq7r7ozhcOhDzTSfz6elaDR6lEwmY2fnF/FLWY6nUqk4+PFEIrEXZFmORSKR4y887kFJmkCACwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Generated code&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_generated_code-512a1c3b23a94b9cd4e7870245d8a56c-86d16.png&quot;
        srcset=&quot;/static/editor_generated_code-512a1c3b23a94b9cd4e7870245d8a56c-bd9cb.png 300w,
/static/editor_generated_code-512a1c3b23a94b9cd4e7870245d8a56c-fe5c6.png 600w,
/static/editor_generated_code-512a1c3b23a94b9cd4e7870245d8a56c-86d16.png 1200w,
/static/editor_generated_code-512a1c3b23a94b9cd4e7870245d8a56c-92b91.png 1800w,
/static/editor_generated_code-512a1c3b23a94b9cd4e7870245d8a56c-c030b.png 2400w,
/static/editor_generated_code-512a1c3b23a94b9cd4e7870245d8a56c-57f14.png 2784w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The generated code should be saved as &lt;em&gt;src/graph.json&lt;/em&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If for some reason you get an error saying that the code cannot be generated, please make sure that all &lt;em&gt;local nodes&lt;/em&gt; have their &lt;em&gt;underlaying nodes&lt;/em&gt; selected.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;Coding different behaviors&lt;/h1&gt;
&lt;p&gt;After having some (I hope) good time drawing, it&apos;s time to code a bit. We&apos;re going to start from the &lt;a href=&quot;https://rosmaro.js.org/doc/#handlers-introduction&quot;&gt;handler&lt;/a&gt; of the &lt;em&gt;IsABunnyOwner&lt;/em&gt; node. The first step is to create a handler file, which in this case is called &lt;em&gt;IsABunnyOwner.js&lt;/em&gt; and it&apos;s located in the &lt;em&gt;handlers&lt;/em&gt; directory.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/IsABunnyOwner.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  render&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;Do you have a bunny&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
      type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;button&quot;&lt;/span&gt;
      value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Yes, I have a bunny!&quot;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
      type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;button&quot;&lt;/span&gt;
      value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;No, I don&apos;t have a bunny.&quot;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A quick look at its &lt;em&gt;render&lt;/em&gt; method reveals that it gives the user a choice by displaying two buttons. Let&apos;s make sure it actually renders without crashing. We will need a test for this handler. All we need to do is to create a file called &lt;em&gt;IsABunnyOwner.test.js&lt;/em&gt; which is located in the same directory.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/IsABunnyOwner.test.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; IsABunnyOwner &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./IsABunnyOwner&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;shallow&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;enzyme&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;IsABunnyOwner&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; wrapper&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;beforeEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    wrapper &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;shallow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;IsABunnyOwner&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;renders two buttons&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;wrapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;input[type=&quot;button&quot;]&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, when we run the following command, we can make sure that it actually renders two buttons.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;npm test&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The graph tells us that we expect the &lt;em&gt;IsABunnyOwner&lt;/em&gt; node to follow either &lt;em&gt;has no bunny&lt;/em&gt; or &lt;em&gt;has a bunny&lt;/em&gt; arrow. Here&apos;s the complete handler code.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/IsABunnyOwner.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  hasABunny&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;has a bunny&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  hasNoBunny&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;has no bunny&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  render&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;thisModel&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;Do you have a bunny&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
      type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;button&quot;&lt;/span&gt;
      value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Yes, I have a bunny!&quot;&lt;/span&gt;
      onClick&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hasABunny&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
      type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;button&quot;&lt;/span&gt;
      value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;No, I don&apos;t have a bunny.&quot;&lt;/span&gt;
      onClick&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hasNoBunny&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;em&gt;render&lt;/em&gt; method takes a reference to the model object. It can be used to build event handlers which call methods of the Rosmaro model. In this case, the same handler that renders the UI, also handles method calls. That&apos;s why there are functions &lt;em&gt;hasABunny&lt;/em&gt; and &lt;em&gt;hasNoBunny&lt;/em&gt;. All they need to do is to return the arrow we want the model to follow when they&apos;re called. If you want, you can find more about this in the &lt;a href=&quot;https://rosmaro.js.org/doc/#handlers-method-handlers&quot;&gt;documentation chapter about method handlers&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And here is the test case. Please notice how &lt;a href=&quot;http://sinonjs.org&quot;&gt;Sinon spy objects&lt;/a&gt; are used to make sure that clicking a button actually triggers a model method.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/IsABunnyOwner.test.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; IsABunnyOwner &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./IsABunnyOwner&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;shallow&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;enzyme&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; sinon &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sinon&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;IsABunnyOwner&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; wrapper&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;beforeEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    thisModel &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      hasABunny&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; sinon&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;spy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      hasNoBunny&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; sinon&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;spy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    wrapper &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;shallow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;IsABunnyOwner&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;thisModel&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;renders two buttons&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;wrapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;input[type=&quot;button&quot;]&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;calls .hasABunny when &quot;Yes, I have a bunny!&quot; is clicked&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    wrapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;input[value=&quot;Yes, I have a bunny!&quot;]&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;simulate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;click&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;thisModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hasABunny&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;called&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBeTruthy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;calls .hasNoBunny when &quot;No, I don\&apos;t have a bunny.&quot; is clicked&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    wrapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;input[value=&quot;No, I don\&apos;t have a bunny.&quot;]&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;simulate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;click&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;thisModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hasNoBunny&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;called&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBeTruthy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;simply follows an arrow when .hasNoBunny is called&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;IsABunnyOwner&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hasNoBunny&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;has no bunny&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;simply follows an arrow when .hasABunny is called&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;IsABunnyOwner&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hasABunny&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;has a bunny&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When it comes to the home screen of our application, the only thing left to do is to wire the handler with the graph node. At the beginning of this article we created the &lt;em&gt;src/handlers/all.js&lt;/em&gt; file. All it&apos;s responsible for is to provide a map connecting graph nodes with their handlers. This is how does it look with the first handler.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/all.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; IsABunnyOwner &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./IsABunnyOwner&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  IsABunnyOwner&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And that&apos;s how we finished the home screen of our app.&lt;/p&gt;
&lt;p&gt;The node meant to enter the name, that is &lt;em&gt;EnteringTheName&lt;/em&gt;, behaves slightly different. It not only follows arrows, but also alters the context of the Rosmaro model.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can think of context as of something similar to state from React or store from Redux.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In order to set the default value of the user name, we&apos;re going to wire a simple handler to the &lt;em&gt;main&lt;/em&gt; node.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/main.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  initCtx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Unknown person&apos;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The list of all handlers must be updated.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/all.js&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ... previously imported handlers&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; main &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./main&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ... previously exported handlers&lt;/span&gt;
  main&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Since now, every time a child of the &lt;em&gt;main&lt;/em&gt; node reads &lt;em&gt;ctx.name&lt;/em&gt; before the context is set to any non-empty value, it&apos;s going to read &lt;em&gt;Unknown person&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;EnteringTheName&lt;/em&gt; handler renders a text field and a button.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/EnteringTheName.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  render&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;Please&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; enter your name&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
      type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;text&quot;&lt;/span&gt;
      value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
      type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;button&quot;&lt;/span&gt;
      value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Done&quot;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/all.js&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ... previously imported handlers&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; EnteringTheName &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./EnteringTheName&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ... previously exported handlers&lt;/span&gt;
  EnteringTheName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Please note how we read the &lt;em&gt;name&lt;/em&gt; property of the context. The method is called with an object. It has a property called &lt;em&gt;ctx&lt;/em&gt;, which is the context. We read it using &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment&quot;&gt;object destructing&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We want to make sure the view renders without crashing and that it sets the value of the text field to the name read from the context.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/EnteringTheName.test.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; EnteringTheName &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./EnteringTheName&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;shallow&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;enzyme&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; sinon &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sinon&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;EnteringTheName&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; initCtx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Joh&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; another&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; wrapper&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;beforeEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    thisModel &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    wrapper &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;shallow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;EnteringTheName&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;thisModel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; initCtx&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;renders a text field and a button&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; field &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; wrapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;input[type=&quot;text&quot;]&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;field&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;field&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Joh&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;wrapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;input[type=&quot;button&quot;][value=&quot;Done&quot;]&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Adding the behavior responsible for handling the &lt;em&gt;Done&lt;/em&gt; button is very similar to what we did in order to handle buttons rendered by the &lt;em&gt;IsABunnyOwner&lt;/em&gt; node.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/EnteringTheName.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  finishEnteringTheName&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;done&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  render&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;thisModel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;Please&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; enter your name&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
      type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;text&quot;&lt;/span&gt;
      value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
      type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;button&quot;&lt;/span&gt;
      value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Done&quot;&lt;/span&gt;
      onClick&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;finishEnteringTheName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To sum it up, in order to handle a button click that makes the model follow an arrow, we need to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;register an event listener that calls a model method&lt;/li&gt;
&lt;li&gt;create a model method that follows an arrow&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The thing that makes the &lt;em&gt;EnteringTheName&lt;/em&gt; node more interesting than other nodes with buttons is that it handles typing on the keyboard as well. We want to let the user type her name, what means altering the &lt;em&gt;name&lt;/em&gt; context parameter. The only way to update the context is by doing a transition. That&apos;s why we&apos;re going to need an extra arrow - to handle a situation when the name is being typed but it&apos;s not ready yet so we don&apos;t want to change the screen.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_main_with_extra_typed_arrow-90666feeedbb6a81cbeb45d47993adcc-57f14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.560344827586206%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAACMUlEQVQoz6VSy27TQBT1kg38AhJ0wyoqqQkJRiAQiQgSC1TxUTW/wAewYoWKEMjKq2oeRApZhCaKH6mDE9d2nGRiJ05mhjtTXNoqEguudTT2+N5zzr0zQlP5eqf1vSKf9HqyoekHuqbLDCNrJJ/ZZxyGbsiaqsmu48qeO5GtX5asqzrkG2w9ME9NVvfu8NPhjnB8dJQPggWNooj+b1Sr1deCUii+6Kka9jwvWi6XEcaYMW/FCp6Rexq5U/v6vxXUkUaj8VIoFYvZTqdDu90umc/nZLPZcDVCyAVY2LZNoS06nU4pQoiu12sOcp7Ak+r1el4olUrZVqtFB4MBCYKAsKQ4LhNOJhOOMAwpCFNd16llWZQ5u0JYKZez7R9tqmkaWSwWXLDdblPf9y+IQYjOZjP+zmbNiGE8seg1wkolq6oqUyTQCm+ZgTmNW2NtMmeO41DTNJmry11cJazVatkQ1FarFQFVEs+LibAwDIP2+31OysihC04ef/8h+0tYB0K8hoPCG7xZRxgEMTjDrucxG7CLMRRiaBnD7DDMDbuui0Gc57EcVsOMcsLjWi1no5Ba84D64fKfd208HtPhcLj13jabzVfCl2+FZx/KheC98hlVT3rIHo0QFCHbcdDHRgv9HJho5vsIHCM4DASHxdcY3vn+HOYbKoqSE55kpJv7zx/tvXmafPA2nxN3k0kxlUqJD9Np8cbtu+K93fviY0kS05mMmAGkYT+z5V2SpL1EInHrN3O9OriZ7i7gAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Loops called “typed” for “EnteringTheName” nodes&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_main_with_extra_typed_arrow-90666feeedbb6a81cbeb45d47993adcc-86d16.png&quot;
        srcset=&quot;/static/editor_main_with_extra_typed_arrow-90666feeedbb6a81cbeb45d47993adcc-bd9cb.png 300w,
/static/editor_main_with_extra_typed_arrow-90666feeedbb6a81cbeb45d47993adcc-fe5c6.png 600w,
/static/editor_main_with_extra_typed_arrow-90666feeedbb6a81cbeb45d47993adcc-86d16.png 1200w,
/static/editor_main_with_extra_typed_arrow-90666feeedbb6a81cbeb45d47993adcc-92b91.png 1800w,
/static/editor_main_with_extra_typed_arrow-90666feeedbb6a81cbeb45d47993adcc-c030b.png 2400w,
/static/editor_main_with_extra_typed_arrow-90666feeedbb6a81cbeb45d47993adcc-57f14.png 2784w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Now we can register an event listener that will call a model method meant to do a transition and set the new value of the name.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/EnteringTheName.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  typeName&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;typed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ctx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  finishEnteringTheName&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;done&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  render&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;thisModel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;Please&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; enter your name&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
      type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;text&quot;&lt;/span&gt;
      value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      onChange&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;e &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;typeName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;target&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
      type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;button&quot;&lt;/span&gt;
      value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Done&quot;&lt;/span&gt;
      onClick&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;finishEnteringTheName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The most common mistake I make writing handlers like this is to replace the whole context instead of updating just one field. Let&apos;s take a look at its test case.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/EnteringTheName.test.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; EnteringTheName &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./EnteringTheName&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;shallow&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;enzyme&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; sinon &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sinon&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;EnteringTheName&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; initCtx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Joh&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; another&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; wrapper&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;beforeEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    thisModel &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    wrapper &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;shallow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;EnteringTheName&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;thisModel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; initCtx&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;updates the name when .typeName is called&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;EnteringTheName&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;typeName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; initCtx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;John&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;typed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      ctx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;John&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; another&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you were wondering what&apos;s the point of the &lt;em&gt;{another: 123}&lt;/em&gt; part of the context, this is the answer - to make sure it&apos;s not accidentally removed. This handler is meant to update the &lt;em&gt;name&lt;/em&gt; property. It shouldn&apos;t touch other properties.
There&apos;s one more thing about the &lt;em&gt;EnteringTheName&lt;/em&gt; node I&apos;d like to mention about. Let&apos;s have a look at the main graph one more time.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/bunny_app-9dacc6411fa1e148984dbc2677fffb7b-b3be4.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1000px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 64.3%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAEDBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAey0FUf/xAAYEAEAAwEAAAAAAAAAAAAAAAABABARMf/aAAgBAQABBQJnAdE2ZX//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAYEAACAwAAAAAAAAAAAAAAAAAAIQERIP/aAAgBAQAGPwJlws//xAAcEAEAAgMAAwAAAAAAAAAAAAABACExQVERcYH/2gAIAQEAAT8hflSn2OxZplxOpPUytU5KME//2gAMAwEAAgADAAAAELAP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGxABAAMBAQEBAAAAAAAAAAAAAQARITFRQWH/2gAIAQEAAT8Q1iDABv7DeILY2J32UCEfsJCN9XZtKgq3IGIB3Cf/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A whiteboard drawing of the most important screens&quot;
        title=&quot;&quot;
        src=&quot;/static/bunny_app-9dacc6411fa1e148984dbc2677fffb7b-b3be4.jpg&quot;
        srcset=&quot;/static/bunny_app-9dacc6411fa1e148984dbc2677fffb7b-27d6e.jpg 300w,
/static/bunny_app-9dacc6411fa1e148984dbc2677fffb7b-5d038.jpg 600w,
/static/bunny_app-9dacc6411fa1e148984dbc2677fffb7b-b3be4.jpg 1000w&quot;
        sizes=&quot;(max-width: 1000px) 100vw, 1000px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;As we can see, when the name is entered, the user lands on either the &lt;em&gt;FeedingTheBunny&lt;/em&gt; screen or the &lt;em&gt;Thanks&lt;/em&gt; screen. What&apos;s cool is that the code responsible for handling the &lt;em&gt;Done&lt;/em&gt; button always does the same - it makes the model follow an arrow called &lt;em&gt;done&lt;/em&gt;. There is no IF for that. It&apos;s not parametrized using a boolean flag neither. It&apos;s all about where is the arrow pointing at.&lt;/p&gt;
&lt;p&gt;We&apos;re getting closer to the most complicated part which is the &lt;em&gt;FeedingTheBunny&lt;/em&gt; node and its children. The node itself is a composite of two nodes: &lt;em&gt;TheBunny&lt;/em&gt; and &lt;em&gt;CarrotControls&lt;/em&gt;. Both of those nodes handle the &lt;em&gt;render&lt;/em&gt; method in their own ways. In order to make the composite render correctly, we need to make its &lt;em&gt;render&lt;/em&gt; method return a merged result of the &lt;em&gt;render&lt;/em&gt; method of &lt;em&gt;TheBunny&lt;/em&gt; and the &lt;em&gt;render&lt;/em&gt; method of &lt;em&gt;CarrotControls&lt;/em&gt;. This is how we can use &lt;a href=&quot;https://rosmaro.js.org/doc/#handlers-altering-results&quot;&gt;altering results&lt;/a&gt; to achieve this.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/FeedingTheBunny.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  afterRender&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;TheBunny&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;hr&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CarrotControls&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/all.js&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ... previously imported handlers&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; FeedingTheBunny &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./FeedingTheBunny&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ... previously exported handlers&lt;/span&gt;
  FeedingTheBunny&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is its test case.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/FeedingTheBunny.test.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; FeedingTheBunny &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./FeedingTheBunny&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;shallow&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;enzyme&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; sinon &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;sinon&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;FeedingTheBunny&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;renders the bunny and carrot controls&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; wrapper &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;shallow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;FeedingTheBunny&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;afterRender&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      res&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        TheBunny&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span id&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;the-bunny&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        CarrotControls&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span id&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;carrot-controls&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;wrapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;#the-bunny&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;wrapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;#carrot-controls&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We&apos;re going to start from the &lt;em&gt;CarrotControls&lt;/em&gt; graph. What makes it special is that it calls model methods which are handled by two handlers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the controls themselves (when we give a carrot away, we don&apos;t have it anymore)&lt;/li&gt;
&lt;li&gt;the bunny (when the bunny is given a carrot, it&apos;s not hungry anymore)
First, let&apos;s do the controls.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/LookingForACarrot.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  lookForACarrot&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;found a carrot&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  render&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;thisModel&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;You don not have a carrot to give to your bunny&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
      type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;button&quot;&lt;/span&gt;
      value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Look for a carrot&quot;&lt;/span&gt;
      onClick&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lookForACarrot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/GivingTheCarrot.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  giveTheCarrot&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;gave the carrot&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  render&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;thisModel&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;You have a carrot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; You can give it to your bunny&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
      type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;button&quot;&lt;/span&gt;
      value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Give the carrot&quot;&lt;/span&gt;
      onClick&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;giveTheCarrot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/all.js&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ... previously imported handlers&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; LookingForACarrot &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./LookingForACarrot&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; GivingTheCarrot &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./GivingTheCarrot&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ... previously exported handlers&lt;/span&gt;
  LookingForACarrot&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  GivingTheCarrot&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These buttons simply change between &lt;em&gt;Look for a carrot&lt;/em&gt; and &lt;em&gt;Give the carrot&lt;/em&gt;. They do it by calling model methods like &lt;em&gt;giveTheCarrot&lt;/em&gt;. And I must tell you a secret - &lt;em&gt;TheBunny&lt;/em&gt; is especially interested in getting a carrot. &lt;/p&gt;
&lt;p&gt;To make &lt;em&gt;TheBunny&lt;/em&gt; children a bit simpler, we&apos;re going to give them just a slice of the whole context. The whole context looks like this.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Łukasz&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bunny&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ateCarrots&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But we want &lt;em&gt;TheBunny&lt;/em&gt; and its children to see just this.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  ateCarrots&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It turns out to be very easy with &lt;a href=&quot;https://rosmaro.js.org/doc/#handlers-context-slices&quot;&gt;context slices&lt;/a&gt;. All we need to do is to write a simple handler for &lt;em&gt;TheBunny&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/TheBunny.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  ctxSlice&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;bunny&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/all.js&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ... previously imported handlers&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; TheBunny &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./TheBunny&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ... previously exported handlers&lt;/span&gt;
  TheBunny&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can create &lt;em&gt;AHungryBunny&lt;/em&gt;. It will handle the same method call which makes the controls change from &lt;em&gt;GiveTheCarrot&lt;/em&gt; to &lt;em&gt;LookingForACarrot&lt;/em&gt;, that is &lt;em&gt;giveTheCarrot&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/AHungryBunny.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  giveTheCarrot&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ate a carrot&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ctx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      ateCarrots&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  render&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;img&quot;&lt;/span&gt; aria&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;label&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;A hungry bunny&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;🐰&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; 
    This is a hungry bunny&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/all.js&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ... previously imported handlers&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; AHungryBunny &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./AHungryBunny&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ... previously exported handlers&lt;/span&gt;
  AHungryBunny&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Every time we call the &lt;em&gt;giveTheCarrot&lt;/em&gt; method, the node called &lt;em&gt;GivingTheCarrot&lt;/em&gt; follows the arrow called &lt;em&gt;gave the carrot&lt;/em&gt; and the node called &lt;em&gt;AHungryBunny&lt;/em&gt; follows the arrow called &lt;em&gt;ate a carrot&lt;/em&gt; (and sets the number of ate carrots to 1).&lt;/p&gt;
&lt;p&gt;When &lt;em&gt;AHungryBunny&lt;/em&gt; eats a carrot it becomes &lt;em&gt;AnEatingBunny&lt;/em&gt;. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/AnEatingBunny.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  giveTheCarrot&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ateCarrots &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ateCarrots &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; arrow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ateCarrots &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; 
      &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ate 5 carrots&apos;&lt;/span&gt; 
      &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ate a carrot&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      arrow&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      ctx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        ateCarrots
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  render&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;img&quot;&lt;/span&gt; aria&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;label&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;A bunny&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;🐰&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;img&quot;&lt;/span&gt; aria&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;label&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;A carrot&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;🥕&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    This is an eating bunny&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/all.js&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ... previously imported handlers&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; AnEatingBunny &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./AnEatingBunny&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ... previously exported handlers&lt;/span&gt;
  AnEatingBunny&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Every time it&apos;s given a carrot, it increments the number of ate carrots by 1 (what&apos;s actually done by returning a new version of the context, very much like in &lt;a href=&quot;https://redux.js.org&quot;&gt;Redux&lt;/a&gt;). What makes it different than any other handler we implemented is that it picks the arrow to follow based upon the context of the model. If the bunny has eaten at least 5 carrots, it follows the &lt;em&gt;ate 5 carrots&lt;/em&gt; arrow. However, if the bunny ate less than 5 carrots, it just updates the number of ate carrots. It accomplishes this by following a different arrow called &lt;em&gt;ate a carrot&lt;/em&gt;. It is very much like the &lt;em&gt;EnteringTheName&lt;/em&gt; node which follows the &lt;em&gt;typed&lt;/em&gt; arrow in order to update the context. That&apos;s why we need to add this arrow to the graph.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_the_bunny_with_extra_ate_a_carrot_arrow-b3a83ebe4769a8a1d28b1ac47bbf0d14-57f14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.560344827586206%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAACPElEQVQoz5VRz28SURDei0f9CzwY04M3xLLFAF5MhJQmHL176D/D+n94x2gPTQukbPkZWIwmAoVdKCyw/Ia3LCzse868alMkHpzky8x7M+9738wIxfjF83JRlqq1G6mpNqMASa2rkklMiRAiGX1Dampw11ClgTGQDMOQ9I4uaQ0N69FH27ftqKZqH8++nB0IaVkOL03C1rbNHho8ZEDI/sey2WxEuLi8fFetVJ3hcGgvl0t7s9kgsx2LxWwo4LHjONyv12t7Pp/z+C+soYYWCoVjISXLwUq1xm7qdQqEdLvdMkop63a7Owrxfjabsel0ytrtNvdAgrUU0giWz+fDQjqTCX6vVFmn26Mb2+YJUMsURWGlksJjNFDO4EMe2zAevL/jYruEqdRV8Fu5zGDolJgmxYd/bLVascFgwHRdZ6qqco95VDsej7nCPcLraznYaKhM0zQKLfKW0X4Xc8PWYZ6guMTbxbNlWTy313IulwtaoAQGThEPidBwlqhssVjsbRW59gjzQOjgYoEJvAMKMXJarZajlMsOkPEzik4kEk4ymXTuGoC1UsqBZ+TlhNlcPtQnJtMXJptYq/vfUZFFdlXhohD/smKxeCJ8PT9/G8sWlp+u0iTzs0aMXo/0+30ymU7JZ+UHqdx2yBzi4WhEYCQcI4hhKfeYTCYL2LoVj8dDwmvR8/hD5MRzGgmL749DovvwUPR6vaJ4dCQ+evpMfPHylfgmEBB9fr/odrs5/BD7fL4dBAIBj8vlevIL83E3C3P5x00AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;TheBunny and &quot;ate a carrot&quot; arrow&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_the_bunny_with_extra_ate_a_carrot_arrow-b3a83ebe4769a8a1d28b1ac47bbf0d14-86d16.png&quot;
        srcset=&quot;/static/editor_the_bunny_with_extra_ate_a_carrot_arrow-b3a83ebe4769a8a1d28b1ac47bbf0d14-bd9cb.png 300w,
/static/editor_the_bunny_with_extra_ate_a_carrot_arrow-b3a83ebe4769a8a1d28b1ac47bbf0d14-fe5c6.png 600w,
/static/editor_the_bunny_with_extra_ate_a_carrot_arrow-b3a83ebe4769a8a1d28b1ac47bbf0d14-86d16.png 1200w,
/static/editor_the_bunny_with_extra_ate_a_carrot_arrow-b3a83ebe4769a8a1d28b1ac47bbf0d14-92b91.png 1800w,
/static/editor_the_bunny_with_extra_ate_a_carrot_arrow-b3a83ebe4769a8a1d28b1ac47bbf0d14-c030b.png 2400w,
/static/editor_the_bunny_with_extra_ate_a_carrot_arrow-b3a83ebe4769a8a1d28b1ac47bbf0d14-57f14.png 2784w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Finally, &lt;em&gt;AFullBunny&lt;/em&gt; is happy and allows us to go back to what we were doing.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/AFullBunny.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  go&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;fed the bunny&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  render&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;thisModel&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;img&quot;&lt;/span&gt; aria&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;label&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;A full bunny&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;🐰&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; 
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;img&quot;&lt;/span&gt; aria&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;label&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Fireworks&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;🎆&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      The bunny is full&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; You can go&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
      type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;button&quot;&lt;/span&gt;
      value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Go!&quot;&lt;/span&gt;
      onClick&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/all.js&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ... previously imported handlers&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; AFullBunny &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./AFullBunny&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ... previously exported handlers&lt;/span&gt;
  AFullBunny&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The last screen is called &lt;em&gt;Thanks&lt;/em&gt; and it simply says &quot;thank you&quot; and lets us to start the whole process one more time.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/Thanks.js&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  repeat&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;repeated&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  render&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;Thanks&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
      type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;button&quot;&lt;/span&gt;
      value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;One more time!&quot;&lt;/span&gt;
      onClick&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; thisModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/handlers/all.js&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ... previously imported handlers&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Thanks &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./Thanks&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ... previously exported handlers&lt;/span&gt;
  Thanks&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The application is almost ready. The missing functionality is about &lt;em&gt;TheBunny&lt;/em&gt; being hungry every time we see it, while the state of &lt;em&gt;CarrotControls&lt;/em&gt; should never change without user interaction. It means that if we leave the bunny full and we have a carrot (let&apos;s imagine we&apos;re carrying it in a bag), then the bunny is hungry when we meet it again but we don&apos;t need to look for another carrot because we already have one (the one we found previously).
Implementing this feature is actually quite easy and can be done just by editing the graph. First, let&apos;s use a special entry point to &lt;em&gt;FeedingTheBunny&lt;/em&gt;. We&apos;re going to call it &lt;em&gt;feeding&lt;/em&gt;. All we need to do is to open the &lt;em&gt;main&lt;/em&gt; graph, click the &lt;em&gt;fed the bunny&lt;/em&gt; arrow and change its entry point from &lt;em&gt;start&lt;/em&gt; to &lt;em&gt;feeding&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_main_with_feeding_entry_point-8caf71392708033296073181dc981154-57f14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.560344827586206%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAACQElEQVQoz41Sz28SQRTeqwf9B7w0ph5MNETT0UDwYgJFmpJ49OjNv6Xrf+LBeDAcbEKEUoFFCG0MBcr+YmVp+ZndYYGFmfHNIJvGEuNLvszM2/d9+715I1Uyxw9qP/Jyo9WSDU0/0jVd5ujZPbl/3RdQ26qsqZo86A/kXq8nd391ZdMwRZ2u6kdWx+K8D+kv6V2pcHqa9Lwp832f/W8QQrbmi8ViSsp8y8ZaqkZGo5E/n899KObKARzH8Wu1mtgvl0t/NpuJGsd1b9YtIEfL5fJrKZfNxuv1Oms2m9R1XbparQIXQGae57Futyty7fYlu6g3GMZYdEQp5aDwiYMpipKUcrlcHBww0zQpkCm4EGROqFarggTO2WQyYfxnbaPBGpd1RonQuC2YPzmJn5+dM03T6XQ6DQRhz3RdZ8PhkEHbbLFYiJxpmUw3dOF8u2A+H1dVlZMptBK0zMmdTofZti2c8ZWfb8bWlkulUnwGLYEDysHvbl2zDu5sc2fc1ea8mfQtQQUEydIXUyDLJQE3vIYLkxVZB7RMxuMxfwkERAkIEhggVyS89M+6FiyUlP0rDJN0MBt783++P8uy+PCCof0dlUrlQEp/PX71uVD2Pn5XcKnZxrZt4ab+E1/1r/Gncg1fmBZ2JhMM7jDcNYYnhg3DwIPBQOQ4wL0L51kmk9mXwgjdfXeY3Hv/5hC9PUiix6EnaOfhfYRePEd3dnbRo6fP0MtoFIXDYZRIJFAqlUKxWAxFIReJRALAeS8UCt37DVxqOcShXS0TAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Renaming the entry point to &quot;feeding&quot;&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_main_with_feeding_entry_point-8caf71392708033296073181dc981154-86d16.png&quot;
        srcset=&quot;/static/editor_main_with_feeding_entry_point-8caf71392708033296073181dc981154-bd9cb.png 300w,
/static/editor_main_with_feeding_entry_point-8caf71392708033296073181dc981154-fe5c6.png 600w,
/static/editor_main_with_feeding_entry_point-8caf71392708033296073181dc981154-86d16.png 1200w,
/static/editor_main_with_feeding_entry_point-8caf71392708033296073181dc981154-92b91.png 1800w,
/static/editor_main_with_feeding_entry_point-8caf71392708033296073181dc981154-c030b.png 2400w,
/static/editor_main_with_feeding_entry_point-8caf71392708033296073181dc981154-57f14.png 2784w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Since now, every subgraph of the &lt;em&gt;FeedingTheBunny&lt;/em&gt; must have an entry point called &lt;em&gt;feeding&lt;/em&gt;. So let&apos;s start with &lt;em&gt;TheBunny&lt;/em&gt;, which is always hungry when it comes to feeding it.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open &lt;em&gt;TheBunny&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;em&gt;NEW ENTRY POINT&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Type &lt;em&gt;feeding&lt;/em&gt; as its name&lt;/li&gt;
&lt;li&gt;Click &lt;em&gt;ADD&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Draw an arrow from the newly created &lt;em&gt;feeding&lt;/em&gt; entry point to &lt;em&gt;AHungryBunny&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_the_bunny_with_feeding_entry_point-d5da96a38038c5eed5391005d77d99fa-57f14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.560344827586206%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAACDUlEQVQoz52SbWvaUBTH8wW2DzH2XkZ1gvXVYJa1UAb7Bnu3r2L2AfYlRseglA1qxBlbHwha5oukbRKdWjMfInqjJnrv2TlxZnZ7tR74Q/ifm995uFfSlPMnDU2VjesbuWW1si27JbtjV3b6TqjBz4Fs27ZsmVb4Tep1e3Q2lG3a2c6PTta27Pdnp2dPpQtVPZx7DHw/gG202214SJTL5WPpPJd7aegGHw6HwWKxCJbLZVAoFILpdBqQxxgLKPB8JM55MJlMQq1WK/J89EStVnslFVU1oxvXcHN7K+bzucCAk08n0GjUAUcDXdfBNE2YzWaw4QJg0fCbPMdxBMHIr1arh9LF5WXmu25A9+5OYDUhMGe1TDA6V9EoVMR1XcCOYTAYQK/XA8/zwhxCBcL/AIvFb5mrRgNw6YJ5jKARaOwOQckpsF6vI280GkG9Xo+6pqmoZgQsldSMaVqANylwX4J+5oJvqk9nkM/nYVsEdwz9fp8gu3dxH1ipVDIL3Inv+4KE+4jG3A2CUncEo9yO7gOrCOR0UUhaBQHHDrmgTQpibwJhvNlscsuyqFqU3+q3twGWK9UDh3nQnTJgO2/xIaFp2pF0+uXri8/l2vxjRWMflBLDsZg7HrPxX8Jb/sfbyc3wBSwURTmQknt7j94eH8XfvXmdePY8mYgnk4n0/n4ilUr9l9LpdDwWiz3+BTHAONa/LgeMAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;&quot;feeding&quot; entry point to TheBunny&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_the_bunny_with_feeding_entry_point-d5da96a38038c5eed5391005d77d99fa-86d16.png&quot;
        srcset=&quot;/static/editor_the_bunny_with_feeding_entry_point-d5da96a38038c5eed5391005d77d99fa-bd9cb.png 300w,
/static/editor_the_bunny_with_feeding_entry_point-d5da96a38038c5eed5391005d77d99fa-fe5c6.png 600w,
/static/editor_the_bunny_with_feeding_entry_point-d5da96a38038c5eed5391005d77d99fa-86d16.png 1200w,
/static/editor_the_bunny_with_feeding_entry_point-d5da96a38038c5eed5391005d77d99fa-92b91.png 1800w,
/static/editor_the_bunny_with_feeding_entry_point-d5da96a38038c5eed5391005d77d99fa-c030b.png 2400w,
/static/editor_the_bunny_with_feeding_entry_point-d5da96a38038c5eed5391005d77d99fa-57f14.png 2784w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;In order to make the &lt;em&gt;CarrotControls&lt;/em&gt; remember the recently active node, we&apos;re going to make use of the &lt;em&gt;special recent node&lt;/em&gt;. It symbolizes the node which was active before the graph has been left, or if it has never been active, then it&apos;s the node the arrow from the &lt;em&gt;start&lt;/em&gt; entry point is pointing at. Long story short - we need to add the &lt;em&gt;feeding&lt;/em&gt; entry point and connect it with the &lt;em&gt;special recent node&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/editor_carrot_controls_with_feeding_entry_point-59f2fcee32b623f31289881a07b187e7-57f14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.560344827586206%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAACGklEQVQoz6VS3YrTUBDOC+hDiPdFtrXQ7ZVgF3dhEXwD77xUvHHxCRofYNG73oiCN8KyKNiC/VmaltBCf+jPJie1NTZtE9ucpk3anHFOapGyeLHswMfJycx8M/PNEeTMtztVOS+2O11RU7UkQiQKEfWfujgyRgE0oonKpSIahhHcuY/H/I1N9n/0k0Qlb87Pzu8KF/n8oTOn4Hoe3NSKxeKxkE6nH7bbHX8ymXiO43iMMY+b4yx4hV0wuPpvA9f3fVYulx8J2Ww20Ww2AUnZbDZjvNLbd6fw4uVzGJsGGOMh9PoETl6/gg8f3+90hCSADfCcIK9UKh0i4fdEtVIBTdMYdshWKw8sOoLRVIeJPQSTGmDi2VLroPY78NuywEJg8S3vLiHOnWheKtDTfzHPdQNHT+tBtVINot2lC+bEAmrPAZcBhBBARaDRaICqqmCaJluv1/8ICxeFhEo0IFqP2bYdOFAGSKVSsFgsYDjE7lot6Ha7kMvl+CRBoXq9DrVaDRRFYcvlMsiTJGnTIU90sTsOrPbfLU6nUxgMBsHIuq4HGl4ZuSRJCR91496V5/lI6HPjJ+rtb41/b+9b3xZ8P3w3Gw2l0sGQzmEwo0Ddm71FWZaPhLMvXx98LpadT5JMTzMFiu+RWqZJzWsAJbDH4/Eik8kcCNG9vVtPj4/Cz548jty7H42Eo9FIfH8/EovFroV4PB4OhUK3/wBuSTLhjfN2RAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;&quot;feeding&quot; entry point to CarrotControls&quot;
        title=&quot;&quot;
        src=&quot;/static/editor_carrot_controls_with_feeding_entry_point-59f2fcee32b623f31289881a07b187e7-86d16.png&quot;
        srcset=&quot;/static/editor_carrot_controls_with_feeding_entry_point-59f2fcee32b623f31289881a07b187e7-bd9cb.png 300w,
/static/editor_carrot_controls_with_feeding_entry_point-59f2fcee32b623f31289881a07b187e7-fe5c6.png 600w,
/static/editor_carrot_controls_with_feeding_entry_point-59f2fcee32b623f31289881a07b187e7-86d16.png 1200w,
/static/editor_carrot_controls_with_feeding_entry_point-59f2fcee32b623f31289881a07b187e7-92b91.png 1800w,
/static/editor_carrot_controls_with_feeding_entry_point-59f2fcee32b623f31289881a07b187e7-c030b.png 2400w,
/static/editor_carrot_controls_with_feeding_entry_point-59f2fcee32b623f31289881a07b187e7-57f14.png 2784w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;And that&apos;s pretty much it! The application works as expected and consists of &lt;strong&gt;just one IF statement&lt;/strong&gt;. What&apos;s worth noticing, this &lt;strong&gt;IF statement is not mandatory&lt;/strong&gt;. It could be totally removed, what would make the codebase free of any IF statements, if the whole memory of the &lt;em&gt;Rosmaro model&lt;/em&gt; was expressed using graph nodes. However, it would lead to a phenomenon called &lt;a href=&quot;https://en.wikipedia.org/wiki/UML_state_machine#UML_extensions_to_the_traditional_FSM_formalism&quot;&gt;state explosion&lt;/a&gt;. This single IF statement turns out to be surprisingly helpful! It&apos;s one of the the tools which allow us to mitigate the risk of ending up with an enormous number of nodes and arrows, together with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;composites (orthogonal regions)&lt;/li&gt;
&lt;li&gt;subgraphs (state machines in state machines)&lt;/li&gt;
&lt;li&gt;context (a piece of data usually in the form of a map structure)
Depending on our needs, we can balance the number of nodes and IFs. There may be just one node and many IFs, or many nodes and no IFs at all.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The full source code of the application we&apos;ve just built is available on GitHub - &lt;a href=&quot;https://github.com/lukaszmakuch/Rosmaro-React-example-Bunny-App&quot;&gt;Rosmaro-React-example-Bunny-App&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;Modifications worth trying out&lt;/h1&gt;
&lt;p&gt;Here are few modifications which I think are worth trying out. It doesn&apos;t mean that they represent a better approach. They&apos;re simply interesting exercises:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;removing all IF statements from method handlers (hint: it will increase the number of graph nodes)&lt;/li&gt;
&lt;li&gt;making the &lt;em&gt;typed&lt;/em&gt; arrow disappear from the &lt;em&gt;main&lt;/em&gt; graph (hint: a new subgraph will be necessary)&lt;/li&gt;
&lt;li&gt;adding a &lt;em&gt;back&lt;/em&gt; button from &lt;em&gt;Thanks&lt;/em&gt; (hint: depending on the destination screen, new nodes may be necessary)&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;Does it scale?&lt;/h1&gt;
&lt;p&gt;I often hear, that finite state-machines don&apos;t scale. I totally agree on that, when it comes to simple, pure FSM-based solutions. When the graph is the only memory and when every single event needs to be explicitly represented by its own arrow, even trivial tasks may lead to an enormous number of nodes and arrows. &lt;/p&gt;
&lt;p&gt;A great example to illustrate this problem is a &lt;em&gt;Hello YourName!&lt;/em&gt; application, which has one screen with a text input and a button and another screen to display greetings. Even if we limit the length of the name to 2 characters and allow only two letters: &lt;em&gt;a&lt;/em&gt; and &lt;em&gt;b&lt;/em&gt;, the graph will still look like this.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/state_explosion-ac3e5e1ccbb66ced19e19f4a4ec135f2-11fa0.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 961px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 46.514047866805406%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA+UlEQVQoz42S6Q6EIAyEff+nNNFovPC+D9avmxI0+2ObNNAyTKeF4Louq8b+V/wvBg9IhmFo27Z1oOM4xH2bpsn2ff/A7Pv+wDjCZVnsuq72PE85MMYIAQAlruvaZlnmcsR5nrviTiFEXdfZcRztcCuAKIoiW1bVNzcMkoMsSRI7z7MUj+NYnD3dpWkqhQMuAVSV27bZ6iYrikJi8igwdw5ScnRQlqWMgHMKQgouQAEA3wAaUz9mxDj0MSBpmkZWPUOhEAJSsDpEzEcJlUhXOkCh/8p05h7l/R2oHN9zBPTr+4zjIGPyi6gF73+E0Q4P9b7gK2X2fqz+AfRpwLILFXNVAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;An example of the phenomenon called state explosion&quot;
        title=&quot;&quot;
        src=&quot;/static/state_explosion-ac3e5e1ccbb66ced19e19f4a4ec135f2-9fc54.png&quot;
        srcset=&quot;/static/state_explosion-ac3e5e1ccbb66ced19e19f4a4ec135f2-f7658.png 300w,
/static/state_explosion-ac3e5e1ccbb66ced19e19f4a4ec135f2-7fe6d.png 600w,
/static/state_explosion-ac3e5e1ccbb66ced19e19f4a4ec135f2-9fc54.png 1200w,
/static/state_explosion-ac3e5e1ccbb66ced19e19f4a4ec135f2-8c381.png 1800w,
/static/state_explosion-ac3e5e1ccbb66ced19e19f4a4ec135f2-11fa0.png 1922w&quot;
        sizes=&quot;(max-width: 961px) 100vw, 961px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    .&lt;/p&gt;
&lt;p&gt;This doesn&apos;t look good. &lt;/p&gt;
&lt;p&gt;However, there&apos;s no reason why we need to limit ourselves to just one-level graphs or even graphs at all. Thanks to the fact that Rosmaro is not a pure FSM-based solution, we can use some of the techniques described above to make the graph look exactly how we want it to look. We could even reduce the number of nodes to exactly one by replacing other nodes with IFs. Of course, it wouldn&apos;t make to much sense to use Rosmaro if we needed just one node. It simply illustrates the possibility of balancing between nodes and IFs in order to achieve a structure that represents the intended behavior of the application in a clear, documentation-like manner. &lt;/p&gt;
&lt;p&gt;Here&apos;s the &lt;em&gt;Hello YourName!&lt;/em&gt; application modeled using method handlers, context and subgraphs.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/greetings_with_no_state_explosion-bc57cd8aa2a853368b5e04bd65bd26ba-d2cd6.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 838px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 19.09307875894988%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAoElEQVQY061OQQqDMBDM1/xFvudfGnvwlnoxeBEkVhvSkxoTdeouWOi9A8PCzCwzAn+GsNYipYRt27AsC5xzGMcRwzDAe48YI3uUWdeVMxfneWb/OA7Oki+klOi6Du9TqOsa96KA1hrVo+L77Hu4l+MiYwyUUijLkqluCm3bsp5lGfI8h+jPBwK1EGjJxX3ffzxCCIGXEadp+i5vmoZXfgCklC3haoCctgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The main graph of the Hello YourName! application&quot;
        title=&quot;&quot;
        src=&quot;/static/greetings_with_no_state_explosion-bc57cd8aa2a853368b5e04bd65bd26ba-08844.png&quot;
        srcset=&quot;/static/greetings_with_no_state_explosion-bc57cd8aa2a853368b5e04bd65bd26ba-86ca2.png 300w,
/static/greetings_with_no_state_explosion-bc57cd8aa2a853368b5e04bd65bd26ba-fc2dc.png 600w,
/static/greetings_with_no_state_explosion-bc57cd8aa2a853368b5e04bd65bd26ba-08844.png 1200w,
/static/greetings_with_no_state_explosion-bc57cd8aa2a853368b5e04bd65bd26ba-d2cd6.png 1676w&quot;
        sizes=&quot;(max-width: 838px) 100vw, 838px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/user_name_view-8bbc2418c05e5a4da550c9f2e2a1af38-d9a2d.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 450px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68.88888888888889%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABYlAAAWJQFJUiTwAAABbElEQVQ4y5VTS27CMBTMcdhzBq7DhVDZs0ORWIKAEzSrEpGGX/hFCr+k4c9U8yQHY1IpHcnKk2OPZ+bZFgrg8XjIyKtNWP8l0+fN/4UITYLz+Yz7/f5Clg2T8C9bqt5sNphMJgiCAPv9Pu/YJ6FOcLvdcL1eRYmaP51O8H1f6jiO4bouptMpLpcLjscj0p8UXJqrUIeyF4ahqOKaweALo9EInufB+XSwXC7hf/uvGepKms0m6vUPUaCg1JhYr9eIoijjsFRBi8R4PEalUkGpVEKj0cg2MjceZjaDYBRslijMuwq0QDvqEIIWlUKu0/M9HA6yJ7NMyQw5D1RF4n6/j91u92Y7TVPpfJIkT8JqtYpyuQzbtrHdboV8OPTQ7XbRarWErNPpyLfdbsNxHCwWC8xmMxns+kuGvV4PtVoNq9VKrPAaUBkVMdP5fC4Z8ksCdptKdbXKfuGXUvRpWuqu8TKbr0OFbw7zyekKfwHQ9jZY87cBGwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The subgraph of the Hello YourName! application&quot;
        title=&quot;&quot;
        src=&quot;/static/user_name_view-8bbc2418c05e5a4da550c9f2e2a1af38-d9a2d.png&quot;
        srcset=&quot;/static/user_name_view-8bbc2418c05e5a4da550c9f2e2a1af38-5d6b3.png 300w,
/static/user_name_view-8bbc2418c05e5a4da550c9f2e2a1af38-891d4.png 600w,
/static/user_name_view-8bbc2418c05e5a4da550c9f2e2a1af38-d9a2d.png 900w&quot;
        sizes=&quot;(max-width: 450px) 100vw, 450px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;It doesn&apos;t look so scary, does it?&lt;/p&gt;
&lt;p&gt;And when it comes to a bit more complex examples, here&apos;s an application with &lt;strong&gt;13 different screens which depend on each other&lt;/strong&gt; and &lt;strong&gt;many paths&lt;/strong&gt; the user may take.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/complex_app-58eff6c607ac0859b55b5387883ba39d.gif&quot; alt=&quot;A more complex example&quot;&gt;&lt;/p&gt;
&lt;p&gt;In the code, there are &lt;strong&gt;3 IF statements&lt;/strong&gt;. The graph consists of &lt;strong&gt;29 nodes&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;main&lt;/em&gt; node opened in the editor looks like this.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/complex_app_graph-fd4a2d9e2623f1ed85beccff2229cce1-2f7cc.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 805px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68.44720496894409%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABYlAAAWJQFJUiTwAAABeElEQVQ4y41Ty46CQBDkX/0Gb/yF+wtePHv1tkYjBlkOXgz45BHUYDQiKlhrdTIGXZTtpDMz0NPV3VWjocRut9tjLe6rjDHafxLmeS7n3W4Hz/Pg+z6CIBAPwxCr1Qr7/V5itE9oRdtsNhgOh7AsC4ZhoNfryfnnfh4MBgLyNqFKliSJoM9mM0ynU9mfTif5x+qu1+sfcEnIlrIse7SonBfO5zOWyyXSNMXlcpFLXFlx6Qyrhk0wzk7Z4XDAYrFAFEVPc1Z5pELbttHpdKQatsRWt9utEOA4Dsbj8X1GgVQ1mUywXq9xPB5LFSAJG40v1Go1xHEsl4g+Go3ECUYCut9duK4ro/lEnlalK0UO5VH8/uqlM1R6ezWSMJ/PpX0yznbfgWuvL4Js1ut16Lr+YJVtKqd0mJgKoDNGFfL0UlRCXmo2m2i1Wk+BNLJrmiba7Tb6/b7MmOImUaVPr0xCxeopH74IRRw9CEJRxNsKuar2igBVelX/fwGdETeDr38EVQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The main node of the complex example&quot;
        title=&quot;&quot;
        src=&quot;/static/complex_app_graph-fd4a2d9e2623f1ed85beccff2229cce1-19939.png&quot;
        srcset=&quot;/static/complex_app_graph-fd4a2d9e2623f1ed85beccff2229cce1-ae6aa.png 300w,
/static/complex_app_graph-fd4a2d9e2623f1ed85beccff2229cce1-370c7.png 600w,
/static/complex_app_graph-fd4a2d9e2623f1ed85beccff2229cce1-19939.png 1200w,
/static/complex_app_graph-fd4a2d9e2623f1ed85beccff2229cce1-2f7cc.png 1610w&quot;
        sizes=&quot;(max-width: 805px) 100vw, 805px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h1&gt;Conclusions&lt;/h1&gt;
&lt;p&gt;To me, visual automata-based programming turned out to be a really great discovery. For a long time, I considered state machines something almost purely theoretical. Or at least not directly applicable to the field I was working on.
But then I imagined the code structured like there would be islands of clearly defined behavior. These islands are handlers from Rosmaro. There are also bridges connecting these islands. They are arrows representing events. The current behavior of the system is changed by going from one island to another. It all clicked. Now I can design and implement changes of behavior in an elegant, organized way, where previously I would just scatter IF statements.&lt;/p&gt;
&lt;p&gt;I can also see how I benefited from automata-based programming in two different ways. It&apos;s not only easier to program by drawing boxes and arrows instead of inspecting boolean flags. It also makes it necessary to discover and name all the important states of the application, what&apos;s a great framework for thoughts.&lt;/p&gt;
&lt;p&gt;And when it comes to application state, it showed me that there&apos;s &lt;a href=&quot;/post/state-management-beyond-the-map&quot;&gt;state management beyond map structures&lt;/a&gt; (which are key-value pairs, like method-less JavaScript objects). A new tool appeared in my toolbox. It&apos;s the state machine based dispatch mechanism. Instead of just accepting the fact that I have some boolean values to check using IFs, I can consider replacing them with nodes. After playing a bit with this approach, I started noticing the difference between data-related state and behavior-related state. Data-related state is something like information about a user. It may be as simple as name and surname. Most of the time, we don&apos;t need to use IFs to deal with state like this. It&apos;s simply there. We can display or save it without conditional statements. A set of key-value pairs is a perfect model for state like this. On the other hand, behavior-related state determines how should the application work according to events which occurred in the past. Sometimes key-value pairs topped with a few IFs do the job very well, other times state machines feel a lot more natural and easy to understand.&lt;/p&gt;
&lt;p&gt;If you haven&apos;t tried yet, I hope you&apos;ll give state machines a go. Maybe you&apos;ll also find them valuable in your day to day job? &lt;/p&gt;</content:encoded></item><item><title><![CDATA[State management beyond the map]]></title><link>https://coder.earth/post/state-management-beyond-the-map</link><guid isPermaLink="false">https://coder.earth/post/state-management-beyond-the-map</guid><pubDate>Fri, 06 Oct 2017 22:37:20 GMT</pubDate><content:encoded>&lt;p&gt;There&apos;s a way of building web applications where views are declarative. They say what to render and not how exactly should it be done. Data flow is unidirectional, what means it just receives data but never changes it directly. Instead of that, it sends back commands describing what should be done. Then it&apos;s rendered again.
I used this stack to create a simple ToDo App.&lt;/p&gt;
&lt;p&gt;It looks like that.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/todo-f3c184a2259fdca72170379aec223410.gif&quot; alt=&quot;todo_app&quot;&gt;&lt;/p&gt;
&lt;p&gt;Here goes the code.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre class=&quot;language-php&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;require_once&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;__DIR__&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token double-quoted-string string&quot;&gt;&quot;/common.php&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$viewData&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$_SESSION&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;todos&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token variable&quot;&gt;$_SESSION&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;todos&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;add&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;newContent&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token variable&quot;&gt;$_SESSION&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;todos&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;done&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;content&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;newContent&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;mark_done&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;array_keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;mark_done&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$_SESSION&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;todos&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token variable&quot;&gt;$_SESSION&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;todos&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;done&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;htmlspecialchars&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$viewData&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;todos&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$_SESSION&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;todos&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;newContent&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;newContent&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;add&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;newContent&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token delimiter important&quot;&gt;?&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;POST&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$viewData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;todos&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$todo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token delimiter important&quot;&gt;?&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$todo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;done&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token delimiter important&quot;&gt;?&gt;&lt;/span&gt;&lt;/span&gt;
          &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$todo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;content&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token delimiter important&quot;&gt;?&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token delimiter important&quot;&gt;?&gt;&lt;/span&gt;&lt;/span&gt;
          &lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$todo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;content&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token delimiter important&quot;&gt;?&gt;&lt;/span&gt;&lt;/span&gt;
          &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;mark_done[&lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;int&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$id&lt;/span&gt; &lt;span class=&quot;token delimiter important&quot;&gt;?&gt;&lt;/span&gt;&lt;/span&gt;]&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Mark as done&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;endif&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token delimiter important&quot;&gt;?&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;endforeach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token delimiter important&quot;&gt;?&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;newContent&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$viewData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;newContent&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token delimiter important&quot;&gt;?&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;submit&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;add&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Add a ToDo&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hidden&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;_csrf&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token php language-php&quot;&gt;&lt;span class=&quot;token delimiter important&quot;&gt;&amp;lt;?=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;csrfToken&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token delimiter important&quot;&gt;?&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Yup. It&apos;s an old-fashioned, server side PHP script.&lt;/p&gt;
&lt;p&gt;Don&apos;t get me wrong, I fully admit that many things have changed since then. We’ve got wonderful auto-escaping mechanisms which greatly improved security (JSX was born as one of them). Protection against CSRF attacks has become a common thing (at least in mature back-end frameworks). And we have finally moved a vast part of user interfaces to the front-end (JS is not anymore a tool to embed dancing hamsters on a website). It all provides more beautiful and responsive user interfaces.&lt;/p&gt;
&lt;p&gt;But there&apos;s something that hasn&apos;t changed at all. It&apos;s the way how we manage changes of behavior. In the above example there&apos;s exactly one set of bahavior. There are always the same controls and they always to the same. The form is always there and it always adds a new ToDo. The list is also visible all the time and it just displays all the ToDos.&lt;/p&gt;
&lt;p&gt;But what if there are different screens? What if the user may take different paths? What if the app looks list this?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/wizard-2ae75be29166cb3be27ae2eb5cd852d5.gif&quot; alt=&quot;wizard&quot;&gt;&lt;/p&gt;
&lt;p&gt;The state of the art in web interfaces is to save some values within the state and then use conditional statements to pick the appropriate behavior. There may be some boolean values stating that the user has performed some actions, some integers (or enums) representing the current step etc. And then we use if statements (or ternary operators, switch statements or table lookup techniques) to decide what to do. The whole architecture may be summed up as spreading conditional statements over a map (or a session, a database, a dumb object - you name it). We may avoid duplication of if statements, but we can&apos;t avoid them completely even if we wanted to.&lt;/p&gt;
&lt;p&gt;Once I was asked if I could introduce &quot;few little changes&quot; to an app I was maintaining. When I realised what kind of variables would I need to check and how many complicated conditional statements would be necessary, it terrified me! It seemed barbaric!&lt;/p&gt;
&lt;p&gt;What&apos;s interesting is that the description of those changes wasn&apos;t so tangled. It consisted few scenarios like &quot;if the user does this, then she&apos;s finally going to land on this screen&quot; etc. It made me wonder why was it so hard to code it, if it was so easy to talk about. Soon I understood that the high level architecture I had was suitable only for simple screens which never change, but it by no means reflected the domain of the problem.&lt;/p&gt;
&lt;p&gt;Actually the &quot;non-technical people&quot;, as we like to call them, came to me with a much more suitable and elegant architecture. Even though they didn&apos;t use that exact word, what they described was one of the fundamental concepts in computer science - a state machine. It was me who didn&apos;t see that and instead tried to utilize maps and if statements. Such a shame!&lt;/p&gt;
&lt;p&gt;If I would be about to chose one experience, which made me willing to explore practical application of state machines in web development, it would be this one. Some time after that, I published the first version of &lt;a href=&quot;https://rosmaro.js.org/&quot;&gt;Rosmaro&lt;/a&gt;. I actually used it to create the second application presented in this post. You can find a detailed description of its architecture in the post describing &lt;a href=&quot;https://medium.com/dailyjs/state-machines-to-the-rescue-of-complex-forms-867b75790455&quot;&gt;how state machines come to the rescue of complex forms&lt;/a&gt;.
Oh, and let me share something with you. It made me really happy when I recently stumbled upon a great talk given by David Khourshid - &lt;a href=&quot;https://www.youtube.com/watch?v=VU1NKX6Qkxc&quot;&gt;Infinitely Better UIs with Finite Automata&lt;/a&gt;. If you&apos;re interested in how state machines may improve the architecture of user interfaces, definitively check it out. I bet you won&apos;t regret it!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[State machines to the rescue of API mocks]]></title><link>https://coder.earth/post/state-machines-to-the-rescue-of-api-mocks</link><guid isPermaLink="false">https://coder.earth/post/state-machines-to-the-rescue-of-api-mocks</guid><pubDate>Sat, 23 Sep 2017 22:37:20 GMT</pubDate><content:encoded>&lt;p&gt;Let me tell you the story of one of the most valuable test suites I have ever written.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/api-9f64e8f9d2dde1c2ef38e7c2aa2e5c58-ef898.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 101.73333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAQCAwX/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAH3scoi5QM8ApB//8QAHBAAAgICAwAAAAAAAAAAAAAAAQIAAxAREzEy/9oACAEBAAEFAtx/KK82Q11zqB0yhhwV4//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQMBAT8BH//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EABwQAAEEAwEAAAAAAAAAAAAAAAABAhEhEDFBMv/aAAgBAQAGPwI6LLu0WLpZxCja86x//8QAHRAAAgMAAgMAAAAAAAAAAAAAAREAITEQQWGBkf/aAAgBAQABPyEoVCIJfGyxUDQsEN+B9KoNg4CvCmDhEDQpcz9B4//aAAwDAQACAAMAAAAQMwc8/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAwEBPxAf/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAgEBPxAf/8QAHhABAQACAgIDAAAAAAAAAAAAAREAITFBUXEQYYH/2gAIAQEAAT8Qkyq8ZvSulmPV7wpQFOtIFvbF/cjCRV8zgG73Ll66T1OqvaTRreUoqwuXtFCcz3iqmfqB8p267+P/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;api&quot;
        title=&quot;&quot;
        src=&quot;/static/api-9f64e8f9d2dde1c2ef38e7c2aa2e5c58-19371.jpg&quot;
        srcset=&quot;/static/api-9f64e8f9d2dde1c2ef38e7c2aa2e5c58-c766d.jpg 300w,
/static/api-9f64e8f9d2dde1c2ef38e7c2aa2e5c58-f0d1c.jpg 600w,
/static/api-9f64e8f9d2dde1c2ef38e7c2aa2e5c58-19371.jpg 1200w,
/static/api-9f64e8f9d2dde1c2ef38e7c2aa2e5c58-ef898.jpg 1500w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;I was working on an application communicating with a web API. I did similar things before. I wrote plenty of methods making HTTP calls, processing the output and handling errors. But this was a different story. There wasn’t a single domain. There were few. Moreover, in order to perform one operation, I needed to send many HTTP requests. They were strictly correlated — each request contained some data from the previous response. And did I mention a single business process was distributed among many processes of a task queue? It already seemed hard, but the worst was yet to come.
During the development phase I wrote many unit tests. I used the mocking tool provided by the test framework to create test doubles of objects communicating with the external world. I was checking if correct methods were called, what was the result of method calls if the API returned some particular response etc.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/integration_collapsed-b414b919ed809457abe9717d6c8cb5f5-ef898.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 69.4%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAOABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAMCBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAeBSeyYP/8QAGhAAAgIDAAAAAAAAAAAAAAAAAQISMQADEP/aAAgBAQABBQIXtSD4LZpc/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFxAAAwEAAAAAAAAAAAAAAAAAABARAf/aAAgBAQAGPwIjur//xAAZEAEAAwEBAAAAAAAAAAAAAAABABARYUH/2gAIAQEAAT8hGggYVTpSwMd+nDK//9oADAMBAAIAAwAAABBQD//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABoQAQACAwEAAAAAAAAAAAAAAAEAERBhkTH/2gAIAQEAAT8Q2AhEQkDdDzGgG4zE8lgOGP/Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;integration collapsed&quot;
        title=&quot;&quot;
        src=&quot;/static/integration_collapsed-b414b919ed809457abe9717d6c8cb5f5-19371.jpg&quot;
        srcset=&quot;/static/integration_collapsed-b414b919ed809457abe9717d6c8cb5f5-c766d.jpg 300w,
/static/integration_collapsed-b414b919ed809457abe9717d6c8cb5f5-f0d1c.jpg 600w,
/static/integration_collapsed-b414b919ed809457abe9717d6c8cb5f5-19371.jpg 1200w,
/static/integration_collapsed-b414b919ed809457abe9717d6c8cb5f5-ef898.jpg 1500w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;I did it. It worked perfectly on my dev machine. Great! But it miserably failed in production. Great… Most of the time the user saw nothing but a message saying that an error occurred while trying to communicate with the external system. How was that possible? I wrote automated tests. I did some manual testing as well. Never saw anything like this.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/race_condition-982c1371991294001011e98ef72cff90-ef898.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAMEBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAdiWxY8A/8QAGRABAQEBAQEAAAAAAAAAAAAAAgEDEQQU/9oACAEBAAEFAnrDJ6j0qM3MqfPlwkif/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAHBABAAIBBQAAAAAAAAAAAAAAAQARAhIhMlFx/9oACAEBAAY/Al6m+R5U1YtkpJwJWIBP/8QAGhABAAIDAQAAAAAAAAAAAAAAAQARITFhQf/aAAgBAQABPyEiJ0ztGqq4UAmkjwKLcwDX7WZzDQT/2gAMAwEAAgADAAAAEHAP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAHBABAAICAwEAAAAAAAAAAAAAAREhAEExUYFh/9oACAEBAAE/EE4yQyRJojlmoN4ojknVNW+dR7gijngOVUiHT2dN4DqikKfedGWmiYQTn//Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;race condition&quot;
        title=&quot;&quot;
        src=&quot;/static/race_condition-982c1371991294001011e98ef72cff90-19371.jpg&quot;
        srcset=&quot;/static/race_condition-982c1371991294001011e98ef72cff90-c766d.jpg 300w,
/static/race_condition-982c1371991294001011e98ef72cff90-f0d1c.jpg 600w,
/static/race_condition-982c1371991294001011e98ef72cff90-19371.jpg 1200w,
/static/race_condition-982c1371991294001011e98ef72cff90-ef898.jpg 1500w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;A quick investigation revealed there was a race condition problem. The API was responding with some IDs. Right after receiving those IDs, I was sending them back in order to ask for more details. It turned out that the production environment was fast enough to get a &lt;em&gt;404 Not Found response&lt;/em&gt; for resources which, according to the API, have just been created. There were also few very similar problems. And just one solution — to repeat the request.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/how_to_test-ad5c057a80e51cac503bf7f9b931ec11-ef898.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 64.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAMEBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAd6SxY0A/8QAGhAAAgIDAAAAAAAAAAAAAAAAARIAAgMQMf/aAAgBAQABBQI8xs+qVUT/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAaEAACAgMAAAAAAAAAAAAAAAABIRARABJR/9oACAEBAAY/AllbE9ku3H//xAAaEAEAAgMBAAAAAAAAAAAAAAABEUEAEDEh/9oACAEBAAE/IZStU5VEOi9uR9k8jX//2gAMAwEAAgADAAAAEOAP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGhABAQADAQEAAAAAAAAAAAAAAREhQVEQAP/aAAgBAQABPxDX8XhdX5hJdGwF6vtkU1iBcGOd8//Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;how to test?&quot;
        title=&quot;&quot;
        src=&quot;/static/how_to_test-ad5c057a80e51cac503bf7f9b931ec11-19371.jpg&quot;
        srcset=&quot;/static/how_to_test-ad5c057a80e51cac503bf7f9b931ec11-c766d.jpg 300w,
/static/how_to_test-ad5c057a80e51cac503bf7f9b931ec11-f0d1c.jpg 600w,
/static/how_to_test-ad5c057a80e51cac503bf7f9b931ec11-19371.jpg 1200w,
/static/how_to_test-ad5c057a80e51cac503bf7f9b931ec11-ef898.jpg 1500w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;I got concerned. How was I supposed to test this? I already knew it would never occur on my machine. Pretty soon I realised that really good, isolated and automated tests were not my support. They were my only hope. There was simply no other way. I needed to somehow create a test double of the whole, stateful web API!&lt;/p&gt;
&lt;p&gt;The HTTP client I was using was a piece of object oriented software. I could easily use the mocking tool to create its test double which would always respond with some particular response to some particular request. But such a simple, stateless behavior was not even close to how the actual service behaved. I seriously needed a test double which would work (and fail) like the real API.&lt;/p&gt;
&lt;p&gt;The very first idea I got was to write some imperative code that would mimic the stateful behavior. It didn’t feel correct. If I can make mistakes writing simple imperative code making some calls, how can I know another imperative code responding to these calls is free of bugs? I faced this problem around the time when I got interested in practical application of state machines in web applications (which few years later led to the creation of &lt;a href=&quot;http://127.0.0.1:4000/post/state-machines-to-the-rescue-of-complex-forms&quot;&gt;Rosmaro&lt;/a&gt;). I recalled the State design pattern and implemented the interface of the HTTP client around the idea of a graph where every leaf was a response and every arrow was a request. It allowed me to mimic some pretty complex behavior in a way that was easy on the brain and closely reflected how did the API behave in production.&lt;/p&gt;
&lt;p&gt;For the purpose of this article, I’d like to focus on a simple yet stateful interaction with a web API. Because we’re talking about web applications, it’s natural to choose a ToDo App as the example. Our task is to add a ToDo and then mark it as done. There are two endpoints: one to add a ToDo and another one to mark a ToDo as done. After adding a ToDo we’re given its ID. We can then use it to mark it as done.
I solved the problem I faced by implementing my own mocking tool using the State design pattern. But I wouldn’t do it again. The only reason I did it was because I didn’t know a great tool called WireMock. Let me quote the official documentation to explain what sets it apart from other mocking tools.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;WireMock supports state via the notion of scenarios. A scenario is essentially a state machine whose states can be arbitrarily assigned.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It had me at behavior modeled as state machines.&lt;/p&gt;
&lt;p&gt;Let’s run it as a standalone process and configure it using a bunch of JSON files in order to mimic the behavior shown in the picture below. This WireMock process will simply behave like an HTTP server. We can then configure our system under the test to send requests to an address like &lt;em&gt;localhost:8888&lt;/em&gt; instead of &lt;em&gt;example.com/api&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/add_and_mark_as_done_graph-93fac2e4ebd4f34db7c7b6568c69f1ca-ef898.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 25.4%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAFABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAB34FB/8QAFBABAAAAAAAAAAAAAAAAAAAAEP/aAAgBAQABBQJ//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAEP/aAAgBAQAGPwJ//8QAGBAAAgMAAAAAAAAAAAAAAAAAABAhUYH/2gAIAQEAAT8h0m1//9oADAMBAAIAAwAAABBzz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABkQAAMAAwAAAAAAAAAAAAAAAAABESFBwf/aAAgBAQABPxCMTLgSm2z/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;adding a todo&quot;
        title=&quot;&quot;
        src=&quot;/static/add_and_mark_as_done_graph-93fac2e4ebd4f34db7c7b6568c69f1ca-19371.jpg&quot;
        srcset=&quot;/static/add_and_mark_as_done_graph-93fac2e4ebd4f34db7c7b6568c69f1ca-c766d.jpg 300w,
/static/add_and_mark_as_done_graph-93fac2e4ebd4f34db7c7b6568c69f1ca-f0d1c.jpg 600w,
/static/add_and_mark_as_done_graph-93fac2e4ebd4f34db7c7b6568c69f1ca-19371.jpg 1200w,
/static/add_and_mark_as_done_graph-93fac2e4ebd4f34db7c7b6568c69f1ca-ef898.jpg 1500w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Here comes the first arrow connecting the initial node (which is always called &lt;em&gt;Started&lt;/em&gt;) with the &lt;em&gt;Added&lt;/em&gt; node:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;scenarioName&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Add and mark as done&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;requiredScenarioState&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Started&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;newScenarioState&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Added&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;request&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;url&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/todos/add&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;method&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;bodyPatterns&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;equalToJson&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;{ \&quot;todo\&quot;: \&quot;make a test double\&quot; }&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;response&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;status&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;headers&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;Content-Type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;application/json&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;jsonBody&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;123&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;em&gt;request&lt;/em&gt; key tells us that we expect it to be a request to add a ToDo. We will then get a response described under the &lt;em&gt;response&lt;/em&gt; key. It contains the ID our ToDo was given. Following this arrow will lead us to the Added node.
All our mock supports is to mark the added ToDo as done. The arrow between &lt;em&gt;Added&lt;/em&gt; and &lt;em&gt;Marked as done&lt;/em&gt; is defined in the following way:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;scenarioName&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Add and mark as done&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;requiredScenarioState&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Added&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;newScenarioState&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Marked as done&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;request&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;url&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/todos/markDone/123&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;method&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;POST&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;response&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;status&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;em&gt;requiredScenarioState&lt;/em&gt; key is very important. It states that this is an arrow from the &lt;em&gt;Added&lt;/em&gt; node. It means that even if we send a request that matches while the current state is different (let’s say we’ve just &lt;em&gt;Started&lt;/em&gt; and we’re in the the &lt;em&gt;Started&lt;/em&gt; node), it’s not going to be followed. It forces us to first add a ToDo and only then mark it as done. The ID within the request is also worth noticing. It’s the exact same ID the server responded with when we added a ToDo.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;scenarioName&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Add and mark as done&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;requiredScenarioState&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Marked as done&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;request&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;url&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/passed&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;method&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;GET&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;response&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;status&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The last node of this simple graph makes the server respond with the 200 HTTP code only if the ToDo has been successfully added and marked as done. This will allow us to verify if the code worked correctly.
Let’s see how does our mock API work.&lt;/p&gt;
&lt;p&gt;We’re adding a ToDo and its given an ID.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ curl \
    -H &amp;quot;Content-Type: application/json&amp;quot; \
    -X POST \
    -d &amp;#39;{&amp;quot;todo&amp;quot;: &amp;quot;make a test double&amp;quot;}&amp;#39; \
    http://localhost:8888/todos/add
{&amp;quot;id&amp;quot;:123}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can mark it as done.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ curl -i -X POST http://localhost:8888/todos/markDone/123
HTTP/1.1 200 OK&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And finally we’re making sure the ToDo was marked as done.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ curl -i http://localhost:8888/passed
HTTP/1.1 200 OK&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/recording-badcba36c068d48eecb01b0861f4d117-b8c0b.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1200px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 81.60095579450419%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsSAAALEgHS3X78AAACLklEQVQ4y6WS224SQRjHwZve6YPoS5jOBa/gM5j4CtzxGkZCInCBMTWmtFqbVKjGrICHBmEPpbDsGbZl2QOzO58zwyFGFmv0n/zzbWb3++3855tMhkpsvr/f/nKWExVl/1K+RFKvh04FER2dX6DjRgedfPiO3p5/RY3PfdTuaUj4JqMfF13U6/aQLMr7kijlWkLrQWYtpSW8uPHGYDoOcacuTGwbRNUBcaCDqIxAvtJAGoxhqNngXPugmVOwDBNsywbLskgSJ9Bpd15tgGPDOACqOE4wSRLCBMAM3GRVEwIk3rxn64R+nmDWaxjG4QaoaRoHUuE15G9NtQ009CVQsl2cTAcQhgsIwojXaIF5XbAaLYDuiP+Z8P1xbwMdY3zAflf6KGDcKcJQtaDbv+IeqiaIsgoKPce+NIK5H94O3ESOMcYEUrU8ttT1lMiGzoHD4Qjrmgau69KINGa021EU8W92AJdTHqgDPNJHYFoW3Hgz8OYejThPted79JyD9SB/H8oSOL5WsT4zIEoiHieMA5gFFBx6W2brwSJgs94G6voy8sSZYH6xJ1P4JHTAmbirc4KdSo1smiYH1ut13Gw2SP34lDzMPSJvTs74XYvjmPxBqVN+yRZ934/CkAalNi0nZs9s9rRpp+m9jFbA17/u8Aj+U7Ztv1vz7hSLxce1Wu15pVJ5Wq1Wn1Woy+Uyr9VbzHpYb6lUekJZ2Uw+n8/Shz3qu9T3/tGsd69QKGR/AnEC46KwG/6iAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;recording&quot;
        title=&quot;&quot;
        src=&quot;/static/recording-badcba36c068d48eecb01b0861f4d117-86d16.png&quot;
        srcset=&quot;/static/recording-badcba36c068d48eecb01b0861f4d117-bd9cb.png 300w,
/static/recording-badcba36c068d48eecb01b0861f4d117-fe5c6.png 600w,
/static/recording-badcba36c068d48eecb01b0861f4d117-86d16.png 1200w,
/static/recording-badcba36c068d48eecb01b0861f4d117-b8c0b.png 1674w&quot;
        sizes=&quot;(max-width: 1200px) 100vw, 1200px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;If you are like me and you got worried that it may be tedious work to properly mimic all the real endpoints, let me tell you about another WireMock feature I find amazing. Instead of describing how does the mock behave in the first place, we can order WireMock to record the traffic between our machine and the real API. All we need to do is to fire up the browser and enter &lt;em&gt;&lt;a href=&quot;http://where&quot;&gt;http://where&lt;/a&gt;&lt;/em&gt;is&lt;em&gt;wiremock&lt;/em&gt;listening/_&lt;em&gt;admin/recorder&lt;/em&gt;, enter the address of the real API and press the Record button. Now we can make requests to &lt;em&gt;localhost:8888&lt;/em&gt; like it would be example.com/api. All the requests and responses are going to be saved as JSON files for us.&lt;/p&gt;
&lt;p&gt;Of course it’s still the happy path. We could probably test it using the real API, even though it would be slower, less repeatable and dependent on the internet connection. But the real power of mocking APIs lies in the capability of testing how does our code behave in situations which are quite hard or even impossible to reproduce, like getting some specific errors or experiencing long delays. In order to do it, we can simply tweak a bit the graph representing the happy path by putting some 500 Internal Server Errors here and there. That’s exactly what I did to make sure my application was handling situations where the 5th request of out 8 fails three times.&lt;/p&gt;
&lt;p&gt;Another thing worth noticing is that having a mock of the API we can test code interacting with endpoints which don’t exist yet. Both the API client and the API server can be developed simultaneously, because the team responsible for the client doesn’t need to wait for the team working on the server to deliver a testing environment. They just need to agree on the API contract, what’s necessary anyways.&lt;/p&gt;
&lt;p&gt;WireMock has many other features, like: powerful request matchers, response templates and transformers, custom recording settings etc. This post is by no means an attempt to describe them all. I just wanted to encourage you to apply state machines to HTTP testing, because as you already know, it worked wonders with my test suite. It was literally the only way I found to deliver a working solution in a reasonable amount of time. If you’re willing to learn more about this amazing tool, I recommend &lt;a href=&quot;http://wiremock.org/docs/&quot;&gt;the official documentation of WireMock&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Happy testing to all of you!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[JavaScript is like a big city]]></title><link>https://coder.earth/post/javascript-is-like-a-big-city</link><guid isPermaLink="false">https://coder.earth/post/javascript-is-like-a-big-city</guid><pubDate>Sat, 29 Jul 2017 14:37:20 GMT</pubDate><content:encoded>&lt;p&gt;Let’s meet Adam. Adam enjoys hanging out dressed as a cartoon character. In the big city he lives in, he can find all the costumes he likes. Sure, some people don’t understand him. One of them is Brian. These two meet each other quite often waiting for the subway. Brian then looks at Adam and thinks to himself, ‘I bet he wears a big green dog costume only because he hasn’t learn how to wear a suit correctly!’. But he forgets about him as soon as he notices the perfect cufflinks on a store window. They both are able to enjoy their own ways of dressing up in the same way how JavaScript programmers may see lists everywhere (ClojureScript) or add types almost everywhere (TypeScript).&lt;/p&gt;
&lt;p&gt;It’s obvious that a city of millions of people cannot be served by one hairdresser. And it’s not only about the number of potential customers. Different people have different needs. Some want to just shorten the hair, while others look for a fancy hairstyle. From time to time Adam has his hair cut. But he doesn’t go to the same place Brian does. In the end it’s all about having your hair cut, but they expect it to be done in very different ways. And it’s totally fine to have different ways of getting your hair done, so is to have few libraries handling HTTP requests.&lt;/p&gt;
&lt;p&gt;Sometimes when it’s the lunch time, they see each other again. Brian is waiting for his meal to be served. He’s looking through the window of a fully vegetarian restaurant. Then he spots Adam running to the kebab place located next door. They both are grateful that they can have the exact dish they want. Because big cities are full of life, they attract people of all kinds. Those who love to cook can make their living by running a restaurant. They don’t need to offer food that will be accepted by everyone in the town. They can specialize in some narrow field and they can do it well. It’s not a rare case to see a JavaScript programmer who works mostly on back-end systems. Another JavaScript programmer may focus on rich front-end experience. Somebody else can use JavaScript to develop mobile applications.&lt;/p&gt;
&lt;p&gt;After living in that big city for a while, both Adam and Brian know which districts should be avoided. They know the city is not perfect, but they stay there because of all those possibilities they would never have in a small town. They create the city.&lt;/p&gt;
&lt;p&gt;JavaScript is very much like a big city. That was one of the reasons why I decided to re-write &lt;a href=&quot;http://coder.earth/post/state-machines-to-the-rescue-of-complex-forms&quot;&gt;Rosmaro&lt;/a&gt; in JavaScript.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Programming books on Kindle]]></title><link>https://coder.earth/post/programming-books-on-kindle</link><guid isPermaLink="false">https://coder.earth/post/programming-books-on-kindle</guid><pubDate>Wed, 12 Jul 2017 14:37:20 GMT</pubDate><content:encoded>&lt;p&gt;Recently I stumbled upon a Facebook pool asking whether I read programming books on Kindle. I voted yes. Definitely yes. I felt it didn&apos;t express my experience well enough, so I wrote a comment. What you&apos;re reading right now is the English version of this comment.&lt;/p&gt;
&lt;p&gt;I started reading programming books when I was a student. I was lucky enough that the public library in the city where I used to live offered access to many valuable books on software engineering. Some of the titles include &lt;em&gt;Design Patterns: Elements of Reusable Object-Oriented Software&lt;/em&gt; and &lt;em&gt;Extreme Programming Explained: Embrace Change&lt;/em&gt;. I also managed to buy books like &lt;em&gt;Thinking in Java&lt;/em&gt; and &lt;em&gt;PHP Objects, Patterns and Practice&lt;/em&gt;. And it was all paper.&lt;/p&gt;
&lt;p&gt;It didn&apos;t last long before I read all the paper books I was interested in I could borrow or buy easily. Happily, around that time, I got a job. It made me able to shop for any book I wanted without worrying about running short of pocket money. Well, sort of. Paying tons of money for a book shipped from a different continent didn&apos;t seem sane.&lt;/p&gt;
&lt;p&gt;I&apos;ve found a solution! Now I read exclusively on Kindle. When I was a commuter, I used to carry a book with me. Before I got my e-book reader, I read a blog post praising the possibility to read controversial e-books in public. I didn&apos;t quite believe in that. Would somebody notice the cover of my book? Soon I figured it out. I remember once when I was reading the previously mentioned Java book, one guy looked at me. &quot;Java...&quot; he said, in a voice full of disgust. I&apos;m pretty sure he was a Modern Language Programmer or one of those macho guys who always consider things like a garbage collector or operating system an unnecessary overhead. If I had my Kindle, I&apos;d avoid all the shame! But who knows, maybe I&apos;d never check out Ruby.&lt;/p&gt;
&lt;p&gt;There&apos;s another reason why I prefer electronic versions of books over paper when I read in means of public transport. They weight nothing. Compared to huge hardcover books, I can easily hold the reader in one hand. When I don&apos;t read, I can put it into the pocket of my jacket. My whole library in my pocket. Isn&apos;t this amazing? It doesn&apos;t matter if I&apos;m going to a nearby city or different continent. It&apos;s always that easy!&lt;/p&gt;
&lt;p&gt;By today&apos;s standards, e-book readers are not impressive computers. But they&apos;re computers, after all! Every time I recall that I read about something in some book, the built-in search function turns out to be a lot more convenient than the index at the end of a book. And did I mention that all the books fit into my pocket?&lt;/p&gt;
&lt;p&gt;I don&apos;t like messy notes in margins. That&apos;s why I hesitate to take them on paper. But with the on-screen keyboard it&apos;s a totally different story! They don&apos;t make the main text messy. They don&apos;t force me to write tiny letters. Great!&lt;/p&gt;
&lt;p&gt;Because English is the lingua franca of computing, I prefer to read in English. Unfortunately, it&apos;s not my mother tongue. Thus, some words are unknown to me. But it doesn&apos;t worry me, as all I need to do is to hold a word on the screen it and its definition pops up! So I not only carry the whole library with me. I carry the English dictionary as well!&lt;/p&gt;
&lt;p&gt;But the most important thing is that there are countless books to read. Shopping for books abroad can&apos;t be easier! And it takes seconds to deliver a book! If I couldn&apos;t buy some of the e-books I read, I&apos;d never read them. It&apos;s simply too hard to get some paper books. From time to time we can even get a book for free. For example, O’Reilly Media publishes many e-books for free.&lt;/p&gt;
&lt;p&gt;The E-ink screen is one of the biggest advantages of an e-book reader. It&apos;s also one of its downsides. The relatively small, gray-scale screen works great most of the time, but sometimes it&apos;s just too small and too gray. Recently I read a book describing a lot of color theory. There were big, colorful diagrams. I mean, I think there were. I haven&apos;t seen them. To me they were small and gray. Fortunately, it doesn&apos;t happen too often. If I&apos;d be consuming more content of this kind, I&apos;d consider trading great battery life and sunlight visibility for great colors and get a tablet.&lt;/p&gt;
&lt;p&gt;I&apos;m not a Kindle fanboy. The reason why I got it is that I hoped it would be a simple and problem-free product. I was right. It does everything I expect it to do and I can honestly recommend it. However, I try to avoid shopping exclusively for it. I prefer to buy e-books not only in the &lt;em&gt;.mobi&lt;/em&gt; format, but also &lt;em&gt;.pdf&lt;/em&gt; and &lt;em&gt;.epub&lt;/em&gt;. That way if I decide to change my device, I don&apos;t lose the books I paid for.&lt;/p&gt;
&lt;p&gt;I believe the things I mentioned sum up my experience with Kindle quite well. If you are considering getting one, please bear in mind that your needs may differ. I want to travel light and read in a foreign language. If you can easily get all the paper books you want and you don&apos;t mind carrying them, you may not need an e-book reader. Or maybe you already have one?&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How secure are old sessions?]]></title><link>https://coder.earth/post/how-secure-are-old-sessions</link><guid isPermaLink="false">https://coder.earth/post/how-secure-are-old-sessions</guid><pubDate>Fri, 02 Jun 2017 22:37:20 GMT</pubDate><content:encoded>&lt;p&gt;There are plenty of places where people can access the Internet using computers shared among many users: public libraries, schools or Internet cafés.&lt;/p&gt;
&lt;p&gt;Different people can get there. Unfortunately, some of them may be malicious. Usually we can expect that the user will have very limited rights and there will be some type of anti-malware software. Sadly, if our app keeps the same session ID after logging the user in, our users are in danger.&lt;/p&gt;
&lt;p&gt;The action of this story takes place in a fictional public library.&lt;/p&gt;
&lt;p&gt;A malicious person visits the login page, presses F12 to open the developer tools and takes a picture of the session ID with his phone. Then he closes the tab and sits somewhere else, where he enters the session ID stolen from himself. The trap is set.&lt;/p&gt;
&lt;p&gt;Somebody takes the seat previously taken by the attacker. The computer is not infected, the connection is encrypted and the victim is totally unaware of the threat. He authenticates.&lt;/p&gt;
&lt;p&gt;This is the moment the attacker has been waiting for! Because the app doesn&apos;t regenerate the session ID before putting there the data of the authenticated user, now both the victim and the attacker share the same session. The attacker can do everything he could do as he would be sitting in front of the victim&apos;s computer.&lt;/p&gt;
&lt;p&gt;How can we protect our users against that kind of attacks? We should never put their data into &quot;old&quot; sessions. Before we log the user in, we regenerate the session and get a new ID.&lt;/p&gt;
&lt;p&gt;If we write node and the authentication middleware we use doesn&apos;t regenerate the session, we can use the &lt;a href=&quot;https://github.com/lukaszmakuch/express-new-session&quot;&gt;express-new-session&lt;/a&gt; middleware:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; newSession &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;express-new-session&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/login&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;newSession&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tryToLogin&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you work with different technologies, the easiest way to figure out whether the system is vulnerable to this type of attacks, is to check whether the session ID changes after an user logs in.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[State machines to the rescue of complex forms]]></title><link>https://coder.earth/post/state-machines-to-the-rescue-of-complex-forms</link><guid isPermaLink="false">https://coder.earth/post/state-machines-to-the-rescue-of-complex-forms</guid><pubDate>Sat, 06 May 2017 22:37:20 GMT</pubDate><content:encoded>&lt;p&gt;Complex forms may have many names, like wizards or creators, but they are always a challenge to implement and even a greater challenge to modify. A little change in the drawing on the whiteboard may lead to plenty of changes of if statements, session variables and routes.&lt;/p&gt;
&lt;h2&gt;The hidden machine&lt;/h2&gt;
&lt;p&gt;Very often during the process of development the whiteboard gets full of drawings representing different looks and behaviors connected with arrows named after some events. It helps us to understand the complex nature of the system we&apos;re building by taking away all of those constructions like assignments or conditional statements. Unfortunately the actual code rarely reminds of those drawings, even though they often look exactly like one of the fundamental concepts in computer science - state machines.&lt;/p&gt;
&lt;p&gt;Sadly, state machines seem to be an underestimated idea in the world of web applications. Why is that? One of the reasons may be the fact that all the examples we can easily find differ a lot from the reality of back-end programming. A wonderful model of a vending machine or a turnstile may look appealing, but in the end it&apos;s nothing we need in our web app. A function that given a string gives another string still isn&apos;t a ready to use solution. Of course there are also different reasons, like open questions about storage mechanisms or solving the problem of state explosion.&lt;/p&gt;
&lt;h2&gt;When nodes and arrows become first-class citizens&lt;/h2&gt;
&lt;p&gt;In this article we&apos;re going to take a look at a wizard implemented around the idea of state machines, where things like methods, variables or conditionals are implementation details.&lt;/p&gt;
&lt;h2&gt;The goal and the toolchain&lt;/h2&gt;
&lt;p&gt;The goal of that wizard is to take orders for things to drink. It&apos;s implemented in node with &lt;a href=&quot;https://expressjs.com&quot;&gt;express&lt;/a&gt; and &lt;a href=&quot;https://rosmaro.js.org&quot;&gt;rosmaro&lt;/a&gt;. I&apos;ll skip the process of building it, because it&apos;s intentionally not the simplest example. I&apos;d like to focus on what does the code look like when things get complicated.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/wizard-2ae75be29166cb3be27ae2eb5cd852d5.gif&quot; alt=&quot;wizard&quot;&gt;&lt;/p&gt;
&lt;p&gt;The scary part is the wall of text that could be called &quot;requirements&quot;. The wizard visible above is relatively complex, and so is the description. To save you the pain I removed the boring parts and left only what indicates the complexity:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;At the beginning [...] then we display a screen [...] it may be skipped [...] consists of few steps [...] First we see [...] If we picked a cold drink [...] Otherwise under the select field [...] if we previously entered the correct promo code [...] From that final screen we go back [...] then before picking the drink [...]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Understanding that endless stream of ifs is very hard.&lt;/p&gt;
&lt;h2&gt;From the drawing into the code&lt;/h2&gt;
&lt;p&gt;After reading the whole description (what you luckily don&apos;t need to do) it becomes clear that it always begins with a promo code screen and then we enter the path for either a valid or invalid promo code.&lt;/p&gt;
&lt;p&gt;So the drawing of the main graph would look like this:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/main_graph-5ce4edb51568977b54be71a01c3e6a77-51d83.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1122px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 59.09090909090909%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAB3SlQf//EABcQAQEBAQAAAAAAAAAAAAAAAAARARD/2gAIAQEAAQUC7qJH/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAIP/aAAgBAQAGPwJf/8QAGhABAAIDAQAAAAAAAAAAAAAAAQAREDFBIf/aAAgBAQABPyEXdMQfW8Dk07ACif/aAAwDAQACAAMAAAAQQw//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAcEAEBAQABBQAAAAAAAAAAAAABEQBxECExUWH/2gAIAQEAAT8QRVWyCZQCz746UoUH06GFRzu8Cc7/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;wizard&quot;
        title=&quot;&quot;
        src=&quot;/static/main_graph-5ce4edb51568977b54be71a01c3e6a77-51d83.jpg&quot;
        srcset=&quot;/static/main_graph-5ce4edb51568977b54be71a01c3e6a77-433ca.jpg 300w,
/static/main_graph-5ce4edb51568977b54be71a01c3e6a77-c1a9e.jpg 600w,
/static/main_graph-5ce4edb51568977b54be71a01c3e6a77-51d83.jpg 1122w&quot;
        sizes=&quot;(max-width: 1122px) 100vw, 1122px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;What can be directly reflected in the code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;graph&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  start&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;promo_code&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  arrows&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    promo_code&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      ok&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ordering_with_promo_code&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      wrong&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ordering_without_promo_code&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      skipped&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ordering_without_promo_code&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    ordering_without_promo_code&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      go_back&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;promo_code&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  nodes&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    promo_code&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;promo_code&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ordering_with_promo_code&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ordering_with_promo_code&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ordering_without_promo_code&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ordering_without_promo_code&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Those factory functions like &lt;em&gt;promo&lt;/em&gt;code&lt;em&gt;, _ordering&lt;/em&gt;with&lt;em&gt;promo&lt;/em&gt;code_ and &lt;em&gt;ordering&lt;/em&gt;without&lt;em&gt;promo&lt;/em&gt;code_ return other graphs built in the same way.&lt;/p&gt;
&lt;p&gt;The screen responsible for picking the drink has a finite number of variants. Great! Here goes the sketch:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/pick_drink_graph-5e5b47ac917ba5067329853e248dc436-b3be4.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1000px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 78.4%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAQABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAIF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAB3QUD/8QAFBABAAAAAAAAAAAAAAAAAAAAIP/aAAgBAQABBQJf/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAIP/aAAgBAQAGPwJf/8QAGBABAAMBAAAAAAAAAAAAAAAAAQARMRD/2gAIAQEAAT8hzZVnAajpz//aAAwDAQACAAMAAAAQMM//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAZEAEBAQEBAQAAAAAAAAAAAAABEQAhMUH/2gAIAQEAAT8QI18fMwSh73DCRxFztvd2SYIQ3//Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;wizard&quot;
        title=&quot;&quot;
        src=&quot;/static/pick_drink_graph-5e5b47ac917ba5067329853e248dc436-b3be4.jpg&quot;
        srcset=&quot;/static/pick_drink_graph-5e5b47ac917ba5067329853e248dc436-27d6e.jpg 300w,
/static/pick_drink_graph-5e5b47ac917ba5067329853e248dc436-5d038.jpg 600w,
/static/pick_drink_graph-5e5b47ac917ba5067329853e248dc436-b3be4.jpg 1000w&quot;
        sizes=&quot;(max-width: 1000px) 100vw, 1000px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;And here&apos;s the code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;pick_drink&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;graph&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  start&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;nothing_configured&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  arrows&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    nothing_configured&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      picked_hot_drink&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;pick_cooler&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      picked_cold_drink&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;cold_drink_configured&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    pick_cooler&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      picked_cooler&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;hot_drink_configured&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      picked_cold_drink&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;cold_drink_configured&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    hot_drink_configured&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      picked_hot_drink&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;hot_drink_configured&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      picked_cooler&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;hot_drink_configured&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      picked_cold_drink&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;cold_drink_configured&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

    cold_drink_configured&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      picked_hot_drink&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;pick_cooler&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      picked_cold_drink&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;cold_drink_configured&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  nodes&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    nothing_configured&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;nothing_configured&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    cold_drink_configured&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cold_drink_configured&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    pick_cooler&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pick_cooler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    hot_drink_configured&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;hot_drink_configured&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can clearly see 4 nodes connected with arrows. Let&apos;s take a closer look at the factory of the screen called &quot;cold drink configured&quot;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;cold_drink_configured&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;composite&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  nodes&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;change_drink_type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sugar&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;set_sugar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;nav&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pick_cold_button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Again, it closely reflects the sketch. It has a separated way to change the drink type, set the sugar and a button that finally picks the configured cold drink.&lt;/p&gt;
&lt;p&gt;So far there have been no if statements. Is that approach totally free of them? No, it&apos;s not. There are some, just deeper. Let&apos;s dig then. That&apos;s the code of the &lt;em&gt;change&lt;/em&gt;drink&lt;em&gt;type&lt;/em&gt; factory:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; change_drink_type &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; picked &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;drink

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; html&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`
      &amp;lt;select class=&quot;auto-submit&quot; name=&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;safeHtml`$&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;drink&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&quot;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;coffee&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;tea&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;lemonade&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;drink &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; safeHtml&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`
          &amp;lt;option value=&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;drink&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;picked &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; drink &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;selected&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;drink&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/option&gt;
        `&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;select&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    `
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;params&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; picked &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; params&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;drink&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;picked&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; is_hot &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;coffee&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;tea&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;picked&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; arrow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; is_hot &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;picked_hot_drink&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;picked_cold_drink&quot;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;follow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;arrow&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;drink&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; picked&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What does this object do? It renders a list of all drinks and selects the currently picked one. It also handles the form data. How does it do it? It has a few if statements! One to check whether a drink is selected, another one to check whether we picked some drink and yet another one to determine whether that drink is hot! But aren&apos;t if statements definitely harmful? I don&apos;t think so. I&apos;d rather say they are very much like cakes - it&apos;s a great thing to have a piece of cake, but eating the whole cake could make us sick. Those little if statements actually turn out to be very helpful, because they save us from facing a problem called state explosion. Imagine how messy would it be if we needed a separate node for each drink just to display the selected one! So instead of sticking to the idea of pure FSM, we add some if statements where it&apos;s handy to make the graph more descriptive and less bloated. The important part is that the code is free of if statements that would just introduce some noise.&lt;/p&gt;
&lt;p&gt;It&apos;s a lot harder to make unwanted elements appear on the screen out of nowhere, because we made a mistake in an if statement, when there&apos;s no if statement to decide if they should be visible or hidden. Their placement within the graph tells enough.&lt;/p&gt;
&lt;h2&gt;No more /step1, /step2a, /step2b, /step2bfinal, /step3...&lt;/h2&gt;
&lt;p&gt;A pattern that may be often seen is to create a bunch of GET endpoints for every step of the wizard. Unfortunately, things get very complicated when it comes to access control. Let&apos;s say the user hasn&apos;t entered the valid promo code, but she&apos;s trying to open the &lt;em&gt;/order-wizard/ordering-with-promo-code&lt;/em&gt; address. We don&apos;t want any insecure direct access like that. So we put a bunch of if statements in front of every single view. That&apos;s some additional work to do and another opportunity to introduce bugs.&lt;/p&gt;
&lt;p&gt;The good thing is that a model with a state machine under the hood, where the current state is not a public and mutable property (like the request path), can completely eliminate this problem. We don&apos;t expose all the possible states, just to later limit the access with if statements. Instead of that, we relay on the fact that there&apos;s always only one current node and we have one endpoint like &lt;em&gt;/wizard&lt;/em&gt;. Here&apos;s the whole express-specific code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/wizard&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;render_wizard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;wizard&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/wizard&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; wizard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;redirect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;The &quot;go back&quot; button just goes back&lt;/h2&gt;
&lt;p&gt;A very simple example of node reuasbility is the &quot;go back&quot; button. What does it do? It goes back. But where? The graph will tell us.&lt;/p&gt;
&lt;p&gt;That&apos;s the code of the button:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; go_back &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; safeHtml&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`&amp;lt;input
      type=&quot;submit&quot;
      name=&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;back&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;
      value=&quot;Back&quot;&gt;`&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;params&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;params&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;back&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;follow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;go_back&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When clicked, it follows the go_back arrow. That&apos;s it. It doesn&apos;t tell where exactly does it go. It just express the intention to go back.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ordering_with_promo_code_graph-5c3bfa5709c8d1803e5df942699272ac-b3be4.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1000px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 51.300000000000004%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAKABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAd1zQwD/xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAEFAl//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAVEAEBAAAAAAAAAAAAAAAAAAAQAf/aAAgBAQAGPwJr/8QAGhAAAgIDAAAAAAAAAAAAAAAAAAERIRAxof/aAAgBAQABPyGIdHCx6Cx//9oADAMBAAIAAwAAABAQz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABoQAQADAQEBAAAAAAAAAAAAAAEAESExEGH/2gAIAQEAAT8QaFBeGTVbYGnL+3M0ZsA9L8//2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;wizard&quot;
        title=&quot;&quot;
        src=&quot;/static/ordering_with_promo_code_graph-5c3bfa5709c8d1803e5df942699272ac-b3be4.jpg&quot;
        srcset=&quot;/static/ordering_with_promo_code_graph-5c3bfa5709c8d1803e5df942699272ac-27d6e.jpg 300w,
/static/ordering_with_promo_code_graph-5c3bfa5709c8d1803e5df942699272ac-5d038.jpg 600w,
/static/ordering_with_promo_code_graph-5c3bfa5709c8d1803e5df942699272ac-b3be4.jpg 1000w&quot;
        sizes=&quot;(max-width: 1000px) 100vw, 1000px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Here if we click the &quot;back&quot; button we are redirected to the screen where we can enter the name.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/main_graph-5ce4edb51568977b54be71a01c3e6a77-51d83.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 1122px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 59.09090909090909%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAB3SlQf//EABcQAQEBAQAAAAAAAAAAAAAAAAARARD/2gAIAQEAAQUC7qJH/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAIP/aAAgBAQAGPwJf/8QAGhABAAIDAQAAAAAAAAAAAAAAAQAREDFBIf/aAAgBAQABPyEXdMQfW8Dk07ACif/aAAwDAQACAAMAAAAQQw//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAcEAEBAQABBQAAAAAAAAAAAAABEQBxECExUWH/2gAIAQEAAT8QRVWyCZQCz746UoUH06GFRzu8Cc7/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;wizard&quot;
        title=&quot;&quot;
        src=&quot;/static/main_graph-5ce4edb51568977b54be71a01c3e6a77-51d83.jpg&quot;
        srcset=&quot;/static/main_graph-5ce4edb51568977b54be71a01c3e6a77-433ca.jpg 300w,
/static/main_graph-5ce4edb51568977b54be71a01c3e6a77-c1a9e.jpg 600w,
/static/main_graph-5ce4edb51568977b54be71a01c3e6a77-51d83.jpg 1122w&quot;
        sizes=&quot;(max-width: 1122px) 100vw, 1122px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;But here clicking the same button will take us to the screen where we can enter the promo code. And there are no ifs for that. The same button may be reused wherever we want. We just connect the arrow to a different node.&lt;/p&gt;
&lt;h2&gt;We should give state machines a go&lt;/h2&gt;
&lt;p&gt;It seems that in web development, compared to areas like game development, we don’t utilize the full power of state machines.
If you haven’t tried yet, I strongly encourage you to identify state machines hidden in your code. Extracting them into a readable structure often leads to a surprisingly clear, declarative model of our domain.&lt;/p&gt;
&lt;h2&gt;Further reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;David Harel, Statecharts: A visual formalism for complex systems&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/lukaszmakuch/rosmaro-example-wizard&quot;&gt;the source code of the application described in this post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rosmaro.js.org&quot;&gt;rosmaro.js.org&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[When to cut carrots in half?]]></title><link>https://coder.earth/post/when-to-cut-carrots-in-half</link><guid isPermaLink="false">https://coder.earth/post/when-to-cut-carrots-in-half</guid><pubDate>Tue, 21 Feb 2017 22:37:20 GMT</pubDate><content:encoded>&lt;p&gt;A long time ago I heard a joke that I recalled recently while thinking about programming.&lt;/p&gt;
&lt;p&gt;I don&apos;t remember it in details, but the overall meaning is preserved. Here it goes:&lt;/p&gt;
&lt;p&gt;Two friends were talking about carrots:&lt;/p&gt;
&lt;p&gt; - Jim, why do you always cut carrots in half, when you want to boil them?&lt;/p&gt;
&lt;p&gt; - That&apos;s simple, Tim. I do it because my mom was always doing that.&lt;/p&gt;
&lt;p&gt;Tim got a bit confused, so he decided to ask Jim&apos;s mom about that:&lt;/p&gt;
&lt;p&gt;- Jim always cuts carrots in half. He told me you always do it. Why is that?&lt;/p&gt;
&lt;p&gt;- I don&apos;t know why does Jim do it, but I was doing it because the pot I had was too small.&lt;/p&gt;
&lt;p&gt;When I was doing my very first steps in software development, I didn&apos;t have too much experience with different programming languages. The vast majority of my code was written in PHP. I was lucky enough to read books that improved my skills a lot. That great literature on programming was mostly based on Java or similar languages. Some of those fantastic books were released more than 10 years ago.&lt;/p&gt;
&lt;p&gt;I find neat solutions valuable, so when I was facing a problem I read about in a book, I was doing my best to apply that clever solution I found in the book. It all looked right and most of the time it was the best thing I could do. However, sometimes that solution was addressing a problem I didn&apos;t have. I didn&apos;t know about it, because I didn&apos;t know any alternative solution.&lt;/p&gt;
&lt;p&gt;If I needed to check whether a person meets some requirement, I&apos;d look at something like the following example.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonTester&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;metBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Person p&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ThreeLettersName&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonTester&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;metBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Person p&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;PersonTester requirement &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ThreeLettersName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then I&apos;d write something similar in PHP. I would not consider anything like this.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre class=&quot;language-php&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$meetsRequirement&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$person&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mb_strlen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$person&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Why? Because I didn&apos;t see it in those books written by people a lot smarter than me. Why wasn&apos;t it mentioned? Does it mean it&apos;s a bad solution? I don&apos;t think so. There&apos;s an explanation that makes much more sense. Their pots were too small. When those books were written, Java didn&apos;t support code like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;Predicate&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Person&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; requirement &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; p &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Something like this wouldn&apos;t look serious to me.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre class=&quot;language-php&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$person&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Object&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;name&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;Jim&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;email&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;jim@domain_of_jim.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The correct way I knew was something like this.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; String name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; String email&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;String name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; String email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;String name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;getEmail&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setEmail&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;String email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Using objects as mutable, dumb bags of data, when there are no constructions that act like bags of data provided by the language, is understandable. Sticking to this solution as the only one available in PHP, which has array literals and magic methods, is sometimes harder to justify.  &lt;/p&gt;
&lt;p&gt;Avoiding heavy builds every time we change a configuration detail and letting applications written in different languages read from the same config file is a great thing. Fortunately there&apos;s no such thing as heavy builds in the PHP world. It&apos;s quite uncommon to share all the config files with a totally different application neither. That&apos;s why associative arrays often turn out to be a faster and better solution.&lt;/p&gt;
&lt;p&gt;I&apos;m aware of the fact that some of the alternative solutions I presented here mean degradation of PHP tooling support (like autocomplete functions of IDEs). However, the &quot;static vs. dynamic&quot; conflict is a topic for another entry.&lt;/p&gt;
&lt;p&gt;Long story short - the most important lesson I learned from working with different technologies is to always check what&apos;s the problem some solution solves before applying it.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Singletons are often misused but easy to test]]></title><link>https://coder.earth/post/singletons-are-often-misused-but-easy-to-test</link><guid isPermaLink="false">https://coder.earth/post/singletons-are-often-misused-but-easy-to-test</guid><pubDate>Sun, 13 Nov 2016 22:37:20 GMT</pubDate><content:encoded>&lt;p&gt;A discussion on singletons:&lt;/p&gt;
&lt;p&gt;Why are singletons so nice?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Because they are easy to use.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why are they easy to use?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Because they provide us a way of getting an object we need.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why are singletons bad?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Because they make testing hard.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why do they make testing hard?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Because it&apos;s impossible to use their test doubles while testing code which depends on them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Judging from my experience, &lt;strong&gt;none of those answers is correct&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Let&apos;s start from testing.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FloristShop&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;placeOrder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
    DeliveryGuy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deliver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;flowers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; address&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&apos;s not so rare to hear that now every time the test suite runs, some poor guy delivers some flowers... somewhere. It happens in real life, because it&apos;s a real delivery service and not a test double, thus we&apos;re charged for that! Sounds awful! Fortunately that&apos;s not true. We don&apos;t even need a special mocking framework in order to use a test double of the &lt;em&gt;DeliveryGuy&lt;/em&gt;. If our singleton has the following method:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; IDeliveryGuy &lt;span class=&quot;token function&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;there may be one like this as well:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;IDeliveryGuy instance&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;so in the setup method of the test class we can simply write:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;DeliveryGuy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DeliveryGuyTestDouble&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the same way the main method of our application could set the real delivery service instance, so running the test suite without passing a fake &lt;em&gt;IDeliveryGuy&lt;/em&gt; implementation to the &lt;em&gt;setInstance&lt;/em&gt; method will cause an exception and won&apos;t accidentally send the real delivery guy to the address used in the test suite.&lt;/p&gt;
&lt;p&gt;But what about the ease of use? Don&apos;t singletons make it easier to write the code? Sometimes they do, but only in languages without global variables, as they are nothing but global variables. Otherwise a global variable can be used, what&apos;s even easier. The main source of problems with singletons I&apos;ve seen is using them for a totally different purpose than they are created for. Their main job isn&apos;t to address the question &quot;How do I get this object?&quot; but to limit the number of instances of some class to exactly one. In other words, &lt;strong&gt;making writing any code easier isn&apos;t what are they created for. It&apos;s making writing some code impossible&lt;/strong&gt;. And they do it well. Unconsciously putting this restriction on our code often leads to a situation when we would like to use composition, but we can&apos;t. Take a look the following example which doesn&apos;t use the Singleton design pattern:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;FloristShop mainShop &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FloristShop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RegularDeliveryGuy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let&apos;s imagine we want to add support of a premium florist shop, which delivers orders faster. We can easily avoid duplication and changes of the already existing code by constructing the premium shop this way:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;FloristShop mainShop &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FloristShop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RegularDeliveryGuy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
FloristShop premiumShop &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FloristShop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MotorDrivingDeliveryGuy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As we can see, it would be impossible with singletons, because there could be just one delivery guy.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Multiple dispatch in Java]]></title><link>https://coder.earth/post/multiple-dispatch-in-java</link><guid isPermaLink="false">https://coder.earth/post/multiple-dispatch-in-java</guid><pubDate>Sun, 25 Sep 2016 22:37:20 GMT</pubDate><content:encoded>&lt;p&gt;In this article I&apos;d like to show few examples of code beyond the world of single dispatch. I&apos;ll show why method overloading isn&apos;t enough, how things may be done in Clojure and that it&apos;s quite easy to write a similar code in Java. I hope you&apos;ll find this valuable.&lt;/p&gt;
&lt;h1&gt;Animal sounds&lt;/h1&gt;
&lt;p&gt;Let&apos;s tart with an interface of &lt;em&gt;Animal&lt;/em&gt;s:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Animal&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;doSound&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Just by looking at it we know that every single &lt;em&gt;Animal&lt;/em&gt; is able to do a sound.&lt;/p&gt;
&lt;p&gt;There are two classes of &lt;em&gt;Animal&lt;/em&gt;s: Cats and Cows respectively:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cat&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Animal&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;doSound&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Meow&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cow&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Animal&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;doSound&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Mooo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Thanks to polymorphism we can take any &lt;em&gt;Animal&lt;/em&gt; and make it do a sound:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;Animal meower &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Mr. Meower&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Animal mooer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Lady Mooer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;meower&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;doSound&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &quot;Meow&quot;&lt;/span&gt;
System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mooer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;doSound&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &quot;Mooo&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It doesn&apos;t matter if it&apos;s a &lt;em&gt;Cow&lt;/em&gt; or a &lt;em&gt;Cat&lt;/em&gt;, as the way of asking it to do a sound is the same. Please notice that in this example the compile time type of both the meower and the mooer is an &lt;em&gt;Animal&lt;/em&gt; and not a &lt;em&gt;Cat&lt;/em&gt; and a &lt;em&gt;Cow&lt;/em&gt;.
It works as expected only because the actual method that&apos;s being called is selected upon the runtime type of the &lt;em&gt;Animal&lt;/em&gt; we call the method on.&lt;/p&gt;
&lt;h1&gt;Cats differ from cows&lt;/h1&gt;
&lt;p&gt;Let&apos;s admit that cats slightly differ from cows:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cat&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Animal&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; String name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; remainingLifes&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Cat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;String name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; remainingLifes&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;remainingLifes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; remainingLifes&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;doSound&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Meow&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cow&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Animal&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; String name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; weight&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Cow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;String name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; weight&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;weight &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; weight&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;doSound&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Mooo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;Mr. Presenter who introduces animals&lt;/h1&gt;
&lt;p&gt;What if we would like to introduce &lt;em&gt;Animal&lt;/em&gt;s to the audience, but we don&apos;t want to make them responsible for that? Then we would need a presenter we could ask for introducing them.&lt;/p&gt;
&lt;h2&gt;Method overloading&lt;/h2&gt;
&lt;p&gt;The simplest, but not always working solution, could be method overloading.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Presenter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;introduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cat c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A kitty called &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; with &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;remainingLifes &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; lifes.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;introduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cow c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;weight &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; kg milk producer named &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Unfortunately method overloading isn&apos;t based on runtime types, but on compile time types. It means that even though this works as expected:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;Presenter presenter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Presenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

Cat meower &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Mr. Meower&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Cow mooer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Lady Mooer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;presenter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;introduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;meower&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;presenter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;introduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mooer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This doesn&apos;t even compile:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;Presenter presenter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Presenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

Animal meower &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Mr. Meower&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Animal mooer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Lady Mooer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;presenter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;introduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;meower&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;presenter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;introduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mooer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It happens because Java supports only single dispatch. The method that&apos;s actually called is selected upon the runtime type of just one variable - the object it is called on. Runtime types of other arguments aren&apos;t taken into account.&lt;/p&gt;
&lt;h2&gt;The visitor pattern&lt;/h2&gt;
&lt;p&gt;One of the possible solutions is the visitor pattern. We define its interface:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AnimalVisitor&lt;/span&gt;&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; T &lt;span class=&quot;token function&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cow c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; T &lt;span class=&quot;token function&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cat c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And we let it visit animals by &lt;strong&gt;modifying the Animal interface&lt;/strong&gt; to accept a visitor:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Animal&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;doSound&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; T &lt;span class=&quot;token function&quot;&gt;accept&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;AnimalVisitor&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; visitor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we need to add the following method to &lt;strong&gt;both the Cat and Cow&lt;/strong&gt; classes:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; T &lt;span class=&quot;token function&quot;&gt;accept&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;AnimalVisitor&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; visitor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; visitor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We&apos;re ready to write a presenting visitor:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PresentingVisitor&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AnimalVisitor&lt;/span&gt;&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cow c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;weight &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; kg milk producer named &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cat c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A kitty called &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; with &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;remainingLifes &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; lifes.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This allows us to forget about differences between cats and cows when we just want to ask a presenter to introduce some animals:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;AnimalVisitor&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; presenter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PresentingVisitor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

Animal meower &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Mr. Meower&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Animal mooer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Lady Mooer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;meower&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;accept&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;presenter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mooer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;accept&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;presenter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Thanks to applying the visitor pattern, it works as expected. Both Mr. Meower and Lady Mooer are considered simply &lt;em&gt;Animal&lt;/em&gt;s, not a &lt;em&gt;Cat&lt;/em&gt; and a &lt;em&gt;Cow&lt;/em&gt;. Because the &lt;em&gt;visit&lt;/em&gt; method is actually called by both the &lt;em&gt;Cat&lt;/em&gt; and the &lt;em&gt;Cow&lt;/em&gt;, the compiler knows which of the &lt;em&gt;AnimalVisitor&lt;/em&gt;&apos;s methods should be called - the one accepting a &lt;em&gt;Cat&lt;/em&gt; and the one accepting a &lt;em&gt;Cow&lt;/em&gt;, respectively. We can now write code that is far more generic, for example we can iterate over a collection of &lt;em&gt;Animal&lt;/em&gt;s and introduce each of them in appropriate way:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;AnimalVisitor&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; presenter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PresentingVisitor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

Animal&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; animals &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Animal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Mr. Meower&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Lady Mooer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Animal oneAnimal&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; animals&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;oneAnimal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;accept&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;presenter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The fact that now every animal must know how to accept a visitor isn&apos;t nice, because we need the visitor interface and its support since the very beginning (the first animal implementation). But it&apos;s not a high price for that flexibility, as it&apos;s always just one method regardless the number of implementations of the visitor interface. However, there&apos;s a more serious problem we face when we add or remove &lt;em&gt;Animal&lt;/em&gt;s.&lt;/p&gt;
&lt;p&gt;The visitor pattern is meant to make it easy to add new functions to &lt;strong&gt;existing&lt;/strong&gt; types, but not to add new types. It means that when it comes to adding new types, it doesn&apos;t allow us to follow the Open/Closed principle, because we&apos;re eventually forced to modify the code of already existing visitors as we keep adding new types.&lt;/p&gt;
&lt;h2&gt;Try Clojure&lt;/h2&gt;
&lt;p&gt;Let&apos;s try to do something similar in the Clojure programming language.
First we define our animals:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;clojure&quot;&gt;&lt;pre class=&quot;language-clojure&quot;&gt;&lt;code class=&quot;language-clojure&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defrecord&lt;/span&gt; Cow &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;name&lt;/span&gt; weight&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defrecord&lt;/span&gt; Cat &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;name&lt;/span&gt; remaining-lifes&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; animals &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cow. &lt;span class=&quot;token string&quot;&gt;&quot;Lady Mooer&quot;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cat. &lt;span class=&quot;token string&quot;&gt;&quot;Mr. Meower&quot;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we add a multimethod based on the class of the given object:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;clojure&quot;&gt;&lt;pre class=&quot;language-clojure&quot;&gt;&lt;code class=&quot;language-clojure&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defmulti&lt;/span&gt; introduce &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That allows us to add independent functions that introduce different animals.
We can start with cats. It means nothing but adding a method that&apos;s called when a &lt;em&gt;Cat&lt;/em&gt; is given:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;clojure&quot;&gt;&lt;pre class=&quot;language-clojure&quot;&gt;&lt;code class=&quot;language-clojure&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defmethod&lt;/span&gt; introduce Cat &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A kitty called &quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:name&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; with &quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:remaining-lifes&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; lifes.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And then we add support of &lt;em&gt;Cow&lt;/em&gt;s. There&apos;s no need of modifying the code responsible for introducing &lt;em&gt;Cat&lt;/em&gt;s or &lt;em&gt;Cow&lt;/em&gt;s themselves:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;clojure&quot;&gt;&lt;pre class=&quot;language-clojure&quot;&gt;&lt;code class=&quot;language-clojure&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defmethod&lt;/span&gt; introduce Cow &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A &quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:weight&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; kg milk producer named &quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:name&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now even if we want to introduce two different animals, we can use the same function. Thanks to polymorphism, the &lt;em&gt;introduce&lt;/em&gt; function is able to introduce both types of animals and doesn&apos;t require us to think which exact function to pick:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;clojure&quot;&gt;&lt;pre class=&quot;language-clojure&quot;&gt;&lt;code class=&quot;language-clojure&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;println&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;map&lt;/span&gt; introduce animals&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Modularity - that&apos;s why it&apos;s so awesome&lt;/h3&gt;
&lt;p&gt;But why is it nicer than the visitor pattern? The answer is very simple - modularity!&lt;/p&gt;
&lt;h4&gt;Adding new types doesn&apos;t force us to add new functions&lt;/h4&gt;
&lt;p&gt;When we add a new type of animal, let&apos;s say a &lt;em&gt;Bird&lt;/em&gt;, we&apos;re not forced to immediately add support of introducing it. Maybe we won&apos;t need it at all in our app? Maybe a bird will just be fed, but never introduced? It doesn&apos;t matter if the &lt;em&gt;Bird&lt;/em&gt; is the first of added animals, or there are already 10 more, if we want to add it&apos;s type we can simply write:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;clojure&quot;&gt;&lt;pre class=&quot;language-clojure&quot;&gt;&lt;code class=&quot;language-clojure&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defrecord&lt;/span&gt; Bird &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;name&lt;/span&gt; can-fly&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&apos;s all! We&apos;ve just added a new type without modifying anything and without a need of thinking about already existing types. We can now use &lt;em&gt;Bird&lt;/em&gt;s. Let&apos;s say we want to introduce them. The great thing is there&apos;s no need of changing the code that already exists to introduce other animals like &lt;em&gt;Cow&lt;/em&gt;s, &lt;em&gt;Cat&lt;/em&gt;s or some other types added in the meantime. We simply add:  &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;clojure&quot;&gt;&lt;pre class=&quot;language-clojure&quot;&gt;&lt;code class=&quot;language-clojure&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defmethod&lt;/span&gt; introduce Bird &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A bird named &quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:name&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; that &quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:can-fly&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;can&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;can&apos;t&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; fly.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Perfect! After the need of introducing &lt;em&gt;Bird&lt;/em&gt;s appeared, not before, we added an &lt;strong&gt;independent&lt;/strong&gt; new function that introduces them. A &lt;em&gt;Bird&lt;/em&gt; may be now added to the list of animals to introduce:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;clojure&quot;&gt;&lt;pre class=&quot;language-clojure&quot;&gt;&lt;code class=&quot;language-clojure&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; animals &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cow. &lt;span class=&quot;token string&quot;&gt;&quot;Lady Mooer&quot;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cat. &lt;span class=&quot;token string&quot;&gt;&quot;Mr. Meower&quot;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Bird. &lt;span class=&quot;token string&quot;&gt;&quot;Sparrow&quot;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;The final code&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;clojure&quot;&gt;&lt;pre class=&quot;language-clojure&quot;&gt;&lt;code class=&quot;language-clojure&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defrecord&lt;/span&gt; Cow &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;name&lt;/span&gt; weight&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defrecord&lt;/span&gt; Cat &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;name&lt;/span&gt; remaining-lifes&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defrecord&lt;/span&gt; Bird &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;name&lt;/span&gt; can-fly&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defmulti&lt;/span&gt; introduce &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defmethod&lt;/span&gt; introduce Cat &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A kitty called &quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:name&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; with &quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:remaining-lifes&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; lifes.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defmethod&lt;/span&gt; introduce Cow &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A &quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:weight&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; kg milk producer named &quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:name&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;defmethod&lt;/span&gt; introduce Bird &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A bird named &quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:name&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; that &quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:can-fly&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;can&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;can&apos;t&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; fly.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; animals &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cow. &lt;span class=&quot;token string&quot;&gt;&quot;Lady Mooer&quot;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cat. &lt;span class=&quot;token string&quot;&gt;&quot;Mr. Meower&quot;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Bird. &lt;span class=&quot;token string&quot;&gt;&quot;Sparrow&quot;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;println&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;map&lt;/span&gt; introduce animals&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It all looks great, doesn&apos;t it? I&apos;ve decided to show a Clojure example, because it&apos;s really clean in that language. Does it mean that in languages that support only single dispatch, like Java, it cannot be achieved? Of course it can!&lt;/p&gt;
&lt;h2&gt;One more attempt in Java&lt;/h2&gt;
&lt;h3&gt;Once again - what&apos;s our goal?&lt;/h3&gt;
&lt;p&gt;Just to sum it up - our goal is to have a presenter capable of introducing animals. We don&apos;t expect animals themselves to do that job well.&lt;/p&gt;
&lt;h2&gt;No need of visitors&lt;/h2&gt;
&lt;p&gt;If there will be a fully separated presenter, we don&apos;t need &lt;em&gt;Animal&lt;/em&gt;s to accept any visitors. We can go back to a very simple &lt;em&gt;Animal&lt;/em&gt; interface:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Animal&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;doSound&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Cat&lt;/em&gt;s may be now implemented without thinking about any visitors. No need of the &lt;em&gt;accept&lt;/em&gt; method.&lt;/p&gt;
&lt;h2&gt;How to talk to a presenter?&lt;/h2&gt;
&lt;p&gt;Let&apos;s write its interface this way:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Presenter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;introduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Animal a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; UnableToIntroduce&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;An important detail is the fact that it may throw a checked exception, when for some reason it&apos;s unable to introduce the given animal. To give you an example from the real world, let&apos;s imagine you&apos;re asking somebody the way. What if that person is not able to answer? Does the world end? Hopefully not! Can you make it on time? Maybe, maybe not. In the end it depends on you, not only on one person you asked.&lt;/p&gt;
&lt;p&gt;So because of this interface, we must be prepared for a situation when Mr. Presenter isn&apos;t able to introduce some animal. This exception may be then handled gracefully or cause an application crash. It&apos;s the client responsibility to make this decision.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An alternative solution could be to return some default value in case of failure, but from my experience I can tell you that it&apos;s easier to add it later than to add proper exception handling if there has been a default value since the very beginning. For example, if there&apos;s a suitable default value, we can write a decorator that catches some specified exceptions and returns that value.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&apos;s write the first presenter - the one that introduces cats:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CatPresenter&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Presenter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;introduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Animal a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; UnableToIntroduce
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a &lt;span class=&quot;token keyword&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UnableToIntroduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        Cat c &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cat&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A kitty called &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; with &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;remainingLifes &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; lifes.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Why do we have type checking and casting here? Because even though the interface lets us to introduce any &lt;em&gt;Animal&lt;/em&gt;, it also provides us a way of saying &quot;Sorry, I don&apos;t know how to do it!&quot;. That&apos;s why this particular implementation may support only &lt;em&gt;Cat&lt;/em&gt;s. The interface forces its clients to support both cases - when a presenter is able to introduce an animal and when it&apos;s not able to do it. This way we don&apos;t break any code that uses the presenter when we change it&apos;s implementation, because it&apos;s prepared for the fact that sometimes an animal may not be introduced.&lt;/p&gt;
&lt;h2&gt;Needs from the future don&apos;t influence the code now&lt;/h2&gt;
&lt;p&gt;Even if we know that in the future there will be &lt;em&gt;Cow&lt;/em&gt;s, we may not need them now. We can already test and deliver part of the functionality, which is full support of &lt;em&gt;Cat&lt;/em&gt;s or anything that uses &lt;em&gt;Animal&lt;/em&gt;s and &lt;em&gt;Presenter&lt;/em&gt;s. Let&apos;s use the first presenter.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;Presenter presenter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CatPresenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//--------------------&lt;/span&gt;

Animal&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; animals &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Animal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Mr. Meower&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Animal oneAnimal&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; animals&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;presenter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;introduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;oneAnimal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;UnableToIntroduce&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//failure handling code goes here&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The line I drew in the comment represents a very important concept - separation of the code that creates the presenter from the code that uses it. For the sake of simplicity, I&apos;m not showing here a separated object that uses a presenter passed to it as a constructor parameter (or in some special cases, using a setter). However, if we want to achieve modularity, the user of a service cannot be its creator in the same time.&lt;/p&gt;
&lt;h2&gt;With Cows (sometimes) comes their presenter&lt;/h2&gt;
&lt;p&gt;We knew this day would come. There are &lt;em&gt;Cow&lt;/em&gt;s. Moreover, we want to introduce them! So we need a &lt;em&gt;Cow&lt;/em&gt; presenter. In order to get more verbose exception messages from the presenter and keep the code simple, we can move the common part into a template method like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassSupportingPresenter&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Presenter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;introduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Animal a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; UnableToIntroduce
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;throwExceptionIfUnsupported&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;actuallyIntroduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;throwExceptionIfUnsupported&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Animal a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; UnableToIntroduce
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getClassOfSupportedAnimals&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UnableToIntroduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;%s supports only %s, but %s was given&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCanonicalName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token function&quot;&gt;getClassOfSupportedAnimals&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCanonicalName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCanonicalName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;abstract&lt;/span&gt; Class &lt;span class=&quot;token class-name&quot;&gt;getClassOfSupportedAnimals&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;abstract&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;actuallyIntroduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Animal raw&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; UnableToIntroduce&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Extending this abstract class, the &lt;em&gt;CowPresenter&lt;/em&gt; looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CowPresenter&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassSupportingPresenter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; Class &lt;span class=&quot;token class-name&quot;&gt;getClassOfSupportedAnimals&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Cow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;actuallyIntroduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Animal raw&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; UnableToIntroduce
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        Cow c &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cow&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;raw&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;weight &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; kg milk producer named &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;An instance of this class may be used to introduce &lt;em&gt;Cow&lt;/em&gt;s and only &lt;em&gt;Cow&lt;/em&gt;s. The problem of having one polymorphic method &lt;em&gt;introduce&lt;/em&gt; capable of introducing &lt;em&gt;Animal&lt;/em&gt;s of any kind hasn&apos;t been solved yet.&lt;/p&gt;
&lt;h2&gt;Dispatcher&lt;/h2&gt;
&lt;p&gt;We need a construction similar to the previously mentioned Clojure &lt;em&gt;introduce&lt;/em&gt; multimethod, that is a connection between a class of &lt;em&gt;Animal&lt;/em&gt;s and its &lt;em&gt;Presenter&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;The Container library&lt;/h3&gt;
&lt;p&gt;In this example I&apos;m going to use a simple map between classes and objects from the &lt;a href=&quot;https://github.com/lukaszmakuch/container&quot;&gt;Container&lt;/a&gt; library. I do it to avoid writing the same container logic over and over again, what allows to keep the domain specific code simpler. The &lt;em&gt;ObjectToObjectMap&lt;/em&gt; fits our needs perfectly:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ObjectToObjectMap&lt;/span&gt;&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;K&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; V&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; V &lt;span class=&quot;token function&quot;&gt;getValueBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;K keyObject&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; UnableToGetValue&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Given an object, gives another based on some logic. If nothing is found, a checked exception is thrown.&lt;/p&gt;
&lt;h3&gt;Presenter composed of many presenters&lt;/h3&gt;
&lt;p&gt;The complete implementation of the class we need in order to be able to use the &lt;em&gt;CatPresenter&lt;/em&gt;, the &lt;em&gt;CowPresenter&lt;/em&gt; and any other &lt;em&gt;Presenter&lt;/em&gt; in the future is:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ComposedPresenter&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Presenter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    ObjectToObjectMap&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Animal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Presenter&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; actualPresenters&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ComposedPresenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ObjectToObjectMap&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Animal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Presenter&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; actualPresenters&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;actualPresenters &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; actualPresenters&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;introduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Animal a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; UnableToIntroduce
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;actualPresenters&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getValueBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;introduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;UnableToGetValue&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UnableToIntroduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;%s doesn&apos;t contain any presenter for %s&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token function&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCanonicalName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCanonicalName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let me explain what&apos;s going on here. First of all, while building the &lt;em&gt;ComposedPresenter&lt;/em&gt;, we provide an &lt;em&gt;ObjectToObjectMap&lt;/em&gt; which given an &lt;em&gt;Animal&lt;/em&gt; gives a &lt;em&gt;Presenter&lt;/em&gt; supposed to introduce it.&lt;/p&gt;
&lt;p&gt;Then, when the &lt;em&gt;introduce&lt;/em&gt; method is called, we try to call it on the actual presenter fetched from the &lt;em&gt;actualPresenters&lt;/em&gt; map. If nothing is found, a suitable exception matching the &lt;em&gt;Presenter&lt;/em&gt; interface is thrown.&lt;/p&gt;
&lt;p&gt;Now instead of limiting ourselves to just this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;Presenter presenter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CatPresenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;Presenter presenter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CowPresenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can get both:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;Presenter presenter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ComposedPresenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ExactClassBasedMap&lt;/span&gt;&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Animal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Presenter&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;associate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CatPresenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;associate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CowPresenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now the code that uses the &lt;em&gt;Presenter&lt;/em&gt; may pass a different &lt;em&gt;Animal&lt;/em&gt; to it without using a separated method like &lt;em&gt;introduceCow&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;The final code&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;Presenter presenter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ComposedPresenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ExactClassBasedMap&lt;/span&gt;&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Animal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Presenter&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;associate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CatPresenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;associate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Cow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CowPresenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

Animal&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; animals &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Animal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Mr. Meower&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Lady Mooer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Animal oneAnimal&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; animals&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;presenter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;introduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;oneAnimal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;UnableToIntroduce&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//failure handling code goes here&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Getting closer to the deadly diamond of death&lt;/h3&gt;
&lt;p&gt;We&apos;ve connected the &lt;em&gt;CatPresenter&lt;/em&gt; with objects of the &lt;em&gt;Cat&lt;/em&gt; class. If there were &lt;em&gt;DomesticCat&lt;/em&gt;s, they wouldn&apos;t be introduced, because the  &lt;em&gt;ObjectToObjectMap&lt;/em&gt; implementation used in this example - &lt;em&gt;ExactClassBasedMap&lt;/em&gt; - doesn&apos;t support inheritance. When picking some that does, we need to answer a very important question - which &lt;em&gt;Presenter&lt;/em&gt; should be used, if there are few matching the given &lt;em&gt;Animal&lt;/em&gt;? The recently associated one? Or maybe the one somehow considered the closest one in the inheritance hierarchy? What if the &lt;em&gt;introduce&lt;/em&gt; method looked like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;introduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    Animal newAnimal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Animal toAnimal
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; UnableToIntroduce&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And we had two dispatchers: one for introducing a &lt;em&gt;Cat&lt;/em&gt; to a &lt;em&gt;DomesticCat&lt;/em&gt; and another for introducing a &lt;em&gt;DomesticCat&lt;/em&gt; to a &lt;em&gt;Cat&lt;/em&gt;? If we pass two &lt;em&gt;DomesticCat&lt;/em&gt;s to it, two &lt;em&gt;Presenter&lt;/em&gt;s match. There&apos;s no one correct answer to this question. How do we solve this problem depends on the logic of our application. For example, in Clojure we could use the &lt;em&gt;prefer-method&lt;/em&gt; function to tell that the function introducing &lt;em&gt;Cat&lt;/em&gt;s to &lt;em&gt;DomesticCat&lt;/em&gt;s is preferred over the one introducing &lt;em&gt;DomesticCat&lt;/em&gt;s to &lt;em&gt;Cat&lt;/em&gt;s.&lt;/p&gt;
&lt;h3&gt;It&apos;s not a free lunch&lt;/h3&gt;
&lt;p&gt;Introducing additional dispatch logic, often based on many parameters, comes with a price in performance. Depending on the exact implementation of the dispatching function, the performance may vary, but it will always be a little bit slower. However, before avoiding this approach in the name of performance, a measurement should be done. Maybe greater modularity and simpler code are worth it?&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Unnecessary IF statements]]></title><link>https://coder.earth/post/less-if</link><guid isPermaLink="false">https://coder.earth/post/less-if</guid><pubDate>Sat, 17 Sep 2016 22:37:20 GMT</pubDate><content:encoded>&lt;p&gt;Making decisions is important. We cannot run from them. What we can is to don&apos;t make decisions that have already been made by us or others.&lt;/p&gt;
&lt;p&gt;In this very short article I&apos;d like to share with you three ways, how can we avoid writing unnecessary IF statements. Those hints are so simple that it&apos;s even hard to believe how helpful they may be.&lt;/p&gt;
&lt;p&gt;But why actually is it a good idea to avoid IF statements? Like many other things, they introduce some complexity and increase the risk of making a mistake. Even though it&apos;s very easy to write and understand them, when done hundreds of times, may be done incorrectly. Believe me or not, I&apos;ve seen a security issue caused by an unnecessary IF statement that could be totally removed without any further changes in the code!&lt;/p&gt;
&lt;h1&gt;(boolean? true : false) == boolean&lt;/h1&gt;
&lt;p&gt;Let&apos;s assume we need a method that tells us whether something weights more than the given value.
The craziest example I can think of looks like that:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;isHeavierThan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; kilos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;boolean&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;weightInKilos &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; kilos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;weightInKilos &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; kilos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Of course most of the time in a real code it doesn&apos;t look that bad. What may be seen definitely more often is:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;isHeavierThan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; kilos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;weightInKilos &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; kilos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or it&apos;s shorter version:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;isHeavierThan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; kilos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;weightInKilos &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; kilos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now this IF is much shorter, but still present. It means that it may still be written incorrectly, like that:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;isHeavierThan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; kilos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;weightInKilos &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; kilos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fortunately the way to get rid of it completely is dead simple, as all what we do here is returning the exact result of a comparison:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;isHeavierThan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; kilos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; weightInKilos &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; kilos&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It still does exactly what the first version does, but without a variable with 3 assignments and 2 conditional statements.&lt;/p&gt;
&lt;h1&gt;Null is not an empty collection&lt;/h1&gt;
&lt;p&gt;A name displaying screen sounds like a great thing!&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;Collection&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; names &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ArrayList&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
names&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Katie&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
names&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

screen&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;names&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Perfect! We&apos;ve just displayed two names. But how do we tell the screen that we don&apos;t want to display anything without modifying the code that actually makes the call to the &quot;display&quot; method? Can it be a null value?&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;Collection&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; names &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; null&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

screen&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;names&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It may work, but what&apos;s the cost? Now in the &quot;display&quot; method, right before actually printing our names, we must check if the given parameter is not a null value.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Collection&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; names&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;null &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; names&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;String singleName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; names&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;singleName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If we try to remove this null checking...&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Collection&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; names&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;String singleName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; names&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;singleName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;... it looks much nicer, but then: NullPointerException!
Isn&apos;t there a way to escape that hell? Of course there is and it&apos;s actually quite simple. Before we write the final solution, let&apos;s think about something. If we want to display 3 names, we pass a collection of 3 names as the parameter. If we want to display 2 names, we pass a collection of 2 names. How does that differ, then, from displaying 1 or 0 names? Well, it doesn&apos;t.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;Collection&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; names &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Collections&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;emptyList&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

screen&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;names&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Passing an empty list when we expect no names to be printed saves the screen from checking if the given collection is actually a collection and not a null.&lt;/p&gt;
&lt;p&gt;Unfortunately Java doesn&apos;t stop us from passing there a null, but the good thing is that there&apos;re great tools like the &lt;a href=&quot;http://checkerframework.org/&quot;&gt;Checker Framework&lt;/a&gt; which are extremely helpful in eliminating null pointers, as they make them appear during the compile time.&lt;/p&gt;
&lt;h1&gt;Let&apos;s meet Mr. Unknown - Null Object&lt;/h1&gt;
&lt;p&gt;In this example we&apos;re going to ask people their name.
Our model of a person is very simple:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Person&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can also look for somebody using the repository of people:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonRepository&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; Person &lt;span class=&quot;token function&quot;&gt;getBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For presentation purposes, the fake repository may be written this way:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FakePersonRepo&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonRepository&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; Map&lt;span class=&quot;token generics function&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Integer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Person&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; people &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HashMap&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;FakePersonRepo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        people&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonImpl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Katie&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        people&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonImpl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; Person &lt;span class=&quot;token function&quot;&gt;getBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; people&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;containsKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; people&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; null&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It holds two people with id 2 and 7 and returns a null value if nobody is found. Now if we want to use this repository to display somebody&apos;s name or some default text in case a person like that doesn&apos;t exist, we can write it this way:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;Person foundPerson &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; people&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
String foundPersonName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;null &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; foundPerson&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; foundPerson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Mr. Unknown&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Depending on our application, it may soon turn out that this fragment of code is repeated over and over again. It&apos;s a good moment to consider introducing the Special Case/Null Object design pattern. One thing we cannot forget about is that the previous two examples were about removing IF statements that were unnecessary at all, while this one is about moving it to a different place and avoiding repetition.&lt;/p&gt;
&lt;p&gt;If every single time, when nobody is found, &quot;Mr. Unknown&quot; becomes the name that is actually used later in our app, it looks like there&apos;s a hidden object representing nobody.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;NullPerson&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Person&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; String &lt;span class=&quot;token function&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Mr. Unknown&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What in the case of our very simple model doesn&apos;t even need to be a separated class, as we can use an instance built this way:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonImpl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Mr. Unknown&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then our repository, when nobody is found, returns this special object instead of a null value.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; Person &lt;span class=&quot;token function&quot;&gt;getBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; people&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;containsKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; people&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonImpl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Mr. Unknown&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now when writing some code that uses the repository of people we can write the following fragment and be sure that it&apos;s going to work regardless somebody is actually found:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;String foundPersonName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; people&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By doing that, we moved some logic from the client code into the repository and made the client code unaware of somebody&apos;s presence. Sometimes it may be a great idea, but it&apos;s definitely nothing that may be applied everywhere without considering pros and cons of using it in some particular application. If there are 20 places in the code where a person is read from the repository and then the same action is performed if nobody is found, it&apos;s a job for the Special Case pattern. On the other hand, if sometimes &quot;Mr. Unknown&quot; is displayed, sometimes no table row is rendered and sometimes an error message pops up, this pattern is useless, because the client code needs to know whether somebody is found. However, if there are tens of cases it matches and just one when we really need to know whether somebody is found, an interesting solution is to make the special case object a Singleton and then check if the returned person is exactly that instance. Even though it&apos;s probably the only use case of the Singleton pattern that doesn&apos;t seem to be a terrible crime, I suggest being very careful with that, especially if the special case object is not very simple or if there&apos;s a chance we will need more than one null object.&lt;/p&gt;
&lt;p&gt;I hope you liked this article. It makes me very happy if you find some of those hints useful! It&apos;s almost a direct transcription of my youtube video &lt;a href=&quot;https://www.youtube.com/watch?v=uBT1B7qUwcs&quot;&gt;&quot;One less IF&quot;&lt;/a&gt; so if you&apos;re interested in a video version, feel free to check it out!&lt;/p&gt;</content:encoded></item></channel></rss>