<?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" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Between The River and The Software]]></title><description><![CDATA[Uncovering philosophies and research behind Software and its Makers.]]></description><link>https://www.riverandsoftware.com</link><image><url>https://substackcdn.com/image/fetch/$s_!YX7R!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf41b42e-9aad-40c0-b442-8cff77f55a4c_500x500.png</url><title>Between The River and The Software</title><link>https://www.riverandsoftware.com</link></image><generator>Substack</generator><lastBuildDate>Fri, 08 May 2026 10:56:20 GMT</lastBuildDate><atom:link href="https://www.riverandsoftware.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[PartNest]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[riverandsoftware@partnest.io]]></webMaster><itunes:owner><itunes:email><![CDATA[riverandsoftware@partnest.io]]></itunes:email><itunes:name><![CDATA[Nayab Siddiqui]]></itunes:name></itunes:owner><itunes:author><![CDATA[Nayab Siddiqui]]></itunes:author><googleplay:owner><![CDATA[riverandsoftware@partnest.io]]></googleplay:owner><googleplay:email><![CDATA[riverandsoftware@partnest.io]]></googleplay:email><googleplay:author><![CDATA[Nayab Siddiqui]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Decisions: Rational, Right.]]></title><description><![CDATA[Decisions Can Be Right Without Being Rational, and Rational Without Being Right. While being rational is somewhat in our hands, getting the decisions right is certainly not.]]></description><link>https://www.riverandsoftware.com/p/decisions-rational-right</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/decisions-rational-right</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Wed, 15 Nov 2023 05:24:48 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!D8ts!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b683d31-1ef3-447a-a144-e516b3853527_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Decisions Can Be Right Without Being Rational, and Rational Without Being Right.</h2><blockquote><p><em>In the battle of Narva (on the border between Russia and what we now call Estonia) on November 20, 1700, King Carl of Sweden and his 8,000 troops attacked the Russian army, led by Tsar Peter the Great. The tsar had about ten times as many troops at his disposal. Most historians agree that the Swedish attack was irrational, since it was almost certain to fail. Moreover, the Swedes had no strategic reason for attacking; they could not expect to gain very much from victory. However, because of an unexpected blizzard that blinded the Russian army, the Swedes won. The battle was over in less than two hours. The Swedes lost 667 men and the Russians approximately 15,000.</em></p><p>&#8212; <a href="https://www.goodreads.com/book/show/11729796">Martin Peterson. 2009. An Introduction to Decision Theory</a>.</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!D8ts!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b683d31-1ef3-447a-a144-e516b3853527_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!D8ts!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b683d31-1ef3-447a-a144-e516b3853527_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!D8ts!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b683d31-1ef3-447a-a144-e516b3853527_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!D8ts!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b683d31-1ef3-447a-a144-e516b3853527_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!D8ts!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b683d31-1ef3-447a-a144-e516b3853527_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!D8ts!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b683d31-1ef3-447a-a144-e516b3853527_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7b683d31-1ef3-447a-a144-e516b3853527_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2315389,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!D8ts!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b683d31-1ef3-447a-a144-e516b3853527_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!D8ts!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b683d31-1ef3-447a-a144-e516b3853527_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!D8ts!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b683d31-1ef3-447a-a144-e516b3853527_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!D8ts!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b683d31-1ef3-447a-a144-e516b3853527_1536x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Battle of Narva, 1700. Imagined using Midjourney.</figcaption></figure></div><p>Sweden army didn&#8217;t have any good reason to attack a significantly outnumbered Russian army. It didn't predict a blizzard which would significantly up their chances of winning. Yet, it attacked. It is easy to see that their decision to attack wasn't a well informed one; an act of valour maybe, but definitely not a rational one. But despite the irrational decision, the outcome turned out to be the most favourable one for the Sweden army &#8212; they won! </p><p>So an irrational decision turned out to be right, but certainly, a rational decision has to be right!</p><p>Software development is much more than just writing code. There are meetings to be attended, work to be prioritised, documentation to be kept up to date, customers to be spoken with, new teammates to be onboarded, other teams to be collaborated with, dependencies to be managed etc. etc. &#8212; aka the &#8220;glue work&#8221;. The importance of glue work is indispensable, and its impact is significant. This underscores the crucial role that a good manager plays in the team. It is rational for one to keep picking up the glue work from time to time and keep the team moving forward. Counterintuitively, it can be a severe career limiting decision when you&#8217;re a junior. In her excellent talk, Tanya Reilly captures this &#8220;<strong><a href="https://noidea.dog/glue">Glue work is expected when you&#8217;re a senior, and risky when you&#8217;re not</a></strong>&#8221; phenomena brilliantly. When you&#8217;re a junior, and you concentrate on glue work more than technical tasks, the appraisers tend to interpret either that you&#8217;re less technical or that you&#8217;re more managerial material. Either ways, in their eyes you&#8217;re less of &#8220;an engineer&#8221; and more of &#8220;a manager&#8221;. Your promotion will be impacted because of this. This is great if management was more appealing to you in the first place, otherwise the rational choice of doing glue work has proven to be a wrong one. This is an interesting thing to notice &#8212; a choice which is rational for one person (the junior) is an irrational one for the other (the junior&#8217;s appraiser).</p><h2></h2><div><hr></div><h2>Rationality</h2><p>Decisions seem right or wrong after the fact, depending upon whether the outcome is a favourable one or not<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a>. This temporal relation between taking a decision and observing its outcome, makes it impossible to know upfront whether a decision is going to be the right one. But, what can be said about the time when we are about to make the decision? What about the rationality of our decisions? That is pre-hoc analysis. </p><p>Most of us have an intuition about what rationality is. If there&#8217;s a forecast about 70% chance of rain, it is rational to carry an umbrella with you before you step outside. It would be irrational not to. Whether it actually rained that day and you could use your umbrella to protect yourself is post-hoc. Similarly, if you prefer apple over orange, and orange over banana, it would be irrational to choose a banana when a juicy apple was lying there in your fruit basket<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a>. Generally speaking, we have an aim &#8212; to not get wet, to enjoy a fruit, to get a promotion, to be recognised. Rationality will be the act of choosing the decision(s) which puts us in the most optimal path to achieve our aim. This &#8220;means to an end&#8221; notion of rationality, without surprise, is criticised throughout the literature, for instance if your aim is to get rich and you steal<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self">3</a>. </p><div class="pullquote"><p>Our primary concern should be about making rational decisions rather than the right ones.</p></div><p>We could also say that rationality is choosing an act (from all possible available acts) which <em>maximises the value </em>we receive from the outcome. </p><p>&#8220;Writing tests will take us longer, let&#8217;s stop for the time being and get the release out first. If we don&#8217;t have a release, if we don&#8217;t have the users using it, what is even the point of these tests?&#8221;. There goes testing out of the window! &#8220;Vulnerability checks are time consuming, let&#8217;s hold on till the release. If we don&#8217;t have a release, if we don&#8217;t have the user using it, what is even the point of having a secure software?&#8221; There goes security out of the window! &#8220;We can&#8217;t take on tech-debt right now. If we don&#8217;t have a release, if we don&#8217;t have the user using it, what is even the point of having a maintainable software?&#8220; And all the tech-debts were surely addressed after the release!?! Quite a few times such decisions turn out to be right<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-4" href="#footnote-4" target="_self">4</a>. In most of the other cases, we minimise our optionality for future and end up regressing. &#8220;why are we not going any faster? &#8212; because there are regression failures&#8221;. &#8220;Why are there regression failures? &#8212; because we don&#8217;t have tests!&#8221;.</p><h2></h2><div><hr></div><h2>Bounded Rationality.</h2><p>We know that humans make irrational decisions under <a href="https://www.goodreads.com/book/show/11468377">bias</a>, and sometimes quite <a href="https://www.goodreads.com/book/show/1713426">predictably</a> so. We make quite reasonable decisions based on the information we have, but our holistic information is itself limited &#8212; either we miss the feedback from distant yet related part of the system, or the feedback itself is delayed, or we deny the information itself because it is dissonant with our mental model.</p><p>Most systemic failures happen because of our bounded rationality<strong><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-5" href="#footnote-5" target="_self">5</a></strong>. For instance, in <a href="https://www.researchgate.net/publication/8150380_A_Typology_of_Organisational_Cultures">Westrum&#8217;s bureaucratic and pathological organisations</a>, it is most rational to withhold the information pertaining to failures; because either you will be punished or the department will justify its act and ignore the information (read sweep under the rug). One is still <em>maximising the expected value</em>, it&#8217;s just that what might be best for the individual turns out not to be so good for the whole organisation. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ty_W!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33c1fe54-3de4-415e-9415-8139ded329d3_843x484.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ty_W!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33c1fe54-3de4-415e-9415-8139ded329d3_843x484.png 424w, https://substackcdn.com/image/fetch/$s_!ty_W!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33c1fe54-3de4-415e-9415-8139ded329d3_843x484.png 848w, https://substackcdn.com/image/fetch/$s_!ty_W!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33c1fe54-3de4-415e-9415-8139ded329d3_843x484.png 1272w, https://substackcdn.com/image/fetch/$s_!ty_W!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33c1fe54-3de4-415e-9415-8139ded329d3_843x484.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ty_W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33c1fe54-3de4-415e-9415-8139ded329d3_843x484.png" width="843" height="484" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/33c1fe54-3de4-415e-9415-8139ded329d3_843x484.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:484,&quot;width&quot;:843,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:89695,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ty_W!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33c1fe54-3de4-415e-9415-8139ded329d3_843x484.png 424w, https://substackcdn.com/image/fetch/$s_!ty_W!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33c1fe54-3de4-415e-9415-8139ded329d3_843x484.png 848w, https://substackcdn.com/image/fetch/$s_!ty_W!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33c1fe54-3de4-415e-9415-8139ded329d3_843x484.png 1272w, https://substackcdn.com/image/fetch/$s_!ty_W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33c1fe54-3de4-415e-9415-8139ded329d3_843x484.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">R. Westrum. 2004. A Typology of Organisational Cultures.</figcaption></figure></div><p>This highlights an important (obvious when sighted, yet overlooked most of the times) aspect of decision making &#8212; the leverage points<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-6" href="#footnote-6" target="_self">6</a>. The reason leverage points become so integral to decision making is because most of our decisions are influenced by culture, and change over time and across cultures. <strong>Rationality of decisions at the pivotal leverage points, then, becomes the prime directive.</strong> No good amount of policies or practices (read post-mortems, retrospectives, root-cause analysis etc.) is impactful enough to bring about a considerable change until the organisation learns how to embrace the information around failures, unless the organisation treats its mission as the most important thing above everything else, unless the organisation <em>has</em> a mission to begin with!</p><p></p><div><hr></div><h2>Closing thoughts</h2><p>Surely not all decision types are the same, because circumstances are not the same. For some decisions the outcome is quite <strong>certain</strong>. For instance, if you drop an apple from a tree, it will fall to the ground (how poetic!). In other cases, we know of all possible outcomes and their chances (probability), yet the final outcome is unknown. For e.g. tossing a coin &#8212; we know that in an unbiased coin, there is a 50% chance of a toss resulting in a heads and 50% chance of it turning out to be tails, yet the final outcome can only be determined after the toss. These are decisions under <strong>risk. </strong>Yet, there is another class of decisions where we know all the possible outcomes, but don't know their respective probabilities. For e.g. going to a new restaurant (so no reviews are available) and wanting to try out an exquisite dish &#8212; we know that if the chef is really good the dish will be a treat, and if the chef is not, the dish will turn out to be a disaster. But we don't know what are the chances of either of the outcomes. These are decisions under <strong>uncertainty</strong>. Quite a lot of decisions in our day to day life/work are of the risky and uncertain kind. </p><p>The normative techniques of taking rational decisions under risk differ from those under uncertainty. (I wish to cover them in subsequent articles.) Our heuristics and bounded rationality might not make us perfect decision making machines, and one might argue about the importance of studying normative methods of decision theory. To that I will leave the readers with a quote from <a href="https://www.goodreads.com/book/show/11729796">Peterson (2009)</a>: </p><blockquote><p>&#8220;<em>Anyone wishing to know what makes a rational decision rational should study normative decision theory. How people actually behave is likely to change over time and across cultures, but a sufficiently general normative theory can be expected to withstand time and cultural differences.</em>&#8221;</p></blockquote><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! &#128588; If you like what I write and would like to see more such articles, why not subscribe! &#128522;</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>Note that sometimes we use &#8220;<em>right</em>&#8221; to refer to a rational decision, for e.g., it is the right thing to carry an umbrella when the meteorological department has predicted high chances of rain. However, here I&#8217;m strictly classifying <em>right vs wrong</em> based on the <em>outcome</em> of decision, and <em>rational vs irrational</em> for the <em>act</em> of making a decision.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self">2</a><div class="footnote-content"><p>These are some examples of how a <a href="https://en.wikipedia.org/wiki/Von_Neumann&#8211;Morgenstern_utility_theorem#:~:text=In%20decision%20theory%2C%20the%20von,over%20the%20potential%20outcomes%20at">VNM-rational agent</a> would act.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-3" href="#footnote-anchor-3" class="footnote-number" contenteditable="false" target="_self">3</a><div class="footnote-content"><p>This notion of &#8220;means to an end&#8221; rationality is called <a href="https://en.wikipedia.org/wiki/Instrumental_and_value_rationality">instrumental rationality</a>. It is also argued that morality is different from rationality. So what might be an immoral thing to do, like steal from others, it might be rational for the thief since it maximises the most favourable outcome for him &#8212; to get rich. The aim itself is outside of the realm of decision theory and most decision theorists are interested in how we make the decision rather than what the aim is. <a href="https://www.goodreads.com/book/show/11729796">Peterson (2009)</a> quotes another criticism of instrumental rationality: &#8220;<em>Philosopher John Rawls argues that an aim such as counting the number of blades of grass on a courthouse lawn is irrational, at least as long as doing so does not help to prevent terrible events elsewhere. Counting blades of grass on a courthouse lawn is not important enough to qualify as a rational aim. In response to this point it could perhaps be objected that everyone should be free to decide for herself what is important in life. If someone strongly desires to count blades of grass on courthouse lawns, just for the fun of it, that might very well qualify as a rational aim.</em>&#8221;</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-4" href="#footnote-anchor-4" class="footnote-number" contenteditable="false" target="_self">4</a><div class="footnote-content"><p>Especially in the cases when product is yet to find its market value (PMF) or you&#8217;re working on an MVP to evaluate your hypothesis and are quite sure that the code you're writing is not production quality and will have to be rewritten.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-5" href="#footnote-anchor-5" class="footnote-number" contenteditable="false" target="_self">5</a><div class="footnote-content"><p>Bounded rationality is a concept proposed by Herbert A. Simon, an American political scientist, in his 1957 book &#8220;<a href="https://www.goodreads.com/book/show/7302177">Models of Man</a>&#8221;. Simon noted that we&#8217;re not omniscient, rational optimisers. Rather we are blundering &#8220;<em>satisficers</em>&#8221;, attempting to meet (<em>satisfy</em>) our needs well enough (<em>sufficiently</em>) before moving on to the next decision.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-6" href="#footnote-anchor-6" class="footnote-number" contenteditable="false" target="_self">6</a><div class="footnote-content"><p>There are several leverage points in a system. Culture and paradigms (mental models) are among the most impactful leverage points. And counterintuitively, people are quite below the list. Primarily because replacing people doesn&#8217;t change the system as much. Although, certain change of people is more impactful than other (for e.g. change in leadership), but still the underlying skeleton of system is difficult to be influenced at this level. </p></div></div>]]></content:encoded></item><item><title><![CDATA[Programming as Theory Building. Peter Naur.]]></title><description><![CDATA[A program is not just its source code. It is a shared mental construct that lives in the minds of the people that work on it. The code is merely a written representation of the program and is lossy.]]></description><link>https://www.riverandsoftware.com/p/programming-as-theory-building-peter-naur</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/programming-as-theory-building-peter-naur</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Sat, 26 Aug 2023 07:16:26 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/98aeae33-e3d8-4fe8-a5ac-a6f419d0e6ce_513x366.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p> In his seminal paper &#8220;<a href="https://pablo.rauzy.name/dev/naur1985programming.pdf">Programming as Theory Building</a>&#8221; published in 1985, <a href="https://en.wikipedia.org/wiki/Peter_Naur">Peter Naur</a> set out to posit that a program is not its source code and cannot be reduced to it. A program is a shared mental construct (referred to as &#8220;theory of the program&#8221; by Naur) which lives in the minds of people who work on it. The code of a program is just a written representation of this theory, and is lossy. It&#8217;s lossy in the sense that theory of the program cannot be rebuild completely only from the code, documentation, and other artefacts, without the presence of developers who worked on the program. These artefacts are necessary but not sufficient. When you lose all the developers who had the theory, it is &#8220;the death of the program&#8221;. Naturally, for a new team member to gain this theory s/he has to work closely alongside the existing developers.</p><p>Naur&#8217;s primary motivation for proposing the building of shared mental construct is to give deeper insight into how it influences the modifications in any software &#8212;<em> &#8220;A prominent reason for proposing the Theory Building View of programming is the desire to establish an insight into programming suitable for supporting a sound understanding of program modifications.&#8221;</em></p><p>Naur&#8217;s idea of &#8220;theory of a program&#8221; is influenced by idea of &#8220;theory building&#8221; and &#8220;theorising&#8221; from <a href="https://en.wikipedia.org/wiki/Gilbert_Ryle">Ryle</a>&#8217;s work in his book <a href="https://www.goodreads.com/book/show/695125.The_Concept_of_Mind">The Concept of Mind</a>. I&#8217;m quite fascinated by the concepts of &#8220;theory&#8221;, &#8220;theory-building&#8221;, and &#8220;theorising&#8221;. I had read the paper earlier, but rereading it after having read &#8220;The Concept of Mind&#8221; presented it in a different light for me. Naturally, I&#8217;ll concentrate more on these meta concepts in this article. To have a better appreciation of Naur&#8217;s thoughts in his paper, I&#8217;ll also present some parts from Ryle&#8217;s book pertaining to the concepts of &#8220;theory&#8221; and &#8220;theorising&#8221; (or &#8220;theory building&#8221;).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LZL1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b42e0f2-2564-4ed7-8661-e1f4352784b8_260x400.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LZL1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b42e0f2-2564-4ed7-8661-e1f4352784b8_260x400.jpeg 424w, https://substackcdn.com/image/fetch/$s_!LZL1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b42e0f2-2564-4ed7-8661-e1f4352784b8_260x400.jpeg 848w, https://substackcdn.com/image/fetch/$s_!LZL1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b42e0f2-2564-4ed7-8661-e1f4352784b8_260x400.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!LZL1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b42e0f2-2564-4ed7-8661-e1f4352784b8_260x400.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LZL1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b42e0f2-2564-4ed7-8661-e1f4352784b8_260x400.jpeg" width="354" height="544.6153846153846" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4b42e0f2-2564-4ed7-8661-e1f4352784b8_260x400.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:260,&quot;resizeWidth&quot;:354,&quot;bytes&quot;:17192,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LZL1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b42e0f2-2564-4ed7-8661-e1f4352784b8_260x400.jpeg 424w, https://substackcdn.com/image/fetch/$s_!LZL1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b42e0f2-2564-4ed7-8661-e1f4352784b8_260x400.jpeg 848w, https://substackcdn.com/image/fetch/$s_!LZL1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b42e0f2-2564-4ed7-8661-e1f4352784b8_260x400.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!LZL1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b42e0f2-2564-4ed7-8661-e1f4352784b8_260x400.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">book cover of &#8220;The Concept of Mind&#8221; by Gilbert Ryle</figcaption></figure></div><div><hr></div><h2>Theory and Theory-Building</h2><p>An intelligent act is different from an unintelligent one. While a task can be done well by just adhering to certain criteria or following a set of rules, like looking both ways before crossing a street, it doesn&#8217;t necessarily qualify as an intelligent one. One could precisely follow the intricate recipes of <a href="https://www.reynoldpoernomo.com.au/about">Reynold Poernomo</a> and succeed in recreating his signature desserts, but that alone does not qualify as intelligent cooking. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Dfgl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb45a32-e2e9-4ab9-9b50-a58af7ed614a_1706x2560.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Dfgl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb45a32-e2e9-4ab9-9b50-a58af7ed614a_1706x2560.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Dfgl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb45a32-e2e9-4ab9-9b50-a58af7ed614a_1706x2560.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Dfgl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb45a32-e2e9-4ab9-9b50-a58af7ed614a_1706x2560.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Dfgl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb45a32-e2e9-4ab9-9b50-a58af7ed614a_1706x2560.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Dfgl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb45a32-e2e9-4ab9-9b50-a58af7ed614a_1706x2560.jpeg" width="386" height="579.2651098901099" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ddb45a32-e2e9-4ab9-9b50-a58af7ed614a_1706x2560.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2185,&quot;width&quot;:1456,&quot;resizeWidth&quot;:386,&quot;bytes&quot;:370018,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Dfgl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb45a32-e2e9-4ab9-9b50-a58af7ed614a_1706x2560.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Dfgl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb45a32-e2e9-4ab9-9b50-a58af7ed614a_1706x2560.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Dfgl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb45a32-e2e9-4ab9-9b50-a58af7ed614a_1706x2560.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Dfgl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb45a32-e2e9-4ab9-9b50-a58af7ed614a_1706x2560.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Reynold Poernomo. Credit <a href="https://www.koidessertbar.com.au/">KOI Dessert Bar</a></figcaption></figure></div><p>Ryle analysed that an intelligent performance is more than just being able to do an activity well according to some criteria. A person able to perform an act intelligently would not only be able to apply the criteria, but also be able to identify and rectify errors, iterate and enhance accomplishments, gain insights from his own and others' experiences, and more.</p><blockquote><p>&#8220;<em>The well-regulated clock keeps good time and the well-drilled circus seal performs its tricks flawlessly, yet we do not call them &#8216;intelligent&#8217;. We reserve this title for the persons responsible for their performances. To be intelligent is not merely to satisfy criteria, but to apply them; to regulate one&#8217;s actions and not merely to be well-regulated. A person&#8217;s performance is described as careful or skilful, if in his operations he is ready to detect and correct lapses, to repeat and improve upon successes, to profit from the examples of others and so forth. He applies criteria in performing critically, that is, in trying to get things right.</em>&#8221;</p><p>&#8212; <em><a href="https://www.goodreads.com/book/show/695125.The_Concept_of_Mind">Gilbert Ryle. 1949. The Concept of Mind</a></em></p></blockquote><p>An intelligent behaviour transcends following rules of some kind. For if there are rules on how to perform an activity intelligently, there will have to be a set of rules on how to effectively follow the rules, and then another set of rules on how to follow the following of rules and so on. An infinite regression! </p><p></p><h3>&#8220;<strong>Knowing That&#8221; is not the same as &#8220;Knowing How&#8221;</strong></h3><blockquote><p><em>&#8220;What characterises intellectual activity, over and beyond activity that is merely intelligent, is the person&#8217;s building and having a theory, where theory is understood as the knowledge a person must have in order not only to do certain things intelligently but also to explain them, to answer queries about them, to argue about them, and so forth. A person who has a theory is prepared to enter into such activities; while building the theory the person is trying to get it.&#8221;</em></p><p><em>&#8212; <a href="https://pablo.rauzy.name/dev/naur1985programming.pdf">Peter Naur. 1985. Programming as Theory Building</a></em></p></blockquote><p>&#8220;Knowing that&#8221; is the knowledge of or knowing a theory. &#8220;Knowing how&#8221; is the ability to be able to apply the theory within the given context. &#8220;Knowing that&#8221; will be knowing Newton&#8217;s laws of motion, to be able to state them, to be able to write their equations fluently and to be able to derive them even. &#8220;Knowing how&#8221; or &#8220;having the theory&#8221; of Newton&#8217;s laws would be to have the ability to identify which category of reality belong to classical mechanics so as to be able to apply the laws of motion effectively. &#8220;A person having Newton&#8217;s theory of mechanics must thus understand how it applies to the motions of pendulums and the planets, and must be able to recognise similar phenomena in the world, so as to be able to employ the mathematically expressed rules of the theory properly.&#8221;</p><blockquote><p><em>&#8220;Newton&#8217;s theories were used when correct predictions and retrodictions were made on the basis of them, when machines were designed in accordance with them, when the hope of building perpetual-motion machines was given up, when some other theories were abandoned, or else were codified with his, when books were produced and lectures delivered enabling students to grasp the whole or parts of his theories and, lastly, when some or all of his theory-building techniques were learned from his example and successfully applied in new investigations. To be a Newtonian was not just to say what Newton had said, but also to say and do what Newton would have said and done. &#8221;</em></p><p>&#8212; <em><a href="https://www.goodreads.com/book/show/695125.The_Concept_of_Mind">Gilbert Ryle. 1949. The Concept of Mind</a></em></p></blockquote><p>Frequently, the mastery of "knowing how" relies upon a foundation of "knowing that." Achieving proficiency in TDD, for instance, necessitates grasping the sequential red, green, and refactor steps. Yet, a mere grasp of these stages might prove insufficient, as true effectiveness in TDD requires an intellectual capacity to comprehend contextual criteria and significance at a higher level than others. It is one thing to be able to write tests and another to reason that we should not test private methods. It is one thing to learn how to mock and another to know when not to and use stubs instead. This transition from factual knowledge ("knowing that") to practical mastery ("knowing how") embodies the process of building a theory for oneself. Once one has his theory solidified, he attains a deeper contextual understanding, enabling him to apply the theory with discernment.</p><p></p><div><hr></div><h2>The Theory To Be Built By The Programmer</h2><p>In terms of Ryle&#8217;s notion of theory, the developer has to build a theory about how certain aspects and functions of the real world are to be handled by the program that has to be written. Programming as a whole encompasses many activities, but not limited to, starting with understanding of the real world problem that the program is intended to map and solve, designing, implementation, deployment, maintenance and enhancement of the software. </p><p>Programming then, has to be about knowledge that is beyond just knowing how to write idiomatic code or knowing about different patterns of asynchronous communication in a distributed system. It must have the knowledge about the real-world use case, and how to map the business rules effectively in the code. It has to do with reasoning about how to design the system to be able to incorporate future modifications as they come, and more importantly also to be able to rationalise when a future extensibility is wishful thinking. </p><p>According to Naur, the knowledge possessed by the programmer by virtue of his/her having the theory of the program transcends any artefacts like the source code, documentation, diagrams etc. in at least the following three areas:</p><ol><li><p>The programmer having the theory of the program can explain how the solution relates to the affairs of the world that it helps to handle. By far the largest part of the world aspects and activities will of course lie outside the scope of the program text, being irrelevant in the context. However, the decision that a part of the world is relevant can only be made by someone who understands the whole world. This understanding must be contributed by the programmer.</p></li><li><p>The programmer having the theory can explain decisions like why a certain approach was taken over the other, why a certain class or set of classes were designed in a way and not the other way, why synchronous communication was preferred over asynchronous and much more. </p></li><li><p>The programmer having the theory of the program is able to respond constructively to any demand for a modification of the program so as to support the affairs of the world in a new manner. Designing how a modification is best incorporated into an established program depends on the perception of the similarity of the new demand with the operational facilities already built into the program. The kind of similarity that has to be perceived is one between aspects of the world. It only makes sense to the agent who has knowledge of the world, that is to the programmer, and cannot be reduced to any limited set of criteria or rules, for reasons similar to the ones given above why the justification of the program cannot be thus reduced.</p><p></p></li></ol><div><hr></div><h2>What Theory Is Not, Theorising Is</h2><p>To get a real appreciation of why the theory of the program, held by the developers, has a primacy over other artefacts, we need to understand how we generally build our theories (or how we theorise) and then later describe our theories through some written or verbal discourse. </p><p>The transition from theorising to putting our theories in didactic fashion is a transition from non-linear thinking to a linear output, and is lossy. When we are theorising, we&#8217;re going through the process of assuming, hypothesising, criticising, conjecturing, proposing. This is mostly a non-linear process. When we later intend to explain our theories through verbal or written mediums we tend to linearise this vision. Imagine the transition between when you are brainstorming on a white board or making a mind-map &#8212; a non-linear representation, and then later when you summarise and put forth the outcome in some sort of documentation &#8212; a linear representation. This transition is bound to be lossy. When we whiteboard a systems design, we present our worldview of the problem statement, we put forth our knowledge, run through different scenarios and challenge each other's hypothesis. We can do our very best to capture these transitions, but it can never capture the theorising process in entirety.</p><p>Karl Weick argues that <a href="http://crts.bilkent.edu.tr/readings_2015/weick.pdf">theories are a continuum and not a dichotomy</a>. A software has very good reasons to keep undergoing changes. As a result, our worldview, understanding, and theory of it is forever changing too. Documentation only works up to a point and generally lags behind, if not missing completely, in capturing this changing worldview.</p><p>Documentations usually are after the fact; they are written after the developers have already built the theories in their minds. In this respect documentation serves as a <a href="https://www.baldurbjarnason.com/2022/theory-building/">mnemonic for what you already know, not as a tool for learning</a> as Baldur Bjarnason puts it. </p><p></p><div><hr></div><h2>Program Life, Death, and Revival</h2><p>Naur presents an interesting idea about the lifecycle of a program. Since theory of a program is built and held in the minds of the programmers and cannot be reduced to or expressed conceivably through other materials, the lifecycle of the program is dependent on the team&#8217;s changes and churn.</p><p>&#8220;The death of a program happens when the programmer team possessing its theory is dissolved.&#8221; The program may continue to serve its purpose long after the team is dissolved, the actual death of the program only becomes evident when there are changes to be made or the program needs to be extended. The new team, devoid of original theory, might still be able to make modifications but these modifications are bound to be divergent from the original theory, and the resultant modified program different from how the developers having the original theory would have done the changes. (** coughs <strong>&#120143;</strong>) </p><p>Naturally, the program&#8217;s life gets extended when new developers come in and get to build their theory of the program by working closely with the developers already having this theory. It is always insufficient for new developers to get onboarded efficiently through just reading documentation and getting familiarised with the source code. It is for this reason that onboarding of a new developer should be a team activity.</p><p>Revival of the program is to rebuild the theory of it by the new developer team. Naur suggests that since the original theory cannot be reconstructed through just the source code and documentation, it is better to rewrite the code. &#8212; &#8220;In preference to program revival, the Theory Building View suggests, the existing program text should be discarded and the new&#8211;formed programmer team should be given the opportunity to solve the given problem afresh. Such a procedure is more likely to produce a viable program than program revival, and at no higher, and possibly lower, cost.&#8221; This is one idea that I found myself heavily disagreeing with. Rewrite is always a bad idea in my opinion and should be avoided at any cost.</p><p></p><div><hr></div><h2>Closing Thoughts</h2><p>In revisiting the paper after having read Ryle&#8217;s book, I had different takes from when I read the paper for the first time. In day to day of modern software development, we take pride in writing clean and idiomatic code, we write our documentation elaborately, we create story maps to layout the real world problem that the program is supposed to handle, we annotate our system design architecture quite well, we often record our design decisions in ADRs, we write tests to ascertain the scenarios our code is supposed to handle, and much more. All these artefacts are secondary to the shared mental construct of the team that is working on the software. They are necessary but not sufficient.</p><p>Although I still find myself disagreeing with the idea of a rewrite. Maybe I&#8217;ve not experienced the &#8220;death of program&#8221; as Naur mentions it. Maybe if you have, I&#8217;d love to know your thoughts and context in the comments below.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! &#128588;  If you like what I write and would like to see more such takes on papers, why not subscribe! &#128522;</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div>]]></content:encoded></item><item><title><![CDATA[Arguments and Results, James Noble. Part 1.]]></title><description><![CDATA[Summary and annotations of paper "Arguments and Results" by James Noble. Part 1: Three patterns to simplify functions with complex arguments.]]></description><link>https://www.riverandsoftware.com/p/arguments-and-results-james-noble-1</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/arguments-and-results-james-noble-1</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Sat, 15 Jul 2023 08:03:39 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/6bcf9717-3043-4b33-ab2d-79f24ba05aab_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This week I read &#8220;<a href="http://www.laputan.org/pub/patterns/noble/noble.pdf">Arguments and Results</a>&#8221; by James Noble. I felt it was a good follow up read to &#8220;<a href="https://www.riverandsoftware.com/p/criteria-to-be-used-in-modularisation-paper">On The Criteria To Be Used in Decomposing Systems into Modules</a>&#8221;. Both the papers are from <a href="https://twitter.com/mfeathers">Michael Feathers</a>&#8217; (Author of Working Effectively with Legacy Code) famous &#8220;<a href="https://michaelfeathers.silvrback.com/10-papers-every-developer-should-read-at-least-twice">10 Papers Every Developer Should Read (at least twice)</a>&#8221;</p><blockquote><p><em>&#8220;We&#8217;ve come to value experiential learning much more, and we&#8217;ve regained a strong pragmatic focus, but I think it would be a shame if we lost sight of some of the deeper things which people have learned over the past 50 years. Rediscovering them would be painful, and (to me) not knowing them would be a shame.&#8221;</em></p><p><em>&#8212; <a href="https://michaelfeathers.silvrback.com/10-papers-every-developer-should-read-at-least-twice">Michael Feathers. 10 Papers Every Developer Should Read</a></em></p></blockquote><p>&#8220;Arguments and Results&#8221; is about patterns that can be used to tackle complexity in APIs (or as Noble calls them &#8220;<em>protocols of an object</em>&#8220;). It primarily focuses on their arguments and return results; hence the title of the paper. The patterns listed in the paper are not exhaustive by any means, but are quite extensively applicable.</p><h4>Two primary motivations behind these patterns:</h4><ol><li><p>To make software simple and concise: &#8220;<em>Since smaller, simpler programs are generally easier to read and write, the patterns are concerned with the complexity or size of a design, such as the number of messages an object understands</em>&#8221;</p></li><li><p>To constrain inevitable complexity from spreading out: Over time, complexity in software is inevitable. But we can constrain the complexity to few places instead of letting it leak to other parts.</p></li></ol><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading <strong>Between The River and The Software</strong>! Subscribe for free to receive new paper summaries and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>In this part 1, I&#8217;m going to only focus on &#8220;arguments&#8221; and in part 2 I&#8217;ll cover the patterns related to &#8220;results&#8221;.</p><p>We&#8217;re going to look at three patterns to tackle complexity with respect to arguments of a function/object:</p><ol><li><p><strong>Argument Objects</strong>: Or how to make implicit concepts explicit</p></li><li><p><strong>Selector Objects</strong>: Or how to simplify methods that do similar things.</p></li><li><p><strong>Curried Objects</strong>: How to simplify extremely complicated APIs by currying and partial application.</p></li></ol><div><hr></div><h2>Arguments Object</h2><p>In simple terms, this is about extracting common and related arguments into respective <a href="https://martinfowler.com/bliki/ValueObject.html">value object</a>s.</p><p>A function that accepts large number of arguments is more prone to modifications. Primarily because it already does too many things. It doesn't hurt to let it do one more thing, and then some more. Moreover, &#8220;<em>adding an eleventh argument to a message with ten arguments is qualitatively quite different to adding a second argument to a unary message</em>&#8221;</p><blockquote><p><em>"If you have a procedure with 10 parameters, you probably missed some"</em></p><p><em>&#8212; Alan Perlis</em> </p></blockquote><p>By lifting and grouping the parameters into respective objects, we make the purpose of a function more explicit. These groupings (abstraction into specific types) make the reasons for change more explicit and meaningful. For instance, when writing a Paint software, it makes sense to talk in terms of coordinates (both X and Y value) together. So it makes API more readable when we extract them into a <em>Point</em> type:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VsI4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F774fe67c-f830-46da-9bd9-e8985ac853e2_1370x1254.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VsI4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F774fe67c-f830-46da-9bd9-e8985ac853e2_1370x1254.png 424w, https://substackcdn.com/image/fetch/$s_!VsI4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F774fe67c-f830-46da-9bd9-e8985ac853e2_1370x1254.png 848w, https://substackcdn.com/image/fetch/$s_!VsI4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F774fe67c-f830-46da-9bd9-e8985ac853e2_1370x1254.png 1272w, https://substackcdn.com/image/fetch/$s_!VsI4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F774fe67c-f830-46da-9bd9-e8985ac853e2_1370x1254.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VsI4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F774fe67c-f830-46da-9bd9-e8985ac853e2_1370x1254.png" width="1370" height="1254" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/774fe67c-f830-46da-9bd9-e8985ac853e2_1370x1254.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1254,&quot;width&quot;:1370,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:166899,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VsI4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F774fe67c-f830-46da-9bd9-e8985ac853e2_1370x1254.png 424w, https://substackcdn.com/image/fetch/$s_!VsI4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F774fe67c-f830-46da-9bd9-e8985ac853e2_1370x1254.png 848w, https://substackcdn.com/image/fetch/$s_!VsI4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F774fe67c-f830-46da-9bd9-e8985ac853e2_1370x1254.png 1272w, https://substackcdn.com/image/fetch/$s_!VsI4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F774fe67c-f830-46da-9bd9-e8985ac853e2_1370x1254.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 1: Before and After extracting Arguments Object of a typical drawLine function</figcaption></figure></div><p>This makes it easier for the client developers to reason with the APIs and eases their cognitive load during implementation.</p><p>I found this pattern very similar to DDD&#8217;s &#8220;<a href="https://www.goodreads.com/book/show/179133">make implicit concepts explicit</a>&#8221; and <a href="https://medium.com/javascript-in-plain-english/why-you-should-stop-representing-age-as-a-number-in-your-code-ea1026a86bc8">using value objects over primitive obsession</a>. </p><p></p><div><hr></div><h2>Selector Object</h2><p>Quite often an API exposes several functions which perform similar underlying operations. For instance, continuing on our Paint software theme, lets say we have a graphical &#8220;View&#8221; type which exposes various methods to draw different shapes:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-vbn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cef9bf-796d-4cc4-94dc-4270285b6dc3_1552x678.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-vbn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cef9bf-796d-4cc4-94dc-4270285b6dc3_1552x678.png 424w, https://substackcdn.com/image/fetch/$s_!-vbn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cef9bf-796d-4cc4-94dc-4270285b6dc3_1552x678.png 848w, https://substackcdn.com/image/fetch/$s_!-vbn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cef9bf-796d-4cc4-94dc-4270285b6dc3_1552x678.png 1272w, https://substackcdn.com/image/fetch/$s_!-vbn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cef9bf-796d-4cc4-94dc-4270285b6dc3_1552x678.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-vbn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cef9bf-796d-4cc4-94dc-4270285b6dc3_1552x678.png" width="1456" height="636" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/66cef9bf-796d-4cc4-94dc-4270285b6dc3_1552x678.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:636,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:122057,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-vbn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cef9bf-796d-4cc4-94dc-4270285b6dc3_1552x678.png 424w, https://substackcdn.com/image/fetch/$s_!-vbn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cef9bf-796d-4cc4-94dc-4270285b6dc3_1552x678.png 848w, https://substackcdn.com/image/fetch/$s_!-vbn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cef9bf-796d-4cc4-94dc-4270285b6dc3_1552x678.png 1272w, https://substackcdn.com/image/fetch/$s_!-vbn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66cef9bf-796d-4cc4-94dc-4270285b6dc3_1552x678.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 2: various draw shape methods</figcaption></figure></div><p></p><blockquote><p><em>&#8220;Protocols (APIs) where many messages perform similar functions are often difficult to learn and to use, especially as the similarity is often not obvious from the protocol's documentation. Because the messages are conceptually closely related, they will often need to be maintained as a group, which will require changing a number of method implementations in servers and many different message sends in clients.&#8221;</em></p></blockquote><p>In a typical Object Oriented world, you would use polymorphism to have different `Shape` types and expose a base class `draw()`function which can take different types of shapes and then <em>draw </em>them<em>. </em>These different instances of <em>shapes</em> then behave like a Selector Object to the base <em>draw</em> function.</p><p>Noble mentions that in simpler scenarios even just an <em>enum</em> type would also work fine as a Selector Object. In more complex scenarios you could use <a href="https://clojure.org/reference/multimethods">multimethods</a> or even <a href="https://refactoring.guru/design-patterns/visitor-double-dispatch">double dispatch</a>. I also found <a href="https://refactoring.guru/design-patterns/composite">Composite pattern</a> to be quite similar to Selector Object concept.</p><p>One could also use Selector Object as <a href="https://refactoring.guru/design-patterns/flyweight">Flyweights</a> .</p><p></p><div><hr></div><h2>Curried Object</h2><p>This is one of my favourite go to techniques, especially when I&#8217;m dealing with external libraries and their APIs. Let&#8217;s take a typical example of using node&#8217;s <em>fetch</em> API to get some data from an HTTP API. Let&#8217;s say I am interested in getting all the posts in my blog and comments from a particular post. A typical code would look like below:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jkOj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd83a5ff-306e-44e3-aefb-d864e469423a_1202x1218.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jkOj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd83a5ff-306e-44e3-aefb-d864e469423a_1202x1218.png 424w, https://substackcdn.com/image/fetch/$s_!jkOj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd83a5ff-306e-44e3-aefb-d864e469423a_1202x1218.png 848w, https://substackcdn.com/image/fetch/$s_!jkOj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd83a5ff-306e-44e3-aefb-d864e469423a_1202x1218.png 1272w, https://substackcdn.com/image/fetch/$s_!jkOj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd83a5ff-306e-44e3-aefb-d864e469423a_1202x1218.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jkOj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd83a5ff-306e-44e3-aefb-d864e469423a_1202x1218.png" width="1202" height="1218" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dd83a5ff-306e-44e3-aefb-d864e469423a_1202x1218.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1218,&quot;width&quot;:1202,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:231937,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jkOj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd83a5ff-306e-44e3-aefb-d864e469423a_1202x1218.png 424w, https://substackcdn.com/image/fetch/$s_!jkOj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd83a5ff-306e-44e3-aefb-d864e469423a_1202x1218.png 848w, https://substackcdn.com/image/fetch/$s_!jkOj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd83a5ff-306e-44e3-aefb-d864e469423a_1202x1218.png 1272w, https://substackcdn.com/image/fetch/$s_!jkOj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd83a5ff-306e-44e3-aefb-d864e469423a_1202x1218.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 3: Typical usage of fetch API to get data from HTTP APIs</figcaption></figure></div><p>There are a <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#supplying_request_options">plethora of options</a> available while configuring the request. For the sake of this article, I&#8217;ve limited these options to passing of a bearer token for authentication purpose and using `<em>Get</em>` method of fetch. Evidently, each client code interested in calling the `<em>getPosts()</em>` and `<em>getComments()</em>` functions would need to pass the token. It needs to be aware of authentication mechanism. Most of the projects, after first authentication with server, would keep this token in some sort of a middleware. With the above code, each client function would also need to be aware of middleware and invoke some sort of <em>get</em> to obtain the token before passing to the <em>getPosts()</em> and <em>getComments()</em> methods. This adds unnecessary coupling and complicates the client code.</p><p>The paper mentions how such arguments are &#8220;<em>content</em>&#8221; and the client needs to cache them (for e.g. knowing about bearer token before it can call getPosts() method) in order to use the APIs:</p><blockquote><p><em>&#8220;These kinds of arguments increase the complexity of a protocol. The protocol will be difficult to learn, as programmers must work out which arguments must be changed, and which must remain constant. This information is not explicitly represented in the protocol, and often not provided by standard documentation. The protocol will be difficult to use, as clients must cache constant arguments between sends and compute the values of slowly-varying arguments.&#8221;</em></p></blockquote><p>This is where currying and partial functions shine. We could very well use currying and expose partial functions to the client code, making the authentication mechanism &#8220;invisible&#8221; to them:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9xZc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95352f78-e8ad-4b8a-9dc1-44c05455b71e_1472x1664.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9xZc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95352f78-e8ad-4b8a-9dc1-44c05455b71e_1472x1664.png 424w, https://substackcdn.com/image/fetch/$s_!9xZc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95352f78-e8ad-4b8a-9dc1-44c05455b71e_1472x1664.png 848w, https://substackcdn.com/image/fetch/$s_!9xZc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95352f78-e8ad-4b8a-9dc1-44c05455b71e_1472x1664.png 1272w, https://substackcdn.com/image/fetch/$s_!9xZc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95352f78-e8ad-4b8a-9dc1-44c05455b71e_1472x1664.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9xZc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95352f78-e8ad-4b8a-9dc1-44c05455b71e_1472x1664.png" width="1456" height="1646" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/95352f78-e8ad-4b8a-9dc1-44c05455b71e_1472x1664.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1646,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:369465,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9xZc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95352f78-e8ad-4b8a-9dc1-44c05455b71e_1472x1664.png 424w, https://substackcdn.com/image/fetch/$s_!9xZc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95352f78-e8ad-4b8a-9dc1-44c05455b71e_1472x1664.png 848w, https://substackcdn.com/image/fetch/$s_!9xZc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95352f78-e8ad-4b8a-9dc1-44c05455b71e_1472x1664.png 1272w, https://substackcdn.com/image/fetch/$s_!9xZc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95352f78-e8ad-4b8a-9dc1-44c05455b71e_1472x1664.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figure 4: Using currying and partial application to simplify API</figcaption></figure></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading <strong>Between The River and The Software</strong>! Subscribe for free to receive new paper summaries and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><p></p><h2>Conclusion</h2><ul><li><p>Quite often, the design can be simplified by &#8220;finding&#8221; additional objects. Strong emphasis on trying to &#8220;find&#8221; objects that part of the <strong><a href="https://www.goodreads.com/book/show/179133">ubiquitous language</a></strong>. This makes sure we&#8217;re not introducing phantom concepts in the system.</p></li><li><p>These patterns introduce another layer of <strong>indirection</strong>. While this can simplify understanding of objects/modules in isolation, at times it can interfere with ability to reason with the global design of the system. </p></li><li><p>Since with all these patterns, additional objects and their construction are getting introduced, at times it can even introduce <strong>space and time complexity</strong>. Each pattern is to be employed with caution.</p></li><li><p>Use <strong>Factory</strong> or other <a href="https://refactoring.guru/design-patterns/creational-patterns">creational patterns</a> when construction of these objects (Argument, Selector etc.) gets complicated. Using a creational pattern can greatly simplify the API for client.</p></li></ul>]]></content:encoded></item><item><title><![CDATA[Serverless and Cost Duality.]]></title><description><![CDATA[In this fortnightly edition: Serverless and Cost Duality. Wolfram's paper "What is ChatGPT? and Why does it work" explains inner workings of ChatGPT and LLMs.]]></description><link>https://www.riverandsoftware.com/p/the-fortnightly-080723</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/the-fortnightly-080723</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Sat, 08 Jul 2023 09:20:19 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/5720525b-8f3b-4c78-b046-11a3984f414c_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Hope you are having great days. &#127808;</em></p><p><em>This is a fortnightly newsletter in which I share interesting articles, talks, quotes from literature, comic strips &#128522; and many such things that I found insightful around software and its makers.</em></p><div><hr></div><p>Things this fortnight:</p><ol><li><p>Serverless and Cost Duality.</p></li><li><p>What Is ChatGPT Doing&#8230; and Why Does It Work?</p></li></ol><p>But first, we need to make this &#8220;Re-Org&#8221; rap as an official re-org anthem! &#128588;</p><div id="youtube2-yDcaRklX7q4" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;yDcaRklX7q4&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/yDcaRklX7q4?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p></p><div><hr></div><h2>Serverless and Cost Duality.</h2><p>Serverless often gets a bad rep in the industry. Mostly because <a href="https://docs.aws.amazon.com/lambda/latest/operatorguide/recursive-runaway.html">if left untapped</a> , it is very potent in <a href="https://blog.tomilkieway.com/72k-1/">drying out your entire capital</a>. We also have commentaries on how teams are able to <a href="https://www.primevideotech.com/video-streaming/scaling-up-the-prime-video-audio-video-monitoring-service-and-reducing-costs-by-90">reduce costs by moving away from serverless</a>.</p><blockquote><p><em>"As a bootstrapped company, there was no way for us to come up with $72K.</em></p><p><em>By this time, I was well versed with Chapter 7 and Chapter 11 of Bankruptcy and mentally prepared of what could come next."</em></p><p>&#8212; <a href="https://blog.tomilkieway.com/72k-1/">Source</a></p></blockquote><p><a href="https://twitter.com/forrestbrazeal?s=21&amp;t=b4Yxe0abRgrb5VDP1EiWFg">Forrest Brazeal</a> has written about the <a href="https://newsletter.goodtechthings.com/p/the-cloud-billing-risk-that-scares">risks of cloud billing</a> citing horror stories of bleeding money across the three major cloud providers.  Brazeal mentions having near real time billing and ability to have hard caps on cloud spend would really <a href="https://newsletter.goodtechthings.com/i/64770572/what-could-help-even-more">help mitigating the horror</a>. Unfortunately, we're not there yet.</p><p>There are ways you can codify some controls in though, like limiting the concurrency limits of your lambda functions and being stringent about the memory limits. <a href="https://twitter.com/theburningmonk?s=21&amp;t=b4Yxe0abRgrb5VDP1EiWFg">Yan Cui</a> explains how AWS lambda pricing works and <a href="https://theburningmonk.com/2022/07/the-best-ways-to-save-money-on-lambda/">how you can optimise the costs</a>. You can also use <a href="https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:451282441545:applications~aws-lambda-power-tuning">AWS Lambda Power Tuning tool</a> which runs in your AWS account and helps you decide the optimum configuration of your lambda.</p><p>On the other side, serverless when used for prototyping is actually a huge cost saver. <strong>Infrastructure cost</strong> is not the only cost a team has to think about. There is <strong><a href="https://pages.awscloud.com/rs/112-TZM-766/images/AWS_MAD_Deloitte_TCO_paper.pdf">development cost</a></strong><a href="https://pages.awscloud.com/rs/112-TZM-766/images/AWS_MAD_Deloitte_TCO_paper.pdf"> and </a><strong><a href="https://pages.awscloud.com/rs/112-TZM-766/images/AWS_MAD_Deloitte_TCO_paper.pdf">maintenance cost</a></strong>. Every developer also comes at a cost. Add dedicated ops people to the mix and the costs start to rise non-linearly. At early stages of a company, there is also an <strong>opportunity cost</strong>. Miss the opportunity to land your product at the right time, and you may never recover from it. The ecosystem of serverless and various building blocks makes it easier to build and ship faster.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/subscribe?"><span>Subscribe now</span></a></p><p><a href="https://me.dm/@adrianco">Adrian Cockroft</a> has a great short video explaining how serverless first is like building with lego blocks. Building with serverless components is &#8220;quick and cheap&#8221;. It shortens the feedback loop. If you&#8217;re trying to launch a new product, you get to launch sooner and test the waters before your competition does. But then why not start with monolith directly? Do you even need serverless at this time? Monolith first is generally a good advice, but there are a lot of nuances. I plan to cover this aspect soon, but in a different article to keep this one a bit shorter.</p><p>If everything goes right, your product will pick up more traffic, and will have more and more users coming in. You&#8217;ll start to notice the costs of lambdas are going higher and higher. You&#8217;ll start to think about bespoke optimisations. This is a right time to start taking out the concerned serverless components and start replacing them with bespoke services and deployments. </p><div id="youtube2-5siD210Grr4" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;5siD210Grr4&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/5siD210Grr4?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><h2></h2><div><hr></div><h2>What Is ChatGPT Doing&#8230; and Why Does It Work?</h2><p>ChatGPT, in simple terms, is doing a next word prediction. </p><blockquote><p>The first thing to explain is that what ChatGPT is always fundamentally trying to do is to produce a &#8220;reasonable continuation&#8221; of whatever text it&#8217;s got so far, where by &#8220;reasonable&#8221; we mean &#8220;what one might expect someone to write after seeing what people have written on billions of webpages, etc.</p></blockquote><p>So given an incomplete sentence: &#8220;The best thing about AI is its ability to&#8230;&#8221;, ChatGPT would rank the next set of possible words by their probabilities of occurrence from the training data (lots and lots of human produced text on Internet) and then choose a word to complete the sentence &#8220;<em>randomly</em>&#8221;. I&#8217;ve quoted &#8220;randomly&#8221; because given the same incomplete sentence, the completion wouldn&#8217;t be the same.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Z9lM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbad4624-a3d7-49ea-8e9e-3696c3f81019_906x274.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Z9lM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbad4624-a3d7-49ea-8e9e-3696c3f81019_906x274.png 424w, https://substackcdn.com/image/fetch/$s_!Z9lM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbad4624-a3d7-49ea-8e9e-3696c3f81019_906x274.png 848w, https://substackcdn.com/image/fetch/$s_!Z9lM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbad4624-a3d7-49ea-8e9e-3696c3f81019_906x274.png 1272w, https://substackcdn.com/image/fetch/$s_!Z9lM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbad4624-a3d7-49ea-8e9e-3696c3f81019_906x274.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Z9lM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbad4624-a3d7-49ea-8e9e-3696c3f81019_906x274.png" width="674" height="203.83664459161147" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fbad4624-a3d7-49ea-8e9e-3696c3f81019_906x274.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:274,&quot;width&quot;:906,&quot;resizeWidth&quot;:674,&quot;bytes&quot;:30561,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Z9lM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbad4624-a3d7-49ea-8e9e-3696c3f81019_906x274.png 424w, https://substackcdn.com/image/fetch/$s_!Z9lM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbad4624-a3d7-49ea-8e9e-3696c3f81019_906x274.png 848w, https://substackcdn.com/image/fetch/$s_!Z9lM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbad4624-a3d7-49ea-8e9e-3696c3f81019_906x274.png 1272w, https://substackcdn.com/image/fetch/$s_!Z9lM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbad4624-a3d7-49ea-8e9e-3696c3f81019_906x274.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Source: Stephen Wolfram. 2023. What is ChatGPT Doing&#8230; and Why Does It Work?</figcaption></figure></div><p>So how is it able to complete the sentences in so human-like manner? How is it able to write lengthy essays on a given topic in such seemingly meaningful way? </p><p>Stephen Wolfram&#8217;s <a href="https://writings.stephenwolfram.com/2023/02/what-is-chatgpt-doing-and-why-does-it-work/">What Is ChatGPT Doing... and Why Does It Work?</a> is one of the best papers I&#8217;ve come across which describes the inner workings of ChatGPT from ground up.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>etc.</h2><ul><li><p>Last week I published my summary and annotations of D.L. Parnas paper &#8220;<a href="https://www.riverandsoftware.com/p/criteria-to-be-used-in-modularisation-paper">On The Criteria to be used in Decomposing System into Modules</a>&#8221;. To which <a href="https://www.linkedin.com/in/nav301186">Naveen Negi</a> suggested a follow up read: <a href="https://www.informit.com/articles/article.aspx?p=2995357&amp;seqNum=2">Volatility based decomposition</a>.</p></li><li><p><a href="https://www.goodreads.com/book/show/61167316">The Value Flywheel Effect</a>, by David Anderson is good read about how value chain mapping and serverless can compliment each other.</p></li></ul><div><hr></div><p><em>That&#8217;s a wrap!</em></p><p><em>Have good days! &#127808;</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/p/the-fortnightly-080723?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/p/the-fortnightly-080723?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[On The Criteria to be used in Decomposing System into Modules by D.L. Parnas]]></title><description><![CDATA[Paper summary of "On The Criteria to be used in Decomposing System into Modules" by D.L. Parnas, 1972. The importance of encapsulation in a good modularisation.]]></description><link>https://www.riverandsoftware.com/p/criteria-to-be-used-in-modularisation-paper</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/criteria-to-be-used-in-modularisation-paper</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Fri, 30 Jun 2023 07:45:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!rxXH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aa541cc-5bce-49d0-9794-02266cba87ed_1738x1000.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p><em>&#8220;If programmers sang hymns, some of the most popular would be hymns in praise of modular programming&#8221;</em></p><p><em>&#8212; D. L. Parnas, 1972 [1]</em></p></blockquote><p>This week i read the paper &#8220;<a href="https://dl.acm.org/doi/10.1145/361598.361623">On The Criteria to be used in Decomposing Systems into Modules</a>&#8221; written by D. L. Parnas in 1972. This article is a summary of the paper. I&#8217;ve put in my thoughts and annotations too.</p><p>What makes this paper a classic is that although published in early 1970s, the ideas presented in it about modularisation are still relevant in the modern development. One could even extend them in designing distributed systems like microservices. The paper is a very good case for good encapsulation, higher cohesion and lesser couplings wrt modules.</p><div><hr></div><h2>Abstract</h2><blockquote><p><em>&#8220;This paper discusses modularisation as a mechanism for <strong>improving the flexibility and comprehensibility of a system while allowing the shortening of its development time</strong>. The effectiveness of a "modularisation&#8221; is dependent upon the criteria used in dividing the system into modules.&#8221;</em></p></blockquote><p>The paper&#8217;s major motivation is to explore &#8220;how to modularise effectively&#8221;. It posits that a good modularisation is not just an assembly of a runnable process, but more than that. It posits that modularisation enables independent development &amp; testing. A good modularisation reduces managerial overhead, increases flexibility and comprehensibility (elaborated later) which in turns reduces development time. It is worth pointing out that Parnas defines &#8220;module&#8221; as &#8220;<em>a work assignment unit rather than a subprogram</em>&#8221;.</p><p>He adds:</p><blockquote><p>&#8220;<em>The modularisations  are intended to describe the design decisions which must be made before the work on independent modules can begin.</em>&#8221;</p></blockquote><p>Now, this is not to be misinterpreted with big upfront design. But instead, having some directional thinking where your team envisions the software to get structured as. DDD and event-storming fall within this paradigm.</p><p>The paper begins by quoting Gauthier<em>[2] </em>that modularisation of code enables independent development and testing with little overhead:</p><blockquote><p><em>"A well-defined segmentation of the project effort ensures system modularity. Each task forms a separate, distinct program module. At implementation time each module and its inputs and outputs are well-defined, there is <strong>no confusion in the intended interface with other system modules</strong>. At checkout time the <strong>integrity of the module is tested independently</strong>; <strong>there are</strong> <strong>few scheduling problems in synchronising</strong> the completion of several tasks before checkout can begin. Finally, the system is maintained in modular fashion; system errors and deficiencies can be traced to specific system modules, thus <strong>limiting the scope of detailed error searching</strong>.&#8221;</em></p><p><em>&#8212; Gauthier, et. al. Designing Systems Programs [2]</em></p></blockquote><p>Parnas, while agreeing with the above, points out that little has been mentioned about the criteria to use in dividing a system into modules. Simply dividing a system into multiple modules doesn&#8217;t achieve the expected benefits of a good modularisation. So what are the expected benefits?</p><h2>Expected Benefits of Good Modularisation</h2><p>The paper posits that a good modularisation results in following three benefits:</p><ol><li><p> <strong>Managerial:</strong> &#8220;<em>development time could be shortened because separate groups would work on each module with little need for communication (and little regret afterward that there had not been more communication)</em>&#8221;; &#8212; think about all the communication overheads, dependencies within and between teams etc when there are poor boundaries between different components of a system.</p></li><li><p><strong>Product Flexibility</strong>: &#8220;<em>it was hoped that it would be possible to make quite drastic changes or improvements in one module without changing others</em>&#8221;;&nbsp;&#8212; A whole lot of literature viz. Agile, DevOps, Evolutionary Architecture, Incremental Development, SOLID, DDD etc., talks about this; the ability to increase &#8220;changeability&#8221; of a software. The greater this ability, the better outcomes for business.</p></li><li><p><strong>Comprehensibility</strong>: &#8220;<em>it was hoped that the system could be studied a module at a time with the result that the whole system could be better designed because it was better understood.</em>&#8221; &#8212; This is really about maintainability of a software and ability to reason with it. The lesser cognitive load a developer has while trying to understand the existing system before s/he can start making changes, the better maintainability of a software is.</p></li></ol><p>So, what should be the criteria of modularisation which sets out to achieve above benefits? This is what is explored in the paper. </p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/subscribe?"><span>Subscribe now</span></a></p><p>At the heart of the paper are two software examples - a <em>KWIC Index Production System</em> and a <em>Markov Algorithm Translator</em>. Parnas uses these two examples and gives different modularisation approaches for them, and then gives reasonings over which modularisation is better. I&#8217;ll pick up only the former example for the sake of this summary.</p><div><hr></div><h2>Background on KWIC Index Production System</h2><p>The KWIC (or Key Word in Context) system was widely employed in libraries to make the text searchable. The system is based on the principle that the title of the document represents its contents. It is believed that the title of the document is one line abstract of the document.</p><p>A typical KWIC index system accepts an ordered set of lines, each line is an ordered set of words, and each word is an ordered set of characters. Any line may be "circularly shifted" by repeatedly removing the first word and adding it to the end of the line. The KWIC index system outputs a listing of all circular shifts of all lines in alphabetical order.</p><p>Let&#8217;s say we have a title of an article/book as &#8220;Prevention of diseases of wheat caused by insects&#8221;. The first step is to identify a set of <strong>keywords</strong> to be searchable. Let&#8217;s say those are (from the title above): &#8220;prevention&#8221;, &#8220;diseases&#8221;, &#8220;wheat&#8221; and &#8220;insects&#8221;. The program would accept these keywords along with the title. It interprets the above title then as &#8220;<strong>Prevention</strong> of <strong>diseases</strong> of <strong>wheat</strong> caused by <strong>insects</strong>&#8221; (the bolded words are just for illustration purposes. The program may choose alternate ways of recognising the keywords within a given title)</p><p>The second step is to circularly shift the sentence so that each significant keyword appears first with the rest of the sentence following it, which the preceding words wrapping at the end (circularly shifting). The outcome of this step would be following list of sentences (note that &#8216;/&#8217; is used as an identifier of end of original title):</p><ul><li><p><strong>Prevention</strong> of diseases of wheat caused by insects</p></li><li><p><strong>diseases</strong> of wheat caused by insects/ Prevention of</p></li><li><p><strong>wheat</strong> caused by insects/ Prevention of diseases of</p></li><li><p><strong>insects</strong>/ Prevention of diseases of wheat caused by</p></li></ul><p>In the third step, the program would take the above list of sentences and arrange them in alphabetical order. So the output of this step would be:</p><ul><li><p><strong>diseases</strong> of wheat caused by insects/ Prevention of</p></li><li><p><strong>insects</strong>/ Prevention of diseases of wheat caused by</p></li><li><p><strong>Prevention</strong> of diseases of wheat caused by insects</p></li><li><p><strong>wheat</strong> caused by insects/ Prevention of diseases of</p></li></ul><p>With the above context in mind, let&#8217;s look at the two modularisation approaches that the paper illustrates:</p><h3>Modularisation 1</h3><p>In the first modularisation attempt, following modules are identified:</p><ol><li><p><strong>Input</strong>: accepts the input lines from a given medium and stores them in memory</p></li><li><p><strong>Circular Shift</strong>: Called after the <em>input</em> module. Rather than storing all circular shifts in memory, it prepares an index which gives the address of the first character of each circular shift, and the original index of the line in the array made up by module 1. It leaves its output in memory with words in pairs (original line number, starting address)  </p></li><li><p><strong>Alphabetising</strong>: This module takes as input the arrays produced by modules 1 and 2. It produces an array in the same format as that produced by module 2. In this case, however, the circular shifts are listed in alphabetical order.</p></li><li><p><strong>Output</strong>: Uses the output produced by modules 1 and 3 and outputs the result.</p></li><li><p><strong>Master Control</strong>: Orchestrates the above modules.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rxXH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aa541cc-5bce-49d0-9794-02266cba87ed_1738x1000.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rxXH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aa541cc-5bce-49d0-9794-02266cba87ed_1738x1000.png 424w, https://substackcdn.com/image/fetch/$s_!rxXH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aa541cc-5bce-49d0-9794-02266cba87ed_1738x1000.png 848w, https://substackcdn.com/image/fetch/$s_!rxXH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aa541cc-5bce-49d0-9794-02266cba87ed_1738x1000.png 1272w, https://substackcdn.com/image/fetch/$s_!rxXH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aa541cc-5bce-49d0-9794-02266cba87ed_1738x1000.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rxXH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aa541cc-5bce-49d0-9794-02266cba87ed_1738x1000.png" width="1456" height="838" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5aa541cc-5bce-49d0-9794-02266cba87ed_1738x1000.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:838,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:237381,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rxXH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aa541cc-5bce-49d0-9794-02266cba87ed_1738x1000.png 424w, https://substackcdn.com/image/fetch/$s_!rxXH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aa541cc-5bce-49d0-9794-02266cba87ed_1738x1000.png 848w, https://substackcdn.com/image/fetch/$s_!rxXH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aa541cc-5bce-49d0-9794-02266cba87ed_1738x1000.png 1272w, https://substackcdn.com/image/fetch/$s_!rxXH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5aa541cc-5bce-49d0-9794-02266cba87ed_1738x1000.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Modularisation 1</figcaption></figure></div><h3>Modularisation 2</h3><p>In the second technique, following modules are identified along with their responsibilities:</p><ol><li><p><strong>Line Storage</strong>: It contains a number of functions defined on a &#8220;line&#8221;. For e.g. it contains a function to add a character at a specific position, another function to find the <em>k-</em>th character of a particular word in a given line, another function to set a <em>k</em>-th character of a particular word of a given line, and so on.</p></li><li><p><strong>Input</strong>: Reads the input from input media and calls <em>Line Storage </em>module to store them internally.</p></li><li><p><strong>Circular Shifter</strong>: This module is again defined in terms of functions, similar to module 1. For e.g. it contains function to get characters of a circularly shifted line.</p></li><li><p><strong>Alphabetiser</strong>: It contains primarily two functions: one for setup and the other to get the index of the circular shift which comes <em>i</em>-th in the alphabetical ordering.</p></li><li><p><strong>Output</strong>: This will give the desired printing of set of lines or circular shifts.</p></li><li><p><strong>Master Control</strong>: Similar to its function  in modularisation-1</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tvNk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f126ade-1690-4705-b8f8-3d8ecd928239_2209x1000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tvNk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f126ade-1690-4705-b8f8-3d8ecd928239_2209x1000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!tvNk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f126ade-1690-4705-b8f8-3d8ecd928239_2209x1000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!tvNk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f126ade-1690-4705-b8f8-3d8ecd928239_2209x1000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!tvNk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f126ade-1690-4705-b8f8-3d8ecd928239_2209x1000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tvNk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f126ade-1690-4705-b8f8-3d8ecd928239_2209x1000.jpeg" width="1456" height="659" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7f126ade-1690-4705-b8f8-3d8ecd928239_2209x1000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:659,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:737112,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tvNk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f126ade-1690-4705-b8f8-3d8ecd928239_2209x1000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!tvNk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f126ade-1690-4705-b8f8-3d8ecd928239_2209x1000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!tvNk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f126ade-1690-4705-b8f8-3d8ecd928239_2209x1000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!tvNk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f126ade-1690-4705-b8f8-3d8ecd928239_2209x1000.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Modularisation 2</figcaption></figure></div><p>You can begin to see the immediate differences in the two approaches, even though the algorithm of the two programmes remain identical in their &#8220;<em>runnable representation</em>&#8221;. The biggest differences are that modularisation-2 gets rid of data coupling completely and instead uses functional dependencies between the modules. </p><div><hr></div><h2>Comparison of the Two Modularisations</h2><p>The paper takes a look at both the modularisations through the lens of the previously stated three benefits of modular programming. Although the two modularisations are almost identical in the way they run, they are significantly different in the way they can be comprehended, maintained and developed. </p><blockquote><p><em>&#8220;<strong>I [Parnas] claim that the systems are substantially different even if identical in the runnable representation. This is possible because the runnable representation is used only for running; other representations are used for changing, documenting, understanding, etc. In those other representations the two systems will not be identical.</strong>&#8221;</em></p></blockquote><h3>Changeability</h3><p>&#8220;There are a number of design decisions which are questionable and likely to change under many circumstances.&#8221; </p><ol><li><p>Change in input format. In this case, both the modularisations would need a change. But the change in both is confined only to one <em>Input</em> module.</p></li><li><p>The decision to have all lines stored in memory. For larger indices it may prove inefficient and impractical to keep all the lines in memory while processing. This change would result in changes in every module of modularisation-1. In case of modularisation-2, the change is still confined to only <em>Line Storage</em> module.</p></li><li><p>The decision to change the underlying data structure in which the lines are stored. This yet again causes change in all the modules of modularisation-1 but because modularisation-2 abstracts the storage through <em>Line Storage, </em>it is able to confine the change only to one module.</p></li><li><p>The decision to make an index for circular shifts, rather than storing them as such. This change would be confined within the <em>Circular Shifter</em> module in modularisation-2. In modularisation-1 though, apart from <em>Circular Shift</em>, even the <em>Alphabetiser</em> and <em>Output</em> modules would accrue change because of data coupling.</p></li></ol><p>The theme is clear: better modularisation is able to better confine the changes caused due to future design decisions. This makes modularisation-2 more adaptable to change.</p><h3>Independent Development</h3><p>Contrasting between the two modularisations, the paper states:</p><blockquote><p><em>&#8220;In the first modularisation the interfaces between the modules are the fairly complex formats and table organizations described above. These represent design decisions which cannot be taken lightly. The table structure and organisation are essential to the efficiency of the various modules and must be designed carefully. The <strong>development of those formats will be a major part of the module development and that part must be a joint effort among the several development groups.</strong>&#8220;</em></p></blockquote><p>While the overhead of design decisions is paramount in modularisation-1, modularisation-2 results in lesser development overhead:</p><blockquote><p>&#8220;In the second modularisation the interfaces are more abstract, they consist primarily in the function names and the numbers and types of the parameters. These are <strong>relatively simple decisions and the independent development of modules should begin much earlier</strong>.&#8221;</p></blockquote><h3>Comprehensibility</h3><p>In modularisation-1, there is little to no possibility of local reasoning. You cannot understand how <em>Output</em> works without understanding what <em>Circular Shift</em> and <em>Alphabetiser</em> do the underlying storage structure, which in turn can&#8217;t be reasoned without taking <em>Input</em> into consideration. This increases the Cognitive load on developers, as they can only understand the system as a whole, not through its different parts.</p><p>In modularisation-2 however, because of clear responsibilities of modules, and the fact that they encapsulate the functionalities within themselves respectively, it is relatively easier to reason with and hence improve/refactor and test individual modules without having to comprehend the entire system at once.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>The Criteria</h2><p>Finally, the paper highlights and contrasts the different criteria used in the two modularisation. It states that modularisation-1 is mostly influenced by a &#8220;flowchart&#8221; of sorts of the programme:</p><blockquote><p><em>&#8220;In the first decomposition the criterion used was make each 'major step' in the processing a module. One might say that to get the first decomposition one makes a flowchart.&#8221;</em></p></blockquote><p>Parnas states that this style of modularisation (modularisation-1) is most common, mainly because that&#8217;s how programming is generally taught. My confirmation bias found me agreeing with it completely. </p><blockquote><p><em>&#8220;This is the most common approach to decomposition or modularization. It is an outgrowth of all programmer training which teaches us that we should begin with a rough flowchart and move from there to a detailed implementation.&#8221;</em></p></blockquote><p>He contrasts this with the encapsulation approach that modularisation-2 takes:</p><blockquote><p><em>&#8220;The second decomposition was made using "information hiding" [encapsulation] as a criteria. The modules no longer correspond to steps in the processing. The line storage module, for example, is used in almost every action by the system. Alphabetization may or may not correspond to a phase in the processing according to the method used. Similarly, circular shift might, in some circumstances, not make any table at all but calculate each character as demanded. <strong>Every module in the second decomposition is characterised by its knowledge of a design decision which it hides from all others. Its interface or definition was chosen to reveal as little as possible about its inner workings.</strong>&#8221;</em></p></blockquote><div><hr></div><h2>Conclusion</h2><p>The paper puts forth a strong case of encapsulation as a first class citizen when breaking down the system into modules. It strongly recommends that while it is important to consider the &#8220;flow&#8221; of the software, it is a poor theme on which the system should be solely be modularised upon. </p><blockquote><p><em>&#8220;We have tried to demonstrate by these examples that it is <strong>almost always incorrect to begin the decomposition of a system into modules on the basis of a flowchart.</strong>&#8220;</em></p></blockquote><p>It is important to take a Systems Thinking approach and analyse how it affects other teams, think about plausible future enhancements in design with respect to your problem domain, think how work will get hashed out and how to do it with least overheads.</p><blockquote><p><em>&#8220;We propose instead that one begins with a list of difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others. Since, <strong>in most cases,</strong> <strong>design decisions transcend time of execution, modules will not correspond to steps in the processing</strong>."</em> </p></blockquote><div><hr></div><p><strong>Notes:</strong></p><ul><li><p><em><strong>[1]</strong></em>: <em>D. L. Parnas. 1972. On the criteria to be used in decomposing systems into modules. Commun. ACM 15, 12 (Dec. 1972), 1053&#8211;1058. https://doi.org/10.1145/361598.361623</em></p></li><li><p><em><strong>[2]</strong></em>: <em>Gauthier, Richard and Stephen Pinto. 1970. Designing Systems Programs. Prentice-Hall, Inc.</em></p></li></ul>]]></content:encoded></item><item><title><![CDATA[The importance of having slack in your plans.]]></title><description><![CDATA[The importance of having slack in your plans. Many bad takes on Prime Video's move to monolith from microservices. Cryptography, brief history and basics.]]></description><link>https://www.riverandsoftware.com/p/the-fortnightly-200623</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/the-fortnightly-200623</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Tue, 20 Jun 2023 11:10:35 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d7de727-383b-44a0-adb1-4d23861671f1_1430x1000.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hope you are having great days and are off to a great start this week. &#127808;</p><p>This is a fortnightly newsletter in which I share interesting articles, talks, quotes from literature, comic strips &#128522; and many such things that I stumbled upon.</p><p>Let&#8217;s jump straight in.</p><h3>Three things this fortnight: </h3><ol><li><p>The importance of having slack in your plans</p></li><li><p>Many bad takes on Prime Video&#8217;s move to monolith from microservices</p></li><li><p>Cryptography: History and Basics</p></li></ol><p>As always some relevant links and recommended reads are present in the notes section at the bottom.</p><p>But before all, my favourite comic this fortnight. Courtesy <a href="https://twitter.com/vincentdnl">@vincentdnl</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1vRQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c20a90b-dec9-43e5-a9d0-1eab5e107cec_1824x1212.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1vRQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c20a90b-dec9-43e5-a9d0-1eab5e107cec_1824x1212.png 424w, https://substackcdn.com/image/fetch/$s_!1vRQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c20a90b-dec9-43e5-a9d0-1eab5e107cec_1824x1212.png 848w, https://substackcdn.com/image/fetch/$s_!1vRQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c20a90b-dec9-43e5-a9d0-1eab5e107cec_1824x1212.png 1272w, https://substackcdn.com/image/fetch/$s_!1vRQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c20a90b-dec9-43e5-a9d0-1eab5e107cec_1824x1212.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1vRQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c20a90b-dec9-43e5-a9d0-1eab5e107cec_1824x1212.png" width="652" height="433.02472527472526" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4c20a90b-dec9-43e5-a9d0-1eab5e107cec_1824x1212.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:967,&quot;width&quot;:1456,&quot;resizeWidth&quot;:652,&quot;bytes&quot;:816357,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1vRQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c20a90b-dec9-43e5-a9d0-1eab5e107cec_1824x1212.png 424w, https://substackcdn.com/image/fetch/$s_!1vRQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c20a90b-dec9-43e5-a9d0-1eab5e107cec_1824x1212.png 848w, https://substackcdn.com/image/fetch/$s_!1vRQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c20a90b-dec9-43e5-a9d0-1eab5e107cec_1824x1212.png 1272w, https://substackcdn.com/image/fetch/$s_!1vRQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c20a90b-dec9-43e5-a9d0-1eab5e107cec_1824x1212.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">comic by @vincentdnl</figcaption></figure></div><div><hr></div><h2>The importance of having slack in your plans</h2><p>Teams often get accustomed to their iteration plannings. So much so that they like to optimise for every bit of capacity that they have. If the team&#8217;s velocity is 15 stories points on average, it will definitely load up 15 points. At times it would throw in another 3-5 points as a stretched effort, a concept which is as antithetical to <em>flow</em> as possible.  </p><blockquote><p><em>&#8220;A plant [system] in which everyone is working all the time is very inefficient&#8221;</em></p><p><em>&#8212; <a href="https://www.goodreads.com/book/show/113934.The_Goal">M. Goldratt, The Goal</a></em></p></blockquote><p>Although setup as a fiction about a manufacturing plant, <a href="https://www.goodreads.com/book/show/113934.The_Goal">the book</a> explains Theory of Constraints better than most others. I particularly like the above quote because it highlights the importance of thinking in systems, as a whole. </p><blockquote><p>Optimising for individuals != Optimising the system</p></blockquote><p>It is intuitive to think that if we optimise for individual resources, the system as a whole will be efficient. If we pull in as much stories as much as we have capacity in this sprint, surely we are efficient, isn&#8217;t it? Well, not quite. We&#8217;re considering capacity as a sole measure. We&#8217;re optimising for one (local) measure. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3vla!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d7de727-383b-44a0-adb1-4d23861671f1_1430x1000.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3vla!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d7de727-383b-44a0-adb1-4d23861671f1_1430x1000.png 424w, https://substackcdn.com/image/fetch/$s_!3vla!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d7de727-383b-44a0-adb1-4d23861671f1_1430x1000.png 848w, https://substackcdn.com/image/fetch/$s_!3vla!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d7de727-383b-44a0-adb1-4d23861671f1_1430x1000.png 1272w, https://substackcdn.com/image/fetch/$s_!3vla!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d7de727-383b-44a0-adb1-4d23861671f1_1430x1000.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3vla!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d7de727-383b-44a0-adb1-4d23861671f1_1430x1000.png" width="1430" height="1000" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5d7de727-383b-44a0-adb1-4d23861671f1_1430x1000.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1000,&quot;width&quot;:1430,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:126693,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3vla!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d7de727-383b-44a0-adb1-4d23861671f1_1430x1000.png 424w, https://substackcdn.com/image/fetch/$s_!3vla!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d7de727-383b-44a0-adb1-4d23861671f1_1430x1000.png 848w, https://substackcdn.com/image/fetch/$s_!3vla!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d7de727-383b-44a0-adb1-4d23861671f1_1430x1000.png 1272w, https://substackcdn.com/image/fetch/$s_!3vla!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d7de727-383b-44a0-adb1-4d23861671f1_1430x1000.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"> Local vs Global Maxima</figcaption></figure></div><p></p><p>In reality local optimisation doesn&#8217;t always lead to optimisation at a global level. As shown in the above pseudo-graph, optimisations done for local or neighbouring problems might result in improvement of the local, a part of the whole system. It doesn&#8217;t necessarily lead to the overall optimisation that the system is capable of achieving. When we optimise only for capacity, other BAU tasks which demand capacity of the team take a hit. </p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/subscribe?"><span>Subscribe now</span></a></p><p>A software team has many more responsibilities than just writing new code for that prospect shiny feature which is hypothesised to earn that extra revenue. It has to look after the cruft in codebase, optimise the load balancing of resources, monitor the deployments and respond appropriately to any unavailabilities of the services, automate that manual task which takes forever and a lot of cognitive load to execute, as so on. Many of these tasks are unpredictable and yet of quite grave importance. How do you plan for these unpredictabilities? &#8212; By adding slack to your plan!</p><p>In his article <a href="https://martinfowler.com/bliki/Slack.html">Slack</a>, <a href="https://twitter.com/martinfowler">Martin Fowler</a> talks about how you can introduce slack in your plan:</p><blockquote><p><em>&#8220;A good way to introduce slack into planning is to use it to cope with the inherent uncertainty of planning. A team that averages 20 stories per iteration won't complete exactly that number every iteration. Instead we'll see a range: say from 15 to 22. In this situation the team can plan at their lowest consistent number (15) and treat the additional time as slack.&#8220;<br><br>&#8212; <a href="https://martinfowler.com/bliki/Slack.html">Martin Fowler</a></em></p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ab88!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2b917f4-c6a1-4d1b-aca0-51686e78bb33_560x300.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ab88!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2b917f4-c6a1-4d1b-aca0-51686e78bb33_560x300.png 424w, https://substackcdn.com/image/fetch/$s_!ab88!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2b917f4-c6a1-4d1b-aca0-51686e78bb33_560x300.png 848w, https://substackcdn.com/image/fetch/$s_!ab88!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2b917f4-c6a1-4d1b-aca0-51686e78bb33_560x300.png 1272w, https://substackcdn.com/image/fetch/$s_!ab88!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2b917f4-c6a1-4d1b-aca0-51686e78bb33_560x300.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ab88!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2b917f4-c6a1-4d1b-aca0-51686e78bb33_560x300.png" width="496" height="265.7142857142857" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b2b917f4-c6a1-4d1b-aca0-51686e78bb33_560x300.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:300,&quot;width&quot;:560,&quot;resizeWidth&quot;:496,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ab88!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2b917f4-c6a1-4d1b-aca0-51686e78bb33_560x300.png 424w, https://substackcdn.com/image/fetch/$s_!ab88!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2b917f4-c6a1-4d1b-aca0-51686e78bb33_560x300.png 848w, https://substackcdn.com/image/fetch/$s_!ab88!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2b917f4-c6a1-4d1b-aca0-51686e78bb33_560x300.png 1272w, https://substackcdn.com/image/fetch/$s_!ab88!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2b917f4-c6a1-4d1b-aca0-51686e78bb33_560x300.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">source: <a href="https://martinfowler.com/bliki/Slack.html">Martin Fowler, Slack</a></figcaption></figure></div><p> Key takeaways on how to utilise the slack time:</p><ul><li><p>The most obvious thing to do is to tackle additional stories. If the team is done with planned stories, it is good to pull in more work and get more done on an as-possible basis.</p></li><li><p>Respond to urgent requests. You may choose to have a dedicated &#8220;developer on support&#8221; person on rota basis. While a dedicated person attends to urgent requests (from end-user, a dependent team, an external vendor) it lets others concentrate on the feature.</p></li><li><p>Pair on a story and get it to done. Experiment pairing if you have a pull-request based workflow. See if pairing made it any better. At times your QA team might be overwhelmed with the number of stories to be tested, try giving a hand.</p></li><li><p>Automate that mundane manual tasks which takes a lot of steps to remember, but is mostly repeatable.</p></li><li><p>Explore how can the builds be made faster and more reliable. Maybe the test setup of your functional tests is flaky. Maybe the assertions themselves are flaky. Maybe there are some tests which should be there but aren&#8217;t.</p></li><li><p>Revisit some of the hurdles which are impeding developer productivity, try to solve them.</p></li><li><p>Pen down that last important architecture decision that the team took but couldn&#8217;t get time to document it.</p></li><li><p>Improve upon your API document and write down contract tests which have been pending since that new team started consuming your services.</p></li><li><p>Update the dependencies. Make sure no vulnerabilities are present. Better yet invest time in automating the security within your build pipelines.</p></li></ul><p>The above are just some of the examples; you may have others depending on your context. But the key thing to remember is without having slack, these activities can&#8217;t be picked up. While some are BAU activities, some cause impediments and others slow down the throughput of the team over time. It is important to prioritise and revisit. </p><div><hr></div><h2>Many bad takes on Prime Video&#8217;s move to monolith from microservices</h2><p>Recently, Amazon Prime Video&#8217;s team published <a href="https://www.primevideotech.com/video-streaming/scaling-up-the-prime-video-audio-video-monitoring-service-and-reducing-costs-by-90">Scaling up the Prime Video audio/video monitoring service and reducing costs by 90%</a> and the internet went wild with their takes on it. Quite a lot of them, quite bad! </p><p>One of the good ones I liked is by <a href="https://me.dm/@adrianco">Adrian Cockraft</a>.</p><blockquote><p><em>&#8220;The Prime Video team had followed a path I call Serverless First, where the first try at building something is put together with Step Functions and Lambda calls. They state in the blog that this was quick to build, which is the point. When you are exploring how to construct something, building a prototype in a few days or weeks is a good approach.</em></p><p><em><strong>The problem is that they called this refactoring a microservice to monolith transition, when it&#8217;s clearly a microservice refactoring step</strong> and is exactly what I recommend people do in my talks about Serverless First&#8221;</em></p><p><em>&#8212; <a href="https://adrianco.medium.com/so-many-bad-takes-what-is-there-to-learn-from-the-prime-video-microservices-to-monolith-story-4bd0970423d4">Source</a></em></p></blockquote><p>His take on why microservices are earning a bad rep:</p><blockquote><p><em>&#8220;In contrast to commentary along the lines that Amazon got it wrong, the team followed what I consider to be the best practice. The result isn&#8217;t a monolith, but there seems to be a popular trigger meme nowadays about microservices being over-sold, and a return to monoliths. <strong>There is some truth to that, as I do think microservices were over sold as the answer to everything, and I think this may have arisen from vendors who wanted to sell Kubernetes</strong> with a simple marketing message that enterprises needed to modernize by using Kubernetes to do cloud native microservices for everything.&#8221;</em></p><p><em>&#8212; <a href="https://adrianco.medium.com/so-many-bad-takes-what-is-there-to-learn-from-the-prime-video-microservices-to-monolith-story-4bd0970423d4">Source</a></em></p></blockquote><p></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>Brief Concept and History of Cryptography</h2><p>Cybersecurity is a vast and burgeoning field. One of the tenets of this area is privacy. Privacy is all about algorithms and best practices to prevent unauthorised users&#8217; from accessing the data that doesn&#8217;t belong to them. The article <a href="https://www.linkedin.com/pulse/cryptography-ashok-hegde?utm_source=share&amp;utm_medium=member_ios&amp;utm_campaign=share_via">Cryptography: Brief Concept and History</a> by <a href="https://www.linkedin.com/in/ashok-hegde-322782">Ashok Hegde</a> is a recommended read.</p><p></p><div><hr></div><p>That&#8217;s a wrap!</p><p>Thank you for reading and being part of the community. If you&#8217;d like to suggest topics to cover or if you&#8217;d like to write for us, do tell us at <a href="mailto:newsletter@partnest.io?subject=Something%20To%20Share">newsletter@partnest.io</a>.</p><p>Have good days! &#127808;</p><div><hr></div>]]></content:encoded></item><item><title><![CDATA[Agile Metrics Sin#2: Unbalanced Metrics]]></title><description><![CDATA[Why is a Balanced Regimen in Agile measurements so important? And why for an overall success, you should measure productivity, quality, predictability and sustainability of your team.]]></description><link>https://www.riverandsoftware.com/p/agile-metrics-sin2-unbalanced-metrics</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/agile-metrics-sin2-unbalanced-metrics</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Mon, 10 Apr 2023 13:16:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!yD2Q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703a7ff-0057-4d8f-8e18-f23b720f6ccf_724x482.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is the second article of a 7-part series of &#8220;Revisiting seven deadly sins of agile measurement&#8221;. Original paper titled &#8220;<a href="https://www.projectmanagement.com/pdf/7DeadlySins_ofAgileMeasurement.pdf">Seven Deadly Sins of Agile Measurement</a>&#8221; was authored by <a href="https://www.linkedin.com/in/larrymaccherone">Larry Maccherone</a>.</p><p>In the <a href="https://open.substack.com/pub/riverandsoftware/p/agile-metrics-sin-1-using-measurement-as-lever?r=yvpqy&amp;utm_campaign=post&amp;utm_medium=web">previous article</a>, we visited why it is important to focus on getting valuable feedback from metrics to focus on improvements and not letting the measures get used as a lever to influence other&#8217;s behaviours. In this article, we&#8217;ll visit why it is necessary to have a balanced metrics regimen.</p><h2>Sin #2: Unbalanced Metrics</h2><p>From the paper:</p><blockquote><p><em>&#8220;The second sin has to do with the need for a balanced metrics regimen. The need for this is fairly readily apparent. If you focus on one aspect of performance (say productivity), other aspects will go down (quality, customer satisfaction, etc.).&#8221;</em></p></blockquote><p>Continuing our wellbeing theme from <a href="https://open.substack.com/pub/riverandsoftware/p/agile-metrics-sin-1-using-measurement-as-lever?r=yvpqy&amp;utm_campaign=post&amp;utm_medium=web">earlier article</a>, just measuring and achieving 10,000 steps in a day certainly won&#8217;t be enough to be qualified as a full-proof step towards your overall wellbeing. What if you ate 2 chocolates on the gloomy Monday? Or went for a couple of craft beers with your friends on Friday to blow off the steam? You would of course need to keep a measure of your diet, your stress levels, sleep habits etc. as a bare minimum to ascertain that you&#8217;re headed towards a better living.</p><p>Intuitively we already know, and the fact is also backed by research that <em>developer satisfaction is important for productivity.[1]</em> While the team might seem productive, but their satisfaction might have taken a dip. Maybe they&#8217;re burnt out because of the extra work load they had to endure to ship that &#8220;important&#8221; delivery. Maybe this is a pattern that keeps repeating. This results in short-term productivity gains and long-term loss in work-satisfaction and even leads to greater than optimal churn.</p><p>Moreover, can we, with certainty, ascertain that just because the team is productive, the overall quality of the product is also high? Or that customer satisfaction is also maintained well? I bet we can&#8217;t. We need <em>observability</em> in other areas too. Hence, the importance of having a balanced regime of measures.</p><p> Larry proposes a well rounded measure from four key areas:</p><blockquote><p><em>&#8220;I recommend that you launch a metrics feedback effort with at least one measure from each of these four areas: </em></p><p><em>1) Do it fast [Responsiveness]</em></p><p><em>2) Do it right [Quality]</em></p><p><em>3) Do it when expected [Predictability], and </em></p><p><em>4) Keep doing it. [Employee Satisfaction]&#8221;</em></p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yD2Q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703a7ff-0057-4d8f-8e18-f23b720f6ccf_724x482.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yD2Q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703a7ff-0057-4d8f-8e18-f23b720f6ccf_724x482.png 424w, https://substackcdn.com/image/fetch/$s_!yD2Q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703a7ff-0057-4d8f-8e18-f23b720f6ccf_724x482.png 848w, https://substackcdn.com/image/fetch/$s_!yD2Q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703a7ff-0057-4d8f-8e18-f23b720f6ccf_724x482.png 1272w, https://substackcdn.com/image/fetch/$s_!yD2Q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703a7ff-0057-4d8f-8e18-f23b720f6ccf_724x482.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yD2Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703a7ff-0057-4d8f-8e18-f23b720f6ccf_724x482.png" width="436" height="290.2651933701657" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1703a7ff-0057-4d8f-8e18-f23b720f6ccf_724x482.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:482,&quot;width&quot;:724,&quot;resizeWidth&quot;:436,&quot;bytes&quot;:259866,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yD2Q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703a7ff-0057-4d8f-8e18-f23b720f6ccf_724x482.png 424w, https://substackcdn.com/image/fetch/$s_!yD2Q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703a7ff-0057-4d8f-8e18-f23b720f6ccf_724x482.png 848w, https://substackcdn.com/image/fetch/$s_!yD2Q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703a7ff-0057-4d8f-8e18-f23b720f6ccf_724x482.png 1272w, https://substackcdn.com/image/fetch/$s_!yD2Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1703a7ff-0057-4d8f-8e18-f23b720f6ccf_724x482.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Well-rounded measure from 4 key areas, viz. Productivity, Quality, Predictability and Employee Satisfaction</figcaption></figure></div><blockquote><p><em>&#8220;These outcomes dimensions form the foundation of the Software Development Performance Index (SDPI), which quantifies insights about development work and provides feedback on how process and technology decisions impact a team&#8217;s performance. Of the metrics in each of the quadrants shown above (productivity, responsiveness, quality, predictability, customer satisfaction, and employee satisfaction), the first four can be extracted from ALM tools [&#8230;]. The fifth and sixth metrics we recommend you gather via lightweight (maybe even single-question) surveys.&#8221;</em></p></blockquote><p></p><h3>Do It Fast (Responsiveness)</h3><p>In the current markets, business model lifetimes have only grown shorter. Naturally, the advantage is with the organisations which are able to adapt changing business goals through software. Inevitably, to be able to ship features and enhancements as quickly as possible, per the changing business models, gives a steep advantage and leverage to make the most out of the dynamic markets.</p><p>Measures like <strong><a href="https://cloud.google.com/blog/products/devops-sre/using-the-four-keys-to-measure-your-devops-performance">lead times</a></strong><a href="https://cloud.google.com/blog/products/devops-sre/using-the-four-keys-to-measure-your-devops-performance"> and </a><strong><a href="https://cloud.google.com/blog/products/devops-sre/using-the-four-keys-to-measure-your-devops-performance">deployment frequencies</a></strong> can give an indicative view of how <a href="http://butunclebob.com/ArticleS.TimOttinger.SoonerNotFaster">fast</a> the software can be shipped. A <strong>Time in State chart </strong>shows you how long your tasks stay in each step of your workflow on their journey to completion. It is a mighty chart to have in hand when you want to understand how quickly your tasks are completed and whether there are bottlenecks in your workflow.</p><p></p><h3>Do It Right (Quality)</h3><p>What is the point of shipping it faster, if that is not what the customer finds useful enough? The quality of software is not just about less buggy features, but also about the quality of UX and data flows. A software that doesn&#8217;t live up to the expectations of its users, or worse makes their job even more cumbersome, might as well never had been made in the first place &#8212; no matter how quickly the team was able to ship it and how early the business was able to capture the initial markets.</p><p>While the quality in terms of <strong>rework</strong> can be tracked via majority of leading tools, customer satisfaction can easily be captured with surveys like <strong>Net Promoter Score</strong>. <strong><a href="https://cloud.google.com/blog/products/devops-sre/using-the-four-keys-to-measure-your-devops-performance">Change failure rate</a></strong><a href="https://cloud.google.com/blog/products/devops-sre/using-the-four-keys-to-measure-your-devops-performance"> and </a><strong><a href="https://cloud.google.com/blog/products/devops-sre/using-the-four-keys-to-measure-your-devops-performance">Time to restore service</a></strong><a href="https://cloud.google.com/blog/products/devops-sre/using-the-four-keys-to-measure-your-devops-performance"> are great indicators of stability</a> too.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/subscribe?"><span>Subscribe now</span></a></p><p></p><h3>Do It On Time (Predictability)</h3><p>Business strategies are future dated. They are seldom siloed to a single business function. It&#8217;s highly likely that there is a marketing team working on how to market the product to the target customer, a sales team preparing the demos and sales pitch, a finance team allocating necessary funds for these related activities. All these activities require coordination to effectively mitigate the dependencies. The predictability of being able to ship the software when it was needed to be is of sheer importance.</p><p>Although, you need to be cautious about falling for the &#8220;estimation is deadline fallacy&#8221;. It is important to have <strong>accuracy over precision </strong>and to <strong><a href="https://www.scrum.org/resources/blog/monte-carlo-forecasting-scrum">incorporate probability when giving forecasts</a>.</strong></p><p></p><h3>Keep Doing It (Employee Satisfaction)</h3><p>Research shows that <em>developer satisfaction is important for productivity.[1]. </em>It is imperative to build <strong>sustainable environments</strong>. Not just a balanced work-life, but developers need an environment which fosters learning and knowledge sharing, and gives the team a sense of <a href="https://en.wikipedia.org/wiki/Maslow's_hierarchy_of_needs">self-actualisation</a>; and does so repeatedly in a sustainable fashion.</p><p>These measures are more <strong>qualitative</strong> in nature. In fact Spotify uses a pure qualitative measure for its teams &#8212; <a href="https://www.riverandsoftware.com/i/109709620/spotifys-squad-health-check-model">Spotify Squad Health Check Model</a></p><p></p><div><hr></div><p>In the next article in this series, we&#8217;ll discuss <strong>Sin #3 &#8212; Believing that metrics can replace thinking</strong>. We&#8217;ll look at why are qualitative measures as important as the quantitative ones, and how well they compliment each other.</p><div><hr></div><p><strong>Notes:</strong></p><ul><li><p><em>[1]</em>: Graziotin D, Wang X, Abrahamsson P. 2014. Happy software developers solve problems better: psychological measurements in empirical software engineering. <em>PeerJ</em> 2:e289 <a href="https://doi.org/10.7717/peerj.289">https://doi.org/10.7717/peerj.289</a></p></li><li><p>If you manage broader goals in your organisation it is worth looking into well rounded measures for organisation -  <a href="https://hbr.org/1992/01/the-balanced-scorecard-measures-that-drive-performance-2">The Balanced Scorecard</a></p></li><li><p>What is DORA Metrics and the Research behind it which proves why these metrics work - <a href="https://www.goodreads.com/book/show/35747076-accelerate">Accelerate</a>, <a href="https://cloud.google.com/blog/products/devops-sre/using-the-four-keys-to-measure-your-devops-performance">Measuring DevOps performance</a>.</p></li><li><p>DevOps Trends in industry and how your team compares to others -  <a href="https://services.google.com/fh/files/misc/2022_state_of_devops_report.pdf">State of Devops Report 2022</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[The Fortnightly. 04.04.23]]></title><description><![CDATA[Highlights: Comic of the fortnight. The "Knowledge is an Investment" metaphor. QWERTY keyboard and path-dependence. And, Why not investing in tests is a "False Economy"!]]></description><link>https://www.riverandsoftware.com/p/the-fortnightly-040423</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/the-fortnightly-040423</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Tue, 04 Apr 2023 15:06:16 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/3ace3afe-2b92-4e19-8e87-e02974dbb03e_984x982.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hope you&#8217;re having a great week so far. <em>This is a fortnightly newsletter in which I share interesting articles, talks, quotes from literature, comic strips &#128522; and many such things that I stumbled upon.</em></p><div><hr></div><p>My favourite comic of the fortnight:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EnG2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5a1b74-b673-429b-831d-27e1a099e645_984x982.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EnG2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5a1b74-b673-429b-831d-27e1a099e645_984x982.png 424w, https://substackcdn.com/image/fetch/$s_!EnG2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5a1b74-b673-429b-831d-27e1a099e645_984x982.png 848w, https://substackcdn.com/image/fetch/$s_!EnG2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5a1b74-b673-429b-831d-27e1a099e645_984x982.png 1272w, https://substackcdn.com/image/fetch/$s_!EnG2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5a1b74-b673-429b-831d-27e1a099e645_984x982.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EnG2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5a1b74-b673-429b-831d-27e1a099e645_984x982.png" width="558" height="556.8658536585366" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8b5a1b74-b673-429b-831d-27e1a099e645_984x982.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:982,&quot;width&quot;:984,&quot;resizeWidth&quot;:558,&quot;bytes&quot;:264109,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EnG2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5a1b74-b673-429b-831d-27e1a099e645_984x982.png 424w, https://substackcdn.com/image/fetch/$s_!EnG2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5a1b74-b673-429b-831d-27e1a099e645_984x982.png 848w, https://substackcdn.com/image/fetch/$s_!EnG2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5a1b74-b673-429b-831d-27e1a099e645_984x982.png 1272w, https://substackcdn.com/image/fetch/$s_!EnG2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5a1b74-b673-429b-831d-27e1a099e645_984x982.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">credits: @_workchronicles</figcaption></figure></div><div><hr></div><h2>The &#8220;Knowledge is an Investment&#8221; metaphor</h2><p>I enjoy re-reading some of the old classics. Mostly, when I get reminded of a vague idea that I fuzzily remember having read in one of the books. Most of the times such triggers are some or the other conversations i&#8217;ve had with interesting people.</p><p>I remember I&#8217;ve read it somewhere. I find my eyes racing along the bookshelf, making a mental note for the n-th time that I need to clean it. I digress.</p><p>I&#8217;m feeling quite confident and take out <a href="https://www.goodreads.com/book/show/113934.The_Goal">The Goal, by M. Goldratt</a>. Flipping through the pages, hoping that I highlighted it, I find it quite sooner than expected. </p><p>It reads&#8230;</p><blockquote><p><em>&#8220;Money for knowledge has us [managers in a manufacturing company] stumped for a while. Then we decide it depends, quite simply, upon what the knowledge is used for. If it's knowledge, say, which gives us a new manufacturing process, something that helps turn inventory into throughput, then the knowledge is operational expense. If we intend to sell the knowledge, as in case of a patent or a technology license, then it's inventory. But if the knowledge pertains to a product which UniCo [the company] itself will build, it's like a machine to make money which will depreciate in value as time goes on. And, again, <strong>the investment that can be sold is inventory; the depreciation is operational expense</strong>.&#8221;<br><br>&#8212; <a href="https://www.goodreads.com/book/show/113934.The_Goal">M. Goldratt, The Goal</a></em></p></blockquote><p></p><p><em>The Goal </em>posits that <strong>the</strong> <strong>goal of any [for-profit] organisation is to make money</strong>. And that all other initiatives are a means of achieving this goal. An organisation does so by <strong>increasing the throughput, while simultaneously reducing both its inventory and operational expenses</strong>. </p><p>In other words, throughput is the money coming in. Inventory is the money currently inside the system. And, operational expense is the money we have to pay out to make throughput happen.</p><p>While it is relatively simpler to visualise this in a manufacturing setup (the original premise in which the book is written), for knowledge-work like in software engineering it is relatively complex to define. </p><p>However, &#8220;<em>knowledge is an investment&#8221;</em> as a metaphor is pretty befitting. In [another classic] <em><a href="https://www.goodreads.com/book/show/4099.The_Pragmatic_Programmer">The Pragmatic Programmer</a></em>, Andy Hunt and Dave Thomas take the investment metaphor and describe keeping up to date with your knowledge as &#8220;<em>Managing a Knowledge Portfolio</em>&#8221;. And just like with an investment portfolio, their advise in managing your knowledge portfolio is to:</p><ul><li><p><strong>Invest regularly</strong>. <em>&#8220;Even if it&#8217;s just a small amount, habit itself is as important as the sums&#8221;</em>, they suggest. Try to read more often than you do now. Go attend meetups. Follow some good twitter and linkedIn (<em>*swallows a big lump</em>) accounts for byte size knowledge streams.</p></li><li><p><strong>Diversify</strong>. Your value grows multifold with more diverse things that you know. Don&#8217;t just stop at learning in depths about the tech that you&#8217;re working on currently. Explore. Get curious about what other tech is being employed in your project, or in your organisation, or around other companies that you find interesting. Networking and attending good meetups helps a lot in this regard.</p></li><li><p><strong>Manage risk</strong>. <em>&#8220;Technology exists along a spectrum from risky, potentially high-reward to low-risk, low-reward standards. It&#8217;s not a good idea to invest all of your money in high-risk stocks that might collapse suddenly, nor should you invest all of it conserva- tively and miss out on possible opportunities. Don&#8217;t put all your technical eggs in one basket</em>.<em>&#8221;</em></p></li><li><p><strong>Buy low, sell high</strong>. <em>&#8220;Learning an emerging technology before it becomes popular can be just as hard as finding an undervalued stock, but the payoff can be just as rewarding&#8221;</em>. Being an early adopter has a great payoff! But remember to manage risk.</p></li><li><p><strong>Review and rebalance</strong>. Software engineering as an industry is quite dynamic. Your next project might be very different from your current one. Other companies might have started looking into some other tech. The framework you were proficient in might be at the stage of its retirement now. Always review your knowledge and keep abreast.</p></li></ul><p>A few helpful trends to watch out for in this regard:</p><ul><li><p>Thoughtwork&#8217;s <a href="https://www.thoughtworks.com/radar">tech-radar</a></p></li><li><p>Gartner&#8217;s <a href="https://www.gartner.com/en">trends</a></p></li><li><p><a href="https://dora.dev/publications/">State of DevOps reports</a></p></li></ul><p>The above by no means is an exhaustive list. But it should be enough get started with.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>QWERTY keyboard and Path-Dependence</h2><p>Path dependence is&nbsp;the <strong>dependence of economic outcomes on the path of previous outcomes, rather than simply on current conditions</strong>. Many a times, the choices made earlier constrain later events or decisions. In a path dependent process, &#8220;history matters&#8221;.</p><p>Take for example, a town that is built around a factory. Ideally, a factory is located at a distance away from residential areas for various legitimate reasons &#8212; primary ones being safety and costs. However, factories are often build first, and then the worker&#8217;s homes and amenities are built close by &#8212; resulting in a town built around a factory. <a href="https://en.wikipedia.org/wiki/Bhilai">Bhilai</a>, a city in Chattishgarh, India, is a great example of such a development; The foundation of which was laid in 1955 when the Indian government signed a historic agreement with the Soviet Union to establish a steel plant near the village.</p><p>Another example of such path-dependent decision is the QWERTY keyboard. The arrangement of letters on QWERTY keyboard was in fact designed to slow down the typing and to avoid jamming of ribbons in a typewriter. People were trained on a QWERTY keyboard. Their habits became so <em>sticky</em> that despite other more efficient keyboard designs like <a href="https://en.wikipedia.org/wiki/Dvorak_Simplified_Keyboard#Comparison_of_the_QWERTY_and_Dvorak_layouts">Dvorak</a>, QWERTY continues to persist dominantly in the market.</p><div><hr></div><h2>Not investing in automated tests is a &#8220;<em>False Economy&#8221;</em>!</h2><p>Writing tests (even if you&#8217;re not doing TDD; although you should whenever possible) is one of the best investments that you can make for your team. At some point, and quite early IME, not having tests begins to cost much higher than what you saved by not writing them in the first place &#8212; aka False Economy!</p><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://twitter.com/nayab_siddiqui/status/1641043333588893697?s=61&amp;t=b4Yxe0abRgrb5VDP1EiWFg&quot;,&quot;full_text&quot;:&quot;You should be testing your code! &quot;,&quot;username&quot;:&quot;Nayab_Siddiqui&quot;,&quot;name&quot;:&quot;Nayab Siddiqui&quot;,&quot;profile_image_url&quot;:&quot;&quot;,&quot;date&quot;:&quot;Wed Mar 29 11:43:14 +0000 2023&quot;,&quot;photos&quot;:[{&quot;img_url&quot;:&quot;https://pbs.substack.com/media/FsYoF28WwAEdWPx.jpg&quot;,&quot;link_url&quot;:&quot;https://t.co/ZzR4V9xwko&quot;,&quot;alt_text&quot;:null}],&quot;quoted_tweet&quot;:{},&quot;reply_count&quot;:0,&quot;retweet_count&quot;:3,&quot;like_count&quot;:10,&quot;impression_count&quot;:0,&quot;expanded_url&quot;:{},&quot;video_url&quot;:null,&quot;belowTheFold&quot;:true}" data-component-name="Twitter2ToDOM"></div><p>Quite hilariously, within a few days of posting this tweet, I had to download my account statement from HDFC bank&#8217;s app. And what do I find? </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EPQJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d87963f-ca5f-4493-b4f6-bf580be1cb95_1600x900.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EPQJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d87963f-ca5f-4493-b4f6-bf580be1cb95_1600x900.png 424w, https://substackcdn.com/image/fetch/$s_!EPQJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d87963f-ca5f-4493-b4f6-bf580be1cb95_1600x900.png 848w, https://substackcdn.com/image/fetch/$s_!EPQJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d87963f-ca5f-4493-b4f6-bf580be1cb95_1600x900.png 1272w, https://substackcdn.com/image/fetch/$s_!EPQJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d87963f-ca5f-4493-b4f6-bf580be1cb95_1600x900.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EPQJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d87963f-ca5f-4493-b4f6-bf580be1cb95_1600x900.png" width="656" height="369" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1d87963f-ca5f-4493-b4f6-bf580be1cb95_1600x900.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:656,&quot;bytes&quot;:234816,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EPQJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d87963f-ca5f-4493-b4f6-bf580be1cb95_1600x900.png 424w, https://substackcdn.com/image/fetch/$s_!EPQJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d87963f-ca5f-4493-b4f6-bf580be1cb95_1600x900.png 848w, https://substackcdn.com/image/fetch/$s_!EPQJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d87963f-ca5f-4493-b4f6-bf580be1cb95_1600x900.png 1272w, https://substackcdn.com/image/fetch/$s_!EPQJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d87963f-ca5f-4493-b4f6-bf580be1cb95_1600x900.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Bug in HDFC app:</strong> &#8216;From&#8217; date must be greater than the &#8216;To&#8217; date. At the same time, &#8216;From&#8217; date cannot be greater than &#8216;To&#8217; date. </figcaption></figure></div><p>Stalemate!</p><p>I&#8217;m very confident this worked earlier and is buggy only recently. So what changed? &#8212; Enhancements without the safety-net of tests!</p><p>Quite interestingly, having no-tests leads to further path-dependent decisions. Your manager might decide to get more manual QAs, or maybe the release will sit longer in UAT now &#8212; all in turn increasing inventory and reducing throughput &#8212; an antithesis of Continuous Delivery!</p><div><hr></div><p>That&#8217;s a wrap! Thank you for reading. </p><p>Wishing you great days ahead! &#127808;</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/p/the-fortnightly-040423?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">This is a public and free newsletter, do share it with your friends. If you have something you&#8217;d like to share, do write to us at newsletter@partnest.io.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/p/the-fortnightly-040423?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/p/the-fortnightly-040423?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><h2></h2>]]></content:encoded></item><item><title><![CDATA[Agile Metrics Sin #1: Using measurement as a lever to drive someone else’s behaviour]]></title><description><![CDATA[Do you use agile metrics as a feedback to improve? Or do your metrics end up influencing other's behaviours, often in unwanted fashion?]]></description><link>https://www.riverandsoftware.com/p/agile-metrics-sin-1-using-measurement-as-lever</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/agile-metrics-sin-1-using-measurement-as-lever</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Tue, 28 Mar 2023 09:46:36 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Xhjz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e79a535-a1b5-4970-a164-2f74bd6102d4_1199x658.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is the first article of a 7-part series of &#8220;Revisiting seven deadly sins of agile measurement&#8221;. Original paper titled &#8220;<a href="https://www.projectmanagement.com/pdf/7DeadlySins_ofAgileMeasurement.pdf">Seven Deadly Sins of Agile Measurement</a>&#8221; was authored by <a href="https://www.linkedin.com/in/larrymaccherone">Larry Maccherone</a>.</p><p>With the advent of data and data analysis, and an immense amount of inspiration from manufacturing industry alone, software engineering continues to employ a plethora of measures to seek the answer to <strong>&#8220;how efficiently do we build our softwares&#8221;</strong>? <a href="https://agilemanifesto.org/">Agile pledges to continue to uncover better ways of writing software</a>. And with uncovering of &#8220;better ways&#8221; arises an innate question of &#8220;Are we doing better and if yes, how do we quantify it?&#8221;</p><p>Agile itself has been interpreted in various ways, Larry writes &#8212;</p><blockquote><p><em>&#8220;Agile can be perceived in different ways: as a manifesto of values or list of principles, as an emphasis on collaboration, as a repackaging of spiral and iterative development concepts, or as the overarching prioritisation of adapting to change over following a plan. I&#8217;ve been around software development long enough to see several of these shifts in perception and I&#8217;ve come to think about all such shifts as reactions to environmental changes, similar to what occurs in nature.&#8221;</em></p></blockquote><p>With newer ways of working and emphasis on collaboration and early feedback, a lot of qualitative measurements were drawn in. But qualitative measurements are not effective, alone, in trying to collaborate with business owners. You can't walk upto your CEO and say &#8220;We should be pair programming as it yields better quality software as per our team&#8221;. This is (usually) not enough. You have to quantify it for them. They know better that just a qualitative feedback is not enough to take critical decisions. You have to bring in &#8220;Pair programming reduced the defects in software by 15% (hypothetical figure) last quarter, we should do it more often&#8221;. This lead to discovering of quantitative measures, clubbed with qualitative measures, to be able to seek the answer to &#8220;Are we really doing better than before?&#8221;.</p><p>Data analysis is like nuclear fission &#8212; use it well and it&#8217;s an evergreen source of valuable insights, use it wrong and it will cause havoc. As much as data can help in better decision making, it can also be evil and lead to malignant behaviour in teams and organisations. Larry identified that with data, there needs to be a necessary perspective shift in order to be use data as a boon, not bane.</p><blockquote><p><em>&#8220;I have been working hard to identify the the key perspective shifts necessary to successfully introduce measurement into an Agile development environment, and I&#8217;ve coined the phrase, &#8220;Seven Deadly Sins of Agile Measurement&#8221; to capture this learning.&#8221; &#8212; Larry Maccherone</em></p></blockquote><p>Let&#8217;s look at the first sin:</p><h1>Sin #1: Using measurement as a lever to drive someone else&#8217;s behaviour </h1><blockquote><p><em>&#8220;If feedback emphasis is key to the success of Agile, the key to effective Agile measurement is to think of measurement in terms of feedback, not as the traditional lever to motivate behaviour. Using measurement as a lever often devolves into keeping score, which is where the dark side of measurement starts.&#8221; &#8212; Larry Maccherone</em></p></blockquote><p>There is a subtle difference between a feedback and a lever:</p><blockquote><p>&#8220;Feedback is something that you use to improve your own performance not to influence other&#8217;s behaviours. <em><strong>The difference is in how you use the measure more than the measure itself.</strong></em>&#8221; </p></blockquote><p>Let&#8217;s take the example of your smart watch; that you wear every day. You need to check upon your daily steps count to make sure you&#8217;ve been active enough. You need this feedback to improve your overall wellbeing. You would never cheat on these figures with yourself. If you&#8217;ve done lesser steps than you aimed for, you will try to do more tomorrow. If you did more steps, you will reward yourself and ask &#8220;Can I do even better?&#8221;. Now imagine your company is &#8220;celebrating a wellbeing month&#8221;. To help spread the awareness and healthy habits, the company decides to reward the employee who does the maximum number of steps over the period of the month. Will you cheat now? Quite a few would &#8212; they would tie up the smart watch to their dogs, try ceiling fans or even put them in drier to maximise the steps. Btw these solutions are not made up, people have actually employed them. Anyways, can you see how people&#8217;s behaviour got influenced? Even when the intention of the company is absolutely pure and selfless. This is how the same data measurement can either behave as a feedback, or as a lever.</p><p>Let&#8217;s take the example of an average cycle-time plot of user stories presented in the paper. Every dot represents a user story, the higher the dot is on the plot, the longer it took for the user story to get delivered. The red line denotes the &#8220;control line&#8221;, meaning anything higher took more than ideal time to get delivered. The red dots represent such outlier user stories.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Xhjz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e79a535-a1b5-4970-a164-2f74bd6102d4_1199x658.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Xhjz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e79a535-a1b5-4970-a164-2f74bd6102d4_1199x658.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Xhjz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e79a535-a1b5-4970-a164-2f74bd6102d4_1199x658.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Xhjz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e79a535-a1b5-4970-a164-2f74bd6102d4_1199x658.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Xhjz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e79a535-a1b5-4970-a164-2f74bd6102d4_1199x658.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Xhjz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e79a535-a1b5-4970-a164-2f74bd6102d4_1199x658.jpeg" width="1199" height="658" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7e79a535-a1b5-4970-a164-2f74bd6102d4_1199x658.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:658,&quot;width&quot;:1199,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:333505,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Xhjz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e79a535-a1b5-4970-a164-2f74bd6102d4_1199x658.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Xhjz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e79a535-a1b5-4970-a164-2f74bd6102d4_1199x658.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Xhjz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e79a535-a1b5-4970-a164-2f74bd6102d4_1199x658.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Xhjz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e79a535-a1b5-4970-a164-2f74bd6102d4_1199x658.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Average Cycle Time</strong>. Shows how long a particular user story takes to get delivered. The red line, called the <strong>control line </strong>denotes longer than ideal times taken. </figcaption></figure></div><p>Larry mentions how such charts can lead to gamifying of the system and hiding the actual data which the team embarked in the first place to seek.</p><blockquote><p><em>&#8220;What&#8217;s going to happen the next time you show this chart? There probably will be fewer red dots, but why? I&#8217;d like to think it will be because people have deeply analysed their process and made necessary changes, blah-blah-blah ... but what&#8217;s more likely is that they will just <strong>game the system</strong> to make sure they don&#8217;t have any red dots. Maybe they&#8217;ll split stories artificially instead of where they deliver value. This is bad because it&#8217;s <strong>wasteful</strong> and doesn&#8217;t improve the process; but what really hurts is that <strong>you&#8217;ve now hidden data from yourself</strong>. <strong>You&#8217;re making decisions with a distorted picture of reality.</strong>&#8221;</em></p></blockquote><p>Replace the above with any similar metric, say your sprint-burndown chart which has that &#8220;ideal burndown line&#8221; for that matter &#8212; the result is going to be similar. </p><p>There are three laws at play now:</p><h3>Measures tend to be gamed when used for target-setting &#8212;  <a href="https://en.wikipedia.org/wiki/Campbell%27s_law">Campbell&#8217;s Law</a></h3><p>The more any quantitative social indicator is used for social decision-making, the more subject it will be to corruption pressures and the more apt it will be to distort and corrupt the social processes it is intended to monitor.</p><p>The team did not achieve a better lead-time. Instead they <strong>gamed</strong> it to achieve the target (to be below the red line). Splitting a story artificially into multiple stories doesn&#8217;t deliver more value to the customer. Neither does by increasing story points to game your velocity. These are false positives.</p><h3>When a measure becomes a target, it ceases to be a good measure &#8212; <a href="https://en.wikipedia.org/wiki/Goodhart%27s_law">Goodhart&#8217;s Law</a></h3><p>The cycle-time measure has become a <strong>waste</strong> now. What the team set out to achieve has gone in vain. Instead they are running after a pseudo target &#8212; to not let their stories cross the red line. In doing so, the <em>actual data </em>has been hidden from the team. The team&#8217;s opportunity to discover the various constraints in the system is lost. With this lost opportunity, the team stands little chance to improve their processes and channel their efforts productively.</p><h3>Individuals will modify an aspect of their behaviour in response to their awareness of being observed &#8212; <a href="https://en.wikipedia.org/wiki/Hawthorne_effect">Hawthorne Effect</a>.</h3><p>Upon being held accountable for the outliers in lead-time plot, the individuals will naturally try to protect themselves. They would give more story points to the story. They would resist in trying new things, say to introduce a new testing strategy or discover a better design pattern &#8212; because they need to deliver fast. Do you think the team stands a fair chance of a good introspection, let alone improvement?</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h1>Inspire Pull and Resist the Push.</h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!58VX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5914e43-aac5-49f1-bcc5-f613055d970a_1252x617.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!58VX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5914e43-aac5-49f1-bcc5-f613055d970a_1252x617.jpeg 424w, https://substackcdn.com/image/fetch/$s_!58VX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5914e43-aac5-49f1-bcc5-f613055d970a_1252x617.jpeg 848w, https://substackcdn.com/image/fetch/$s_!58VX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5914e43-aac5-49f1-bcc5-f613055d970a_1252x617.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!58VX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5914e43-aac5-49f1-bcc5-f613055d970a_1252x617.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!58VX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5914e43-aac5-49f1-bcc5-f613055d970a_1252x617.jpeg" width="1252" height="617" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a5914e43-aac5-49f1-bcc5-f613055d970a_1252x617.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:617,&quot;width&quot;:1252,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:352127,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!58VX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5914e43-aac5-49f1-bcc5-f613055d970a_1252x617.jpeg 424w, https://substackcdn.com/image/fetch/$s_!58VX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5914e43-aac5-49f1-bcc5-f613055d970a_1252x617.jpeg 848w, https://substackcdn.com/image/fetch/$s_!58VX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5914e43-aac5-49f1-bcc5-f613055d970a_1252x617.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!58VX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5914e43-aac5-49f1-bcc5-f613055d970a_1252x617.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">a <strong>Time in State chart </strong>shows you how long your tasks stay in each step of your workflow on their journey to completion. It is a mighty chart to have in hand when you want to understand how quickly your tasks are completed and whether there are bottlenecks in your workflow.</figcaption></figure></div><p>Larry states an alternative:</p><blockquote><p><em>&#8220;As an alternative, I propose this chart:</em></p><p><em>It&#8217;s conceptually very similar to the first chart. The primary difference<br>is the lack of a red line and red dots. This visualization is designed to allow teams to explore their evidence, enabling learning and improvement. You can hover over a dot and get the details about what happened, which should enable discussion. You can talk about probabilities to help gauge risk. You&#8217;ll see that 95% of all stories finish in 28 days; maybe that will help you make a service-level agreement commitment.</em></p><p><em>So, the heavenly virtue here is to inspire pull and resist the push. Use metrics as feedback to improve yourself: never as a lever to alter someone else&#8217;s behavior.&#8221;</em></p></blockquote><p>The above is a <strong>Time in State chart </strong>which<strong> </strong>shows you how long your tasks stay in each step of your workflow on their journey to completion. It is a mighty chart to have in hand when you want to understand how quickly your tasks are completed and whether there are bottlenecks in your workflow.</p><p>Software development has lots of steps and handshakes in between. Typically, a story would get groomed and would be ready for development. Developers will work on the story and (usually) raise a PR for the changes to get merged. One or two reviewers would review the code and sometimes ask for a bit of changes to be made. After the changes, the story would be tested by the QA team. If found acceptable, the build would be shipped to production, if not it will have to be sent back to development for rework. </p><p>Every step is a handover, from one person (or a team) to another. Every handover has a <strong>wait time</strong> and <strong>a processing time</strong> &#8212; imagine every step as a processor which takes x amount of processing time to work on the item and while it is working, there would be work items that will wait for y units of time in the queue to be eventually picked up for processing. The overall cycle time would be a summation of such x(s) and y(s). Every now and then one or more such handovers become a <a href="https://en.wikipedia.org/wiki/Theory_of_constraints">constraint</a> in your system. It is more important to focus on the constraint, rather than trying to <a href="https://en.wikipedia.org/wiki/Local_optimum">locally optimise</a> (or gaming things).</p><p>A good metric helps uncover such constraints. A good metric helps team retrospect and think. A good metric helps supporting or refuting a hypothesis. A good metric helps in making improvements and increases <a href="https://www.youtube.com/watch?v=zLk0YmV5dyQ">flow efficiency</a>.</p><div class="pullquote"><p><strong>A good measure inspires pull and resists push!</strong></p></div><p>In the <a href="https://newsletter.partnest.io/p/agile-metrics-sin2-unbalanced-metrics">next article</a> in this series, we&#8217;ll discuss <strong>Sin #2 &#8212; Unbalanced Metrics</strong>. We&#8217;ll look at why is it important to have a balanced metrics scheme. And why it is imperative to measure other aspects of software engineering &#8212; not just productivity, but also customer satisfaction, quality, employee satisfaction etc.</p><div><hr></div><p><strong>Notes</strong></p><ol><li><p>Theory of Constraints - <a href="https://www.goodreads.com/book/show/113934.The_Goal">The Goal</a>, <a href="https://www.goodreads.com/book/show/848514.Critical_Chain">Critical Chain</a>, <a href="https://www.goodreads.com/book/show/44333183-the-unicorn-project">The Unicorn Project</a></p></li><li><p>Lean Methodology - <a href="https://www.goodreads.com/book/show/10127019-the-lean-startup">The Lean Startup</a></p></li><li><p>Flow Efficiency - <a href="https://www.youtube.com/watch?v=zLk0YmV5dyQ">Hakan Forss: Flow Thinking</a></p></li></ol><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/p/agile-metrics-sin-1-using-measurement-as-lever?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thank you for reading the article. If you have interesting insights to share or you have something that you would want us to write about, do <a href="mailto:newsletter@partnest.io?subject=Something%20To%Share">write to us</a> at newsletter@partnest.io</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/p/agile-metrics-sin-1-using-measurement-as-lever?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/p/agile-metrics-sin-1-using-measurement-as-lever?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div>]]></content:encoded></item><item><title><![CDATA[The Fortnightly. 21.03.23]]></title><description><![CDATA[Highlights: A mental model on having meaningful discussions. How Spotify uses Squad Health-Checks as a model for continuous improvement. One of the best introductory talks on functional programming.]]></description><link>https://www.riverandsoftware.com/p/the-fortnightly-by-partnest-210323</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/the-fortnightly-by-partnest-210323</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Tue, 21 Mar 2023 16:04:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!5oet!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e303579-943f-4d6c-b207-0bbc8118a1bf_1380x1380.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hope you&#8217;re having a great week so far.</p><div class="pullquote"><p><em>This is a fortnightly newsletter in which I share interesting articles, talks, quotes from literature, comic strips &#128522; and many such things that I stumbled upon.</em></p></div><p>My favourite comic of the fortnight:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5oet!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e303579-943f-4d6c-b207-0bbc8118a1bf_1380x1380.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5oet!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e303579-943f-4d6c-b207-0bbc8118a1bf_1380x1380.png 424w, https://substackcdn.com/image/fetch/$s_!5oet!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e303579-943f-4d6c-b207-0bbc8118a1bf_1380x1380.png 848w, https://substackcdn.com/image/fetch/$s_!5oet!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e303579-943f-4d6c-b207-0bbc8118a1bf_1380x1380.png 1272w, https://substackcdn.com/image/fetch/$s_!5oet!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e303579-943f-4d6c-b207-0bbc8118a1bf_1380x1380.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5oet!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e303579-943f-4d6c-b207-0bbc8118a1bf_1380x1380.png" width="556" height="556" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5e303579-943f-4d6c-b207-0bbc8118a1bf_1380x1380.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1380,&quot;width&quot;:1380,&quot;resizeWidth&quot;:556,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!5oet!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e303579-943f-4d6c-b207-0bbc8118a1bf_1380x1380.png 424w, https://substackcdn.com/image/fetch/$s_!5oet!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e303579-943f-4d6c-b207-0bbc8118a1bf_1380x1380.png 848w, https://substackcdn.com/image/fetch/$s_!5oet!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e303579-943f-4d6c-b207-0bbc8118a1bf_1380x1380.png 1272w, https://substackcdn.com/image/fetch/$s_!5oet!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e303579-943f-4d6c-b207-0bbc8118a1bf_1380x1380.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Credit: @vincentdnl</figcaption></figure></div><h2></h2><div><hr></div><h2>People cannot have a fruitful discussion on topics that are part of their identity. &#8212; <a href="https://twitter.com/paulg?s=21&amp;t=b4Yxe0abRgrb5VDP1EiWFg">Paul Graham</a></h2><p>Paul writes that religion and politics eventually become part of the identity of people. In such cases the discussion ceases to be about the topic at hand and instead becomes about people&#8217;s identities themselves. At this point of time, the discussion ceases to be meaningful for either of the participants. </p><blockquote><p><em>&#8220;As a rule, any mention of religion on an online forum degenerates into a religious argument. Why? Why does this happen with religion and not with Javascript or baking or other topics people talk about on forums?</em></p><p><em>What's different about religion is that people don't feel they need to have any particular expertise to have opinions about it. All they need is strongly held beliefs, and anyone can have those. No thread about Javascript will grow as fast as one about religion, because people feel they have to be over some threshold of expertise to post comments about that. But on religion everyone's an expert.</em></p><p><em>Then it struck me: this is the problem with politics too. </em></p><p><em>[&#8230;]</em></p><p><em>I think what religion and politics have in common is that they become part of people's identity, and people can never have a fruitful argument about something that's part of their identity. By definition they're partisan.&#8221;</em></p><p>&#8212; <a href="http://www.paulgraham.com/identity.html">Keep your identity small, Paul Graham.</a></p></blockquote><p>Each and every one of us has witnessed or (and) been part of an opinionated discussion which doesn&#8217;t seem to head towards any outcome. The more strongly we hold our opinions, the more they embed themselves in our identities. An attack on our opinion seems like an attack on ourselves.</p><p>The key to have a meaningful discussion, then, is to <em><strong>keep your identity small</strong></em>.</p><blockquote><p><em>The most intriguing thing about this theory, if it's right, is that it explains not merely which kinds of discussions to avoid, but how to have better ideas. If people can't think clearly about anything that has become part of their identity, then all other things being equal, the best plan is to let as few things into your identity as possible.</em></p><p>&#8212; <a href="http://www.paulgraham.com/identity.html">Keep your identity small, Paul Graham.</a></p></blockquote><p></p><div><hr></div><h2>Spotify&#8217;s Squad Health Check Model</h2><p>Spotify uses a qualitative and human-centric approach towards improvement and gaining insights into &#8220;how are their teams doing?&#8221;.</p><h4>Key Insights:</h4><ul><li><p>Qualitative data on a squad&#8217;s health is gathered through <strong>face to face discussions</strong>; and online-surveys are avoided. The discussions help in gaining meaningful insights and context, which often get missed in online surveys.</p></li><li><p>Such a model works only when there is <strong>high-trust, curiosity and psychological safety</strong> within the environment.</p></li><li><p>The <strong>data is collected through a lean model</strong> with the help of their health-indicators cards called &#8220;<a href="https://storage.googleapis.com/production-eng/1/2014/09/squad-health-check-model2.pdf">Awesome Cards</a>&#8221;. The cards contain an example of &#8220;what good looks like&#8221; and an example of &#8220;what crappy looks like&#8221;. Each card stands for an aspect of work that the team is interested in learning more about, for e.g. &#8220;Ease of release&#8221;, &#8220;Health of codebase&#8221;, &#8220;Delivering Value&#8221; etc.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SGOm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67645f78-127d-4247-acc1-e4974a323cd0_1984x714.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SGOm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67645f78-127d-4247-acc1-e4974a323cd0_1984x714.png 424w, https://substackcdn.com/image/fetch/$s_!SGOm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67645f78-127d-4247-acc1-e4974a323cd0_1984x714.png 848w, https://substackcdn.com/image/fetch/$s_!SGOm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67645f78-127d-4247-acc1-e4974a323cd0_1984x714.png 1272w, https://substackcdn.com/image/fetch/$s_!SGOm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67645f78-127d-4247-acc1-e4974a323cd0_1984x714.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SGOm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67645f78-127d-4247-acc1-e4974a323cd0_1984x714.png" width="1456" height="524" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/67645f78-127d-4247-acc1-e4974a323cd0_1984x714.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:524,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:410215,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!SGOm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67645f78-127d-4247-acc1-e4974a323cd0_1984x714.png 424w, https://substackcdn.com/image/fetch/$s_!SGOm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67645f78-127d-4247-acc1-e4974a323cd0_1984x714.png 848w, https://substackcdn.com/image/fetch/$s_!SGOm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67645f78-127d-4247-acc1-e4974a323cd0_1984x714.png 1272w, https://substackcdn.com/image/fetch/$s_!SGOm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67645f78-127d-4247-acc1-e4974a323cd0_1984x714.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Example cards used in health-checks. Source: Spotify</figcaption></figure></div></li><li><p>Results, when put collectively for all squads gives an easy reflection on how the company as a whole is doing.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kFmU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53784550-4f69-4b55-a808-ca55472ae6d1_565x411.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kFmU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53784550-4f69-4b55-a808-ca55472ae6d1_565x411.png 424w, https://substackcdn.com/image/fetch/$s_!kFmU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53784550-4f69-4b55-a808-ca55472ae6d1_565x411.png 848w, https://substackcdn.com/image/fetch/$s_!kFmU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53784550-4f69-4b55-a808-ca55472ae6d1_565x411.png 1272w, https://substackcdn.com/image/fetch/$s_!kFmU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53784550-4f69-4b55-a808-ca55472ae6d1_565x411.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kFmU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53784550-4f69-4b55-a808-ca55472ae6d1_565x411.png" width="565" height="411" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/53784550-4f69-4b55-a808-ca55472ae6d1_565x411.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:411,&quot;width&quot;:565,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:275464,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kFmU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53784550-4f69-4b55-a808-ca55472ae6d1_565x411.png 424w, https://substackcdn.com/image/fetch/$s_!kFmU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53784550-4f69-4b55-a808-ca55472ae6d1_565x411.png 848w, https://substackcdn.com/image/fetch/$s_!kFmU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53784550-4f69-4b55-a808-ca55472ae6d1_565x411.png 1272w, https://substackcdn.com/image/fetch/$s_!kFmU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53784550-4f69-4b55-a808-ca55472ae6d1_565x411.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Example results of all squads put together. Source: Spotify.</figcaption></figure></div></li></ul><blockquote><p><em>&#8220;It shows how 7 different squads in a tribe see their own situation. Color is current state (green = good, yellow = some problems, red = really bad). Arrow is the trend (is this generally improving or getting worse?).</em></p><p><em>Stare at it for a minute, and you start seeing some interesting things:</em></p><p><em><strong>Scan each column</strong>, and you see some major differences between squads. Squad 4 is happy with just about everything. Squad 2 is having lots of trouble, but most things are improving.</em></p><p><em><strong>Scan each row</strong>, and you see systemic patterns. Every squad is having fun (and it&#8217;s even improving)! Motivation is apparently not a problem at all. But the release process is problematic, and the codebase is overall in bad shape. Over time, that will probably reduce the Fun as well.</em></p><p><em><strong>Scan the overall picture,</strong>&nbsp;and you see that just about every arrow is up, only two down arrow in the whole picture. That means the improvement process (the most important process of all) seems to be working.&#8221;</em></p><p>&#8212; <a href="https://engineering.atspotify.com/2014/09/squad-health-check-model/">Spotify</a></p></blockquote><ul><li><p>Each team itself is <strong>responsible</strong> and encouraged to modify the model, supporting collective autonomy within squads and how they choose to <em>learn </em>about their work.</p></li><li><p>Health-checks are designed to have <strong>no incentives</strong>, in order to prevent them from getting gamed.</p></li><li><p>Follow ups with teams to <strong>gauge the usefulness of the model</strong> for them and feed back the insights towards improving the model, thus fostering a virtuous cycle.</p></li></ul><p></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/subscribe?"><span>Subscribe now</span></a></p><p></p><p>Watch Spotify&#8217;s latest talk on Squad Health Checks:</p><div id="youtube2-MeFHca85RE4" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;MeFHca85RE4&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/MeFHca85RE4?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><h2></h2><div><hr></div><h2>Functional Design Patterns by Scott Wlaschin</h2><p>This is one of the best talks out there which introduces functional programming paradigms and patterns without getting into [too much] theoretical concepts about Category Theory.</p><p>A highly recommended watch for folks trying to learn FP patterns. Equally recommended as a leisure watch for seasoned FP and Category Theory enthusiasts &#8212; you&#8217;ll appreciate the simplicity of Scott&#8217;s explanations. </p><div id="youtube2-srQt1NAHYC0" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;srQt1NAHYC0&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/srQt1NAHYC0?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>Do explore his <a href="https://fsharpforfunandprofit.com/fppatterns/">website</a> for more interesting articles and talks.</p><p></p><div><hr></div><p>Thank you for reading. This is a public and free newsletter, do share it with your friends if you liked it. If you have something you&#8217;d like to share, do write to us at newsletter@partnest.io.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/p/the-fortnightly-by-partnest-210323?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/p/the-fortnightly-by-partnest-210323?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[Don't use acronyms while naming things : It Depends]]></title><description><![CDATA[In Clean Code universe, it is highly advised to not use acronyms while naming things. But should this be a universal law? Like most things software, it depends! Let's explore on what it depends.]]></description><link>https://www.riverandsoftware.com/p/dont-use-acronyms-while-naming-things</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/dont-use-acronyms-while-naming-things</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Thu, 09 Mar 2023 16:02:49 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!MaEJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fpbs.substack.com%2Fmedia%2FCNWtpmpUsAA7MCz.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p><em>There are only two hard things in Computer Science: cache invalidation and naming things.</em></p><p><em>&#8212; Phil Karlton</em></p></blockquote><p>What is the goal of naming things in software and naming them &#8220;right&#8221;? &#8212; To reveal the clear intent. By intent, we mean the name of the variable, or function, or module etc., correctly represents its purpose. A name which reveals its<strong> </strong>intent clearly<strong> reduces cognitive load</strong> on developers&#8217; minds.</p><p>Naturally, naming is neither a one step process nor an individual&#8217;s exercise. It is a team game and as <a href="https://twitter.com/arlobelshee">@arlobelshee</a> points out it is an iterative process, with each iteration your naming approaches a <strong>supple design</strong> (DDD).</p><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://twitter.com/arlobelshee/status/636605852984545280?s=20&quot;,&quot;full_text&quot;:&quot;The 7 stages of naming, now with better image. &quot;,&quot;username&quot;:&quot;arlobelshee&quot;,&quot;name&quot;:&quot;Arlo Belshee&quot;,&quot;profile_image_url&quot;:&quot;&quot;,&quot;date&quot;:&quot;Wed Aug 26 18:27:17 +0000 2015&quot;,&quot;photos&quot;:[{&quot;img_url&quot;:&quot;https://pbs.substack.com/media/CNWtpmpUsAA7MCz.png&quot;,&quot;link_url&quot;:&quot;http://t.co/8BQptfV0oH&quot;,&quot;alt_text&quot;:null}],&quot;quoted_tweet&quot;:{},&quot;reply_count&quot;:0,&quot;retweet_count&quot;:172,&quot;like_count&quot;:232,&quot;impression_count&quot;:0,&quot;expanded_url&quot;:{},&quot;video_url&quot;:null,&quot;belowTheFold&quot;:false}" data-component-name="Twitter2ToDOM"></div><p>The intent, however, is not supposed to be just clear to developers, but to the entire team. A typical team would be cross functional &#8212; it would not just have engineers, but also domain experts, marketing, and product folks. The entire team should use one language &#8212; the <strong>ubiquitous language</strong>.</p><p>In one of the large scale projects which I was a part of, we were developing a business &#8220;proposal calculator&#8221; for a large bank. The &#8220;proposal calculator&#8221; was supposed to run 1000s of calculations and tell whether a proposed corporate deal was beneficial for the bank or not. Long story short, naturally there were a lot of financial terms that were part of daily conversations. PnL, collaterals, amortisation to name a few. </p><p>A lot of such terms were used as their acronyms, instead of their full forms, by the bankers (the domain folks) in their own conversations and also when they referred to such calculations to us (the developers). So they would not say &#8220;Profit and Loss&#8221;, but &#8220;PnL&#8221;. They would not say &#8220;Return on Risk Weighted Assets&#8221;, but &#8220;RoRWA&#8221; (pronounced <em>row-rah</em>).</p><p>Early in our design phase we took a conscious decision of going ahead and using the acronyms themselves instead of their long forms. In hindsight it was a good judgement call by the team, especially when all literature around clean code was advising otherwise. The literature would advise to use pronounceable names and only use acronyms when they were widely known &#8212; highly debatable and very contextual. Turns out RoRWA wasn&#8217;t that widely known amongst developers atleast.</p><p>Imagine if we had not &#8212; When developers would have had conversations amongst themselves, we would use &#8220;Profit and Loss&#8221;. But whenever we would be in meetings with the domain folks, we would only hear &#8220;PnL&#8221;. Imagine the fiasco when &#8220;Return on Risk Weighted Assets&#8221; would come into such conversations. Moreover, our use-cases which were written primarily by domain people would only contain such acronyms, not their full forms. Not only we would have <strong>added unwanted cognitive load</strong> upon ourselves, since we would always be playing this ontology game of mapping the acronyms with their full forms, but we would have also <strong>made the conversations difficult</strong>, because the domain folks were more comfortable with acronyms themselves.</p><p>It was difficult to onboard new developers at first. Imagine yourself hearing PnL vs hearing &#8220;Profit and Loss&#8221;, especially when you do that have acquaintance with financial terms. Your mind can make some sense out of &#8220;Profit and Loss&#8221; in the very first go &#8212; because basic mathematics &#8212; but won&#8217;t comprehend PnL naturally. This was the case with some common-sensical terms, but &#8220;Return on Risk Weighted Assets&#8221; would still not make sense. The team came up with a <strong>glossary</strong>. It helped heaps, not just for the new developers, but also for the ones who had been on the project for considerable amount of time. </p><p>We made a conscious effort to keep the glossary as <strong>a living document</strong> &#8212; forever changing and changing as frequently as was the need. We would refer to it whenever we had a doubt, added questions to it and added lots of examples. We also shared this glossary with the bankers and they generously added enough information to it. At times they added  more information &#8212; just to make us, the financial-rookies understand &#8212; than was required to be able to successfully model it in our code. But it eventually gave us the comfort and cognitive ease which we needed, but didn&#8217;t know we did.</p><div class="pullquote"><p>Remember, DDD is a team activity!</p></div><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/p/dont-use-acronyms-while-naming-things?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thank you for reading. Let us know about your unconventional experiences with naming things. If you found the article useful, please do share it.&#128406;</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/p/dont-use-acronyms-while-naming-things?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/p/dont-use-acronyms-while-naming-things?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Organisations: Through the lens of Emergence.]]></title><description><![CDATA[Why most of our attempts at replicating the success(es) of our &#8220;hero&#8221; organisations in our companies are futile, naive even!]]></description><link>https://www.riverandsoftware.com/p/organisations-through-the-lens-of-emergence-5c80fb2e956f</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/organisations-through-the-lens-of-emergence-5c80fb2e956f</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Sat, 24 Sep 2022 08:54:11 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/38190877-1e09-4bb1-9f1c-22f7a4ecf513_1024x1421.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4>Why most of our attempts at replicating the success(es) of our &#8220;hero&#8221; organisations in our companies are futile, naive even! And how organisations are Complex Adaptive&nbsp;Systems.</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tX66!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff50bd82b-f87e-4a96-92da-ac5c99635a2a_1024x1421.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tX66!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff50bd82b-f87e-4a96-92da-ac5c99635a2a_1024x1421.jpeg 424w, https://substackcdn.com/image/fetch/$s_!tX66!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff50bd82b-f87e-4a96-92da-ac5c99635a2a_1024x1421.jpeg 848w, https://substackcdn.com/image/fetch/$s_!tX66!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff50bd82b-f87e-4a96-92da-ac5c99635a2a_1024x1421.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!tX66!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff50bd82b-f87e-4a96-92da-ac5c99635a2a_1024x1421.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tX66!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff50bd82b-f87e-4a96-92da-ac5c99635a2a_1024x1421.jpeg" width="1024" height="1421" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f50bd82b-f87e-4a96-92da-ac5c99635a2a_1024x1421.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1421,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!tX66!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff50bd82b-f87e-4a96-92da-ac5c99635a2a_1024x1421.jpeg 424w, https://substackcdn.com/image/fetch/$s_!tX66!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff50bd82b-f87e-4a96-92da-ac5c99635a2a_1024x1421.jpeg 848w, https://substackcdn.com/image/fetch/$s_!tX66!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff50bd82b-f87e-4a96-92da-ac5c99635a2a_1024x1421.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!tX66!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff50bd82b-f87e-4a96-92da-ac5c99635a2a_1024x1421.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@anniespratt?utm_source=medium&amp;utm_medium=referral">Annie Spratt</a> on&nbsp;<a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure></div><p>We are in constant awe of the innovation culture at Google. We all revere the autonomous teams at Netflix. We all get inspired by the result-driven nature of the small (pizza sized) teams that Amazon created. We revere such companies so much that we start attempting to replicate (or at-least in theory) their mannerisms in the hope to be able to replicate the &#8220;magic&#8221; that such organisations were able to create for themselves.</p><p>However, trying to be like a Google, Netflix or an Amazon (or any other organisation for that matter) is trying to trivialise the complex adaptive system that an organisation is. An organisation is, ultimately, made up of many individual components which are hard to replicate and difficult to reason with a reductionist approach.</p><h3></h3><div><hr></div><h2>&#8220;Which part of the airplane is responsible for its flight?&#8221;&nbsp;: Emergence</h2><p>To further the reasoning, it is important to recall the concept of <em><strong>Emergence</strong></em>.</p><blockquote><p>When systems as a whole function in ways that we cannot predict by looking at their individual parts&#8202;&#8212;&#8202;This is emergence.</p><p>Emergence occurs when an entity is observed to have properties its parts do not have on their own, properties or behaviours that emerge only when the parts interact in a wider whole. In short, one cannot understand the systems with emergent properties by reducing them to their components.</p></blockquote><p>An airplane can be conceptualised as being composed of various engineered parts. Each individual part is responsible for handling a single function, which it is designed for, and handling it well. But it&#8217;s not a single component (or two) that is responsible for the flight itself. It&#8217;s the complex interactions of those individual parts, as a whole, orchestrated by a fine pilot that makes it possible for the hundreds of tonnes of machinery to be able to fly. So, can one answer: &#8220;Which part of the airplane is responsible for its flight?&#8221;.</p><p>Emergence is all around us. While hydrogen and oxygen exhibit their own properties, the property of <em>wetness </em>is an <em>emergent</em> property of water (and not exhibited by either hydrogen and oxygen individually) which only emerges when hydrogen and oxygen combine in a specific&nbsp;manner.</p><p>Emergence, however, is not alike in all the complex systems. Given enough computational power it is possible to simulate a <em>weak emergence</em> wherein systems exhibit functions identifyable by fixed rules. However, doing so for <em>strong emergence</em> is impossible.</p><blockquote><p>We can construct a computer simulation of the flocking behaviour of a group of birds (weak emergence) but not of the interplay of cells in our brains that creates consciousness (strong emergence)</p><p>&#8212; an excerpt from &#8220;The Great Mental Models&#8221;, by Rhiannon Beaubien and Shane&nbsp;Parrish</p></blockquote><p>Building upon, individually, humans exhibit certain characteristics which are unique to themselves. The emergence lens suggests that the cumulative actions of a group of people is bigger and non-intuitive while considering the individual people&#8217;s characteristics themselves. These groups of people create a <em>behaviour </em>unique to an organisation, in turn, making every organisation unique in&nbsp;itself.</p><h3></h3><div><hr></div><h2>If it walks like a duck, quacks like a duck, it must be a&nbsp;duck!</h2><p>There have been ample articles, books and talks by the experts themselves on how they helped grow and lead an organisation to the success it is known for, what policies they formulated, what initiatives they ran. When Google released information about their &#8220;20 percent rule&#8221; a lot of organisations jumped at implementing them. A similar pattern happened when Google talked about&nbsp;&#8220;OKRs&#8221;.</p><p>Amazon&#8217;s case is no stranger to this pattern. When it attributed a lot of its success to the &#8220;2 pizza sided teams&#8221;, every other organisation, coaches alike wanted to jump and execute&nbsp;it.</p><p>Also, how can we forget about the famous &#8220;culture deck&#8221; from Netflix&nbsp;?!?</p><p>Learning about the framework responsible behind a success story is one thing, being able to replicate it within your environment is&nbsp;another.</p><p>In his book <a href="https://en.wikipedia.org/wiki/The_Fifth_Discipline">The Fifth Discipline</a>, Peter M. Senge&nbsp;writes:</p><blockquote><p><strong>&#8220;</strong>Practicing a discipline is different from emulating a model. All too often, new management innovations are described in terms of &#8220;best practices&#8221; of so called leading&nbsp;firms.</p><p>I (Peter Senge) believe benchmarking &#8220;best practices&#8221; can open people&#8217;s eyes as to what is possible, but it can also do more harm than good, leading to piecemeal copying and playing catch-up<strong>&#8221;</strong></p></blockquote><h3></h3><div><hr></div><h2>A butterfly flaps its wings and a typhoon is&nbsp;caused!</h2><p><a href="https://um-boston.academia.edu/DavidLevy">David Levy</a> conceptualises how industries are complex, dynamic, and non-linear systems in his&nbsp;paper:</p><blockquote><p>Firms interact with each other and with other actors in their environment, such as customers, labor, the government and financial institutions. These interactions are strategic in the sense that decisions by one actor take into account anticipated reactions by others, and this reflect a recognition of interdependence.</p><p>&#8212; David Levy, &#8220;Chaos Theory and Strategy: Theory, Application, and Managerial Implications</p></blockquote><p>Explaining the nature of chaotic systems further, David highlights that small disturbances multiple over time and that such systems are extremely sensitive to initial conditions, which makes forecasting very difficult. This is a formal study in chaos theory, often known as <em><a href="https://en.wikipedia.org/wiki/Butterfly_effect">butterfly effect</a>, </em>a term closely associated with renowned mathematician and meteorologist <a href="https://en.wikipedia.org/wiki/Edward_Norton_Lorenz">Edward&nbsp;Lorenz</a>.</p><p>So if the organisations are chaotic systems and chaotic systems are highly sensitive to their starting conditions (the nature of market at the given point of time, the people present, the scale, the developments in competitive landscape etc.), can we, with confidence, ever really be sure how the same policies will fan out in another organisation? Sure, we might be able to get some benefits out of the detailed frameworks laid out by successful organisations. The benefits might not be the same benefits that the original organisation achieved. And sometimes that&#8217;s acceptable too I&nbsp;guess.</p><h3></h3><div><hr></div><h2>Fooled by Randomness</h2><p>What is even worse is when we achieve initial <em>success</em> by piecemeal copying of the &#8220;best practices&#8221; and convince ourselves that &#8220;we have got it right!&#8221;. We have to challenge ourselves in ascertaining how much of our initial success was skill and how much was&nbsp;luck.</p><p>We tend to give ourselves too much credit for something that might just be an act of luck. The reverse is also true: we beat ourselves in the event of failure, more so because in organisations there is immense pressure on the leaders and managers to <em>lead</em> and &#8220;to be right&#8221;. We are not that great at comprehending true randomness.</p><blockquote><p>&#8220;The human mind is built to identify for each event a definite cause and can, therefore, have a hard time accepting the influence of unrelated or random&nbsp;factors&#8221;</p><p>&#8212; Leonard Mlodinow, The Drunkard&#8217;s Walk: How Randomness Rules Our&nbsp;Lives</p></blockquote><p>All hope is lost? Not quite. In fact quite the opposite. Being aware of the complexities and uncertainties (randomness) is a strong base (some would argue the very first step even) required to be able to work around them, to be able to make better decisions to foster your company&#8217;s prosperity. If you don&#8217;t know about them, that&#8217;s a bigger problem. Because you&#8217;re just playing&nbsp;luck!</p><p>So what can be done? Well, one of the starting approaches is to develop a <em>systemic (</em>Systems Thinking<em>) </em>approach, to be able to see the <em>causality</em> among various parts of a system (more on this in the upcoming blogs), and not just trying to <a href="https://en.wikipedia.org/wiki/Local_optimum">optimise the individual parts</a>.</p><p>When you&#8217;re looking to get inspired by any of the industry leading &#8220;best practices&#8221;, try to get into more details. Get rudimentary. This doesn&#8217;t mean to over simplify and trivialise things. Try to codify what values would have been required to uphold the vision, what principles would have been required to bridge the values and practices to make the initiative a success. Qualify which pieces are missing in your org/team and what can be done to find/substitute them.</p><p>The more the number of teams that get involved, at a given time with such initiatives in an organisation, the better the chances of getting a holistic view and able to realise the interdependencies.</p><p>On the closing note, a <a href="https://fs.blog/decision-journal/">decision journal</a> goes a long way in learning what worked and what didn&#8217;t. Remember that you need to avoid getting&nbsp;lucky!</p><div><hr></div><p><a href="https://medium.com/geekculture/organisations-through-the-lens-of-emergence-5c80fb2e956f">Organisations: Through the lens of Emergence.</a> was originally published in <a href="https://medium.com/geekculture">Geek Culture</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded></item><item><title><![CDATA[Type Safe and Exhaustive ‘switch’ statements, aka Pattern Matching in TypeScript]]></title><description><![CDATA[How to get TypeScript compiler to ascertain type safe and exhaustive matching in switch statement.]]></description><link>https://www.riverandsoftware.com/p/type-safe-and-exhaustive-switch-statements-aka-pattern-matching-in-typescript-e3febd433a7a</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/type-safe-and-exhaustive-switch-statements-aka-pattern-matching-in-typescript-e3febd433a7a</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Mon, 31 Jan 2022 06:02:06 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/4701560b-1b03-4549-908b-e9b1e0d942da_1024x682.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4>How to get TypeScript compiler to ascertain type safe and exhaustive matching in switch statement. Without using any external libraries.</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!__f5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F639be5eb-ccb4-4d26-9e6e-57ab963ee0b2_1024x682.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!__f5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F639be5eb-ccb4-4d26-9e6e-57ab963ee0b2_1024x682.jpeg 424w, https://substackcdn.com/image/fetch/$s_!__f5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F639be5eb-ccb4-4d26-9e6e-57ab963ee0b2_1024x682.jpeg 848w, https://substackcdn.com/image/fetch/$s_!__f5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F639be5eb-ccb4-4d26-9e6e-57ab963ee0b2_1024x682.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!__f5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F639be5eb-ccb4-4d26-9e6e-57ab963ee0b2_1024x682.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!__f5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F639be5eb-ccb4-4d26-9e6e-57ab963ee0b2_1024x682.jpeg" width="1024" height="682" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/639be5eb-ccb4-4d26-9e6e-57ab963ee0b2_1024x682.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:682,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!__f5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F639be5eb-ccb4-4d26-9e6e-57ab963ee0b2_1024x682.jpeg 424w, https://substackcdn.com/image/fetch/$s_!__f5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F639be5eb-ccb4-4d26-9e6e-57ab963ee0b2_1024x682.jpeg 848w, https://substackcdn.com/image/fetch/$s_!__f5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F639be5eb-ccb4-4d26-9e6e-57ab963ee0b2_1024x682.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!__f5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F639be5eb-ccb4-4d26-9e6e-57ab963ee0b2_1024x682.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@alimor?utm_source=medium&amp;utm_medium=referral">Mor THIAM</a> on&nbsp;<a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure></div><h2>Motivation</h2><p>Being a bit inclined towards functional programming, I wanted to try and build a &#8220;type safe&#8221; and &#8220;exhaustive&#8221; <em>Pattern Matching </em>in TypeScript, without using any additional libraries, and only using <em>switch </em>statements and the power of <a href="https://www.typescriptlang.org/docs/handbook/type-inference.html">Type Inference</a> and <a href="https://www.typescriptlang.org/docs/handbook/2/narrowing.html#control-flow-analysis">Control Flow Analysis</a> provided by&nbsp;TS.</p><p></p><h2>Preface</h2><p>So... a <em>switch</em> statement&#8230;</p><p>While <em>switch</em> statements don&#8217;t need much introduction and are pretty ordinary in themselves, the sections in this blog&nbsp;would:</p><ul><li><p>Introduce the code snippet (sample problem statement) we&#8217;ll be working&nbsp;with,</p></li><li><p>Shall discuss what are the limitations of <em>switch</em> statements when used in their naive&nbsp;form</p></li><li><p>And, then go on later to discuss a few enhancements (by harnessing native TypeScript features only!) that we can make to make our <em>switch</em> statements more Type-Safe and Exhaustive.</p></li></ul><blockquote><p><strong>Note:</strong> The aim of this post is not to suggest the resulting code as a &#8216;better&#8217; pattern for implementing calculator application or similar problems. It is merely intended for demonstrating the type safety and exhaustiveness that we can achieve while employing switch statements by harnessing only native (without usage of external libraries) features of TypeScript.</p></blockquote><p></p><h2>Problem Statement</h2><p>We&#8217;ll work with a simple calculator application/function. To begin with, lets assume our calculator does only two operations, viz. <em>Add</em> and <em>Multiply</em>. A simple code for the same would be as&nbsp;follows:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JAy2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9c3090-20a7-49ed-bc7d-c0d7f4a01bba_454x474.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JAy2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9c3090-20a7-49ed-bc7d-c0d7f4a01bba_454x474.png 424w, https://substackcdn.com/image/fetch/$s_!JAy2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9c3090-20a7-49ed-bc7d-c0d7f4a01bba_454x474.png 848w, https://substackcdn.com/image/fetch/$s_!JAy2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9c3090-20a7-49ed-bc7d-c0d7f4a01bba_454x474.png 1272w, https://substackcdn.com/image/fetch/$s_!JAy2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9c3090-20a7-49ed-bc7d-c0d7f4a01bba_454x474.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JAy2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9c3090-20a7-49ed-bc7d-c0d7f4a01bba_454x474.png" width="454" height="474" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4a9c3090-20a7-49ed-bc7d-c0d7f4a01bba_454x474.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:474,&quot;width&quot;:454,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!JAy2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9c3090-20a7-49ed-bc7d-c0d7f4a01bba_454x474.png 424w, https://substackcdn.com/image/fetch/$s_!JAy2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9c3090-20a7-49ed-bc7d-c0d7f4a01bba_454x474.png 848w, https://substackcdn.com/image/fetch/$s_!JAy2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9c3090-20a7-49ed-bc7d-c0d7f4a01bba_454x474.png 1272w, https://substackcdn.com/image/fetch/$s_!JAy2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a9c3090-20a7-49ed-bc7d-c0d7f4a01bba_454x474.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Straight forward, isn&#8217;t it. We&#8217;ve got two types of <em>Operations </em>(<em>Add</em> and <em>Multiply</em>) and then a simple function using <em>switch</em> statement to perform the appropriate operation.</p><p>Now, what happens if we remove either of the <em>case </em>statements, or we add a new <em>Operation</em> type, say <em>Subtract</em>? TS compiler won&#8217;t complain in either scenarios because we have a <em>default </em>case as a fallback. We agree returning a 0(zero) from default is a big NO. Not only 0 is a legitimate result from one of the operations, it doesn&#8217;t signify that the calculator was not able to perform an unknown operation. We can also return an <em>undefined</em> or a <em>null, </em>or throw<em> Error </em>maybe from our <em>default</em> case<em>. </em>But all of these approaches introduce an extra branch and a possiblity that the client code will have to check&nbsp;for.</p><p>We can always write unit tests to make sure either of the above doesn&#8217;t go unnoticed.</p><p><strong>But what if we can get the compiler to fail itself&nbsp;?!?!</strong></p><p></p><h2>The &#8216;<em>default</em>&#8217; case and &#8216;<em>never</em>&#8217;&nbsp;type</h2><p>Lets focus on <em>default</em> case. Let&#8217;s just log the <em>Operation </em>type<em> </em>that goes unmatched and is caught by the <em>default</em>&nbsp;case.</p><p>Notice that TypeScript infers <em>operation</em> inconsole.log statement as <em>never </em>type, as shown&nbsp;below.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UMz4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F454ebaac-c288-4697-9592-db8944eb2071_1020x720.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UMz4!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F454ebaac-c288-4697-9592-db8944eb2071_1020x720.gif 424w, https://substackcdn.com/image/fetch/$s_!UMz4!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F454ebaac-c288-4697-9592-db8944eb2071_1020x720.gif 848w, https://substackcdn.com/image/fetch/$s_!UMz4!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F454ebaac-c288-4697-9592-db8944eb2071_1020x720.gif 1272w, https://substackcdn.com/image/fetch/$s_!UMz4!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F454ebaac-c288-4697-9592-db8944eb2071_1020x720.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UMz4!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F454ebaac-c288-4697-9592-db8944eb2071_1020x720.gif" width="1020" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/454ebaac-c288-4697-9592-db8944eb2071_1020x720.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1020,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!UMz4!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F454ebaac-c288-4697-9592-db8944eb2071_1020x720.gif 424w, https://substackcdn.com/image/fetch/$s_!UMz4!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F454ebaac-c288-4697-9592-db8944eb2071_1020x720.gif 848w, https://substackcdn.com/image/fetch/$s_!UMz4!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F454ebaac-c288-4697-9592-db8944eb2071_1020x720.gif 1272w, https://substackcdn.com/image/fetch/$s_!UMz4!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F454ebaac-c288-4697-9592-db8944eb2071_1020x720.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is because of control flow analysis done by TS. Since the <em>operation </em>type can be one of &#8216;ADD&#8217; and &#8216;MULTIPLY&#8217;, there are naturally no more types left for it to assume in the <em>default</em> case, hence it assumes the <em>never</em>&nbsp;type.</p><p>Below are some excerpts from <a href="https://twitter.com/mariusschulz">Marius Schulz</a>&#8217;s blog on <a href="https://mariusschulz.com/blog/the-never-type-in-typescript">The never Type in TypeScript</a> (highly recommended), and TypeScript <a href="https://www.typescriptlang.org">docs</a> which are most relevant to us in enhancing our solution&nbsp;further.</p><blockquote><p>never is a subtype of and assignable to every&nbsp;type.</p></blockquote><blockquote><p>No type is a subtype of or assignable to <em>never</em> (except <em>never</em> itself). Additionally, it is a bottom-type.</p></blockquote><blockquote><p>In a function expression or arrow function with no return type annotation, if the function has no return statements, or only return statements with expressions of type never, and if the end point of the function is not reachable (as determined by control flow analysis), the inferred return type for the function is&nbsp;never.</p></blockquote><p>Deriving from the above, lets create a function which will signal whether or not our <em>switch </em>case matching is exhaustive.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TyOR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe1da588-d1fb-447e-9c7a-fee7f350b317_605x240.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TyOR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe1da588-d1fb-447e-9c7a-fee7f350b317_605x240.png 424w, https://substackcdn.com/image/fetch/$s_!TyOR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe1da588-d1fb-447e-9c7a-fee7f350b317_605x240.png 848w, https://substackcdn.com/image/fetch/$s_!TyOR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe1da588-d1fb-447e-9c7a-fee7f350b317_605x240.png 1272w, https://substackcdn.com/image/fetch/$s_!TyOR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe1da588-d1fb-447e-9c7a-fee7f350b317_605x240.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TyOR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe1da588-d1fb-447e-9c7a-fee7f350b317_605x240.png" width="605" height="240" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/be1da588-d1fb-447e-9c7a-fee7f350b317_605x240.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:240,&quot;width&quot;:605,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!TyOR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe1da588-d1fb-447e-9c7a-fee7f350b317_605x240.png 424w, https://substackcdn.com/image/fetch/$s_!TyOR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe1da588-d1fb-447e-9c7a-fee7f350b317_605x240.png 848w, https://substackcdn.com/image/fetch/$s_!TyOR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe1da588-d1fb-447e-9c7a-fee7f350b317_605x240.png 1272w, https://substackcdn.com/image/fetch/$s_!TyOR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe1da588-d1fb-447e-9c7a-fee7f350b317_605x240.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The function takes in a <em>never</em> type parameter and &#8220;<em>never&#8221;</em> returns. So in case we try to pass any other type as a parameter, TS compiler would be unhappy and fail. But since the return type is also <em>never, </em>it can be used in conjunction with any other return type within a function.</p><p></p><h2>Stitching it all&nbsp;together</h2><p>So lets replace the return 0 in our <em>default</em> case in our code with the exhaustiveMatchingGuard function we created in previous&nbsp;section.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Yx6a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b0a7c8b-eae8-42a2-9920-5bc144687baa_605x546.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Yx6a!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b0a7c8b-eae8-42a2-9920-5bc144687baa_605x546.png 424w, https://substackcdn.com/image/fetch/$s_!Yx6a!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b0a7c8b-eae8-42a2-9920-5bc144687baa_605x546.png 848w, https://substackcdn.com/image/fetch/$s_!Yx6a!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b0a7c8b-eae8-42a2-9920-5bc144687baa_605x546.png 1272w, https://substackcdn.com/image/fetch/$s_!Yx6a!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b0a7c8b-eae8-42a2-9920-5bc144687baa_605x546.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Yx6a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b0a7c8b-eae8-42a2-9920-5bc144687baa_605x546.png" width="605" height="546" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7b0a7c8b-eae8-42a2-9920-5bc144687baa_605x546.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:546,&quot;width&quot;:605,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Yx6a!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b0a7c8b-eae8-42a2-9920-5bc144687baa_605x546.png 424w, https://substackcdn.com/image/fetch/$s_!Yx6a!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b0a7c8b-eae8-42a2-9920-5bc144687baa_605x546.png 848w, https://substackcdn.com/image/fetch/$s_!Yx6a!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b0a7c8b-eae8-42a2-9920-5bc144687baa_605x546.png 1272w, https://substackcdn.com/image/fetch/$s_!Yx6a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b0a7c8b-eae8-42a2-9920-5bc144687baa_605x546.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Notice that TS compiler is happy with our code because (as elaborated in <strong>&#8220;The &#8216;default&#8217; case and &#8216;never&#8217; type&#8221;</strong> section) there is no other type left for <em>operation</em> to take&nbsp;on.</p><p>Let&#8217;s notice what happens if we add another type of <em>Operation:</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lbVh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604c1000-377a-4a35-b3a5-78e78bfbf789_1265x765.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lbVh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604c1000-377a-4a35-b3a5-78e78bfbf789_1265x765.gif 424w, https://substackcdn.com/image/fetch/$s_!lbVh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604c1000-377a-4a35-b3a5-78e78bfbf789_1265x765.gif 848w, https://substackcdn.com/image/fetch/$s_!lbVh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604c1000-377a-4a35-b3a5-78e78bfbf789_1265x765.gif 1272w, https://substackcdn.com/image/fetch/$s_!lbVh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604c1000-377a-4a35-b3a5-78e78bfbf789_1265x765.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lbVh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604c1000-377a-4a35-b3a5-78e78bfbf789_1265x765.gif" width="1265" height="765" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/604c1000-377a-4a35-b3a5-78e78bfbf789_1265x765.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:765,&quot;width&quot;:1265,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:836218,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lbVh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604c1000-377a-4a35-b3a5-78e78bfbf789_1265x765.gif 424w, https://substackcdn.com/image/fetch/$s_!lbVh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604c1000-377a-4a35-b3a5-78e78bfbf789_1265x765.gif 848w, https://substackcdn.com/image/fetch/$s_!lbVh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604c1000-377a-4a35-b3a5-78e78bfbf789_1265x765.gif 1272w, https://substackcdn.com/image/fetch/$s_!lbVh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F604c1000-377a-4a35-b3a5-78e78bfbf789_1265x765.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>and Voila!! the compiler is not happy that we have forgotten to match the <em>Subtract </em>case!! It tells us that argument of type string is not assignable to type never&nbsp;, as expected!</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FyIA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdda83d67-1103-4945-8988-fdbaf1140913_1024x205.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FyIA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdda83d67-1103-4945-8988-fdbaf1140913_1024x205.png 424w, https://substackcdn.com/image/fetch/$s_!FyIA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdda83d67-1103-4945-8988-fdbaf1140913_1024x205.png 848w, https://substackcdn.com/image/fetch/$s_!FyIA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdda83d67-1103-4945-8988-fdbaf1140913_1024x205.png 1272w, https://substackcdn.com/image/fetch/$s_!FyIA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdda83d67-1103-4945-8988-fdbaf1140913_1024x205.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FyIA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdda83d67-1103-4945-8988-fdbaf1140913_1024x205.png" width="1024" height="205" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dda83d67-1103-4945-8988-fdbaf1140913_1024x205.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:205,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!FyIA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdda83d67-1103-4945-8988-fdbaf1140913_1024x205.png 424w, https://substackcdn.com/image/fetch/$s_!FyIA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdda83d67-1103-4945-8988-fdbaf1140913_1024x205.png 848w, https://substackcdn.com/image/fetch/$s_!FyIA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdda83d67-1103-4945-8988-fdbaf1140913_1024x205.png 1272w, https://substackcdn.com/image/fetch/$s_!FyIA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdda83d67-1103-4945-8988-fdbaf1140913_1024x205.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>And hints us that operation: &#8216;SUBTRACT&#8217; is the culprit. Once we implement it, we&#8217;re back to our happy&nbsp;state!</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!65zE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee95b0f7-871d-4362-bb95-fc095e54072c_1285x777.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!65zE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee95b0f7-871d-4362-bb95-fc095e54072c_1285x777.gif 424w, https://substackcdn.com/image/fetch/$s_!65zE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee95b0f7-871d-4362-bb95-fc095e54072c_1285x777.gif 848w, https://substackcdn.com/image/fetch/$s_!65zE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee95b0f7-871d-4362-bb95-fc095e54072c_1285x777.gif 1272w, https://substackcdn.com/image/fetch/$s_!65zE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee95b0f7-871d-4362-bb95-fc095e54072c_1285x777.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!65zE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee95b0f7-871d-4362-bb95-fc095e54072c_1285x777.gif" width="1285" height="777" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ee95b0f7-871d-4362-bb95-fc095e54072c_1285x777.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:777,&quot;width&quot;:1285,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1111897,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!65zE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee95b0f7-871d-4362-bb95-fc095e54072c_1285x777.gif 424w, https://substackcdn.com/image/fetch/$s_!65zE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee95b0f7-871d-4362-bb95-fc095e54072c_1285x777.gif 848w, https://substackcdn.com/image/fetch/$s_!65zE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee95b0f7-871d-4362-bb95-fc095e54072c_1285x777.gif 1272w, https://substackcdn.com/image/fetch/$s_!65zE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee95b0f7-871d-4362-bb95-fc095e54072c_1285x777.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h2></h2><div><hr></div><h2>Closing thoughts</h2><p>One of the places that this kind of exhaustive matching comes very useful is while using redux and deriving next state based on different action types in reducers.</p><p>I hope this article gives some inspiration and inclination towards functional and type system side of TypeScript. I&#8217;m listing below some additional resources that you might find useful for futher explorations:</p><ul><li><p><a href="https://www.typescriptlang.org/docs/handbook/type-inference.html">Type Inference</a> in TypeScript</p></li><li><p><a href="https://www.typescriptlang.org/docs/handbook/2/narrowing.html#control-flow-analysis">Control Flow Analysis</a> in TypeScript</p></li><li><p><a href="https://twitter.com/mariusschulz">Marius Schulz</a>&#8217;s blog on <a href="https://mariusschulz.com/blog/the-never-type-in-typescript">The never Type in TypeScript</a></p></li><li><p><a href="https://github.com/gvergnaud/ts-pattern">ts-pattern</a> library</p></li></ul><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/p/type-safe-and-exhaustive-switch-statements-aka-pattern-matching-in-typescript-e3febd433a7a?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thank you for reading. Do tell your friends about it. &#128406;</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.riverandsoftware.com/p/type-safe-and-exhaustive-switch-statements-aka-pattern-matching-in-typescript-e3febd433a7a?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.riverandsoftware.com/p/type-safe-and-exhaustive-switch-statements-aka-pattern-matching-in-typescript-e3febd433a7a?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p><div><hr></div><p><a href="https://medium.com/technogise/type-safe-and-exhaustive-switch-statements-aka-pattern-matching-in-typescript-e3febd433a7a">Type Safe and Exhaustive &#8216;switch&#8217; statements, aka Pattern Matching in TypeScript</a> was originally published in <a href="https://medium.com/technogise">Technogise</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded></item><item><title><![CDATA[Why does a code review have to be blocking?]]></title><description><![CDATA[Although immensely popular in open source projects, does the blocking nature of code reviews via Pull Requests really help in the closed source projects?]]></description><link>https://www.riverandsoftware.com/p/why-does-a-code-review-have-to-be-blocking-47622a28f265</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/why-does-a-code-review-have-to-be-blocking-47622a28f265</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Sat, 06 Nov 2021 09:34:32 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/f1afca0f-55ed-4187-a006-4878a84d7ecd_2000x1333.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Although immensely popular in open source projects, does the blocking nature of code reviews via Pull Requests really help in the closed source projects? This article explores the downsides of a blocking code review and reasons with its alternatives.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://images.unsplash.com/photo-1638961852421-ce8ab1c36a76?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwzMDAzMzh8MHwxfHNlYXJjaHw5fHxjbG9zZWQlMjBnYXRlfGVufDB8fHx8MTY3Njk2Njk5Nw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1638961852421-ce8ab1c36a76?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwzMDAzMzh8MHwxfHNlYXJjaHw5fHxjbG9zZWQlMjBnYXRlfGVufDB8fHx8MTY3Njk2Njk5Nw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1638961852421-ce8ab1c36a76?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwzMDAzMzh8MHwxfHNlYXJjaHw5fHxjbG9zZWQlMjBnYXRlfGVufDB8fHx8MTY3Njk2Njk5Nw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1638961852421-ce8ab1c36a76?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwzMDAzMzh8MHwxfHNlYXJjaHw5fHxjbG9zZWQlMjBnYXRlfGVufDB8fHx8MTY3Njk2Njk5Nw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1638961852421-ce8ab1c36a76?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwzMDAzMzh8MHwxfHNlYXJjaHw5fHxjbG9zZWQlMjBnYXRlfGVufDB8fHx8MTY3Njk2Njk5Nw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1638961852421-ce8ab1c36a76?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwzMDAzMzh8MHwxfHNlYXJjaHw5fHxjbG9zZWQlMjBnYXRlfGVufDB8fHx8MTY3Njk2Njk5Nw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" width="1080" height="720" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1638961852421-ce8ab1c36a76?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwzMDAzMzh8MHwxfHNlYXJjaHw5fHxjbG9zZWQlMjBnYXRlfGVufDB8fHx8MTY3Njk2Njk5Nw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1080,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://images.unsplash.com/photo-1638961852421-ce8ab1c36a76?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwzMDAzMzh8MHwxfHNlYXJjaHw5fHxjbG9zZWQlMjBnYXRlfGVufDB8fHx8MTY3Njk2Njk5Nw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1638961852421-ce8ab1c36a76?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwzMDAzMzh8MHwxfHNlYXJjaHw5fHxjbG9zZWQlMjBnYXRlfGVufDB8fHx8MTY3Njk2Njk5Nw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1638961852421-ce8ab1c36a76?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwzMDAzMzh8MHwxfHNlYXJjaHw5fHxjbG9zZWQlMjBnYXRlfGVufDB8fHx8MTY3Njk2Njk5Nw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1638961852421-ce8ab1c36a76?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwzMDAzMzh8MHwxfHNlYXJjaHw5fHxjbG9zZWQlMjBnYXRlfGVufDB8fHx8MTY3Njk2Njk5Nw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@anniespratt">Annie Spratt</a> on <a href="https://unsplash.com">Unsplash</a></figcaption></figure></div><p>Code Reviews have long been and will always be an integral part of the software development lifecycle. They, along with Pull Requests were further popularised through open source community, where contributor(s) would raise a pull request against a change-set they&#8217;re wanting to introduce and then the owner(s) of the repository would review and either accept, request changes or reject the PR. Naturally, the change-set is kept from getting merged till the entire process is completed, rendering it <strong>blocked </strong>from getting&nbsp;shipped.</p><p>The pull requests and code reviews have been aggressively adopted in &#8220;closed&#8221; source projects too. But does the <strong>blocking</strong> nature of code reviews via PRs really help in the closed source projects? I&#8217;ve long proposed PRs and code reviews in teams, more so in new(er) teams. As time progressed, and as I read more (and listened to more talks) and learned from others&#8217; experiences, I started realising the traditional code reviews have more demerits than merits. Let&#8217;s try to reason&nbsp;along.</p><p><strong>Note</strong>: <em>Unless explicitly stated, I&#8217;ll be referring to the blocking code reviews in context of code reviews done via a Pull Request (or PR as referenced in rest of the article), where the code awaits (hence blocked) for merging till a code review has been done to satisfaction.</em></p><div><hr></div><h2>What are the benefits of good code&nbsp;reviews?</h2><p>Before we jump into analysing the pitfalls with blocking style of code reviews, let&#8217;s agree upon why code reviews (whether blocking or not) are important in software engineering. Broadly speaking, benefits of a good code review are as&nbsp;follows:</p><ul><li><p>It ensures design and implementations are consistent across the&nbsp;project</p></li><li><p>Helps check for potential vulnerabilities in the code and logic&nbsp;errors.</p></li><li><p>Fosters knowledge sharing through discussions involved between contributors and reviewers.</p></li><li><p>Helps validate the developed feature against the intended scope and desired&nbsp;outcome.</p></li></ul><div><hr></div><h2>So, whats wrong with blocking code&nbsp;reviews?</h2><h3>1. Increases the Lead&nbsp;Time</h3><ul><li><p>Most of the assumed and agreed upon benefits of a code review come at the cost of blocking the code from getting to trunk(or master/main branch) and eventually blocking the developers from picking their next story. This blocking will increase the Lead Time and also make the feedback loop only&nbsp;bigger.</p></li><li><p>Not forgetting to mention the plethora of merge conflicts the review will continue to accumulate the longer it &#8220;sits in the review&nbsp;lane&#8221;.</p></li><li><p>The biggest impact on the lead time, although is the context switching and overhead of asynchronous communication. (for both the submitter and the reviewer alike). <a href="https://twitter.com/d_stepanovic">Dragan Stepanovi&#263;</a> explains it very beautifully in one of his&nbsp;slides:</p></li></ul><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://twitter.com/d_stepanovic/status/1379451260638785536?s=20&quot;,&quot;full_text&quot;:&quot;\&quot;We'll go faster if we don't pair/mob\&quot; &quot;,&quot;username&quot;:&quot;d_stepanovic&quot;,&quot;name&quot;:&quot;Dragan Stepanovi&#263;&quot;,&quot;profile_image_url&quot;:&quot;&quot;,&quot;date&quot;:&quot;Tue Apr 06 15:09:44 +0000 2021&quot;,&quot;photos&quot;:[{&quot;img_url&quot;:&quot;https://pbs.substack.com/media/EyTLgyUXEAEUf8O.jpg&quot;,&quot;link_url&quot;:&quot;https://t.co/olknHYBNW4&quot;,&quot;alt_text&quot;:null}],&quot;quoted_tweet&quot;:{},&quot;reply_count&quot;:0,&quot;retweet_count&quot;:380,&quot;like_count&quot;:1300,&quot;impression_count&quot;:0,&quot;expanded_url&quot;:{},&quot;video_url&quot;:null,&quot;belowTheFold&quot;:true}" data-component-name="Twitter2ToDOM"></div><p></p><h3>2. Blocking code reviews are not Continuously Integrated.</h3><ul><li><p>Just because you&#8217;re using a top notch &#8220;CI/CD&#8221; tool, doesn&#8217;t guarantee that your team has either of <a href="https://www.thoughtworks.com/continuous-integration">Continuous Integration</a> or <a href="https://continuousdelivery.com/">Continuous Delivery</a>.</p></li></ul><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://twitter.com/SteveSmith_Tech/status/1192526800125136902?s=20&quot;,&quot;full_text&quot;:&quot;No. A tool cannot \&quot;include built-in CI and CD\&quot;\n\n- <span class=\&quot;tweet-fake-link\&quot;>#ContinuousIntegration</span> is a practice\n- <span class=\&quot;tweet-fake-link\&quot;>#ContinuousDelivery</span> is a set of principles and practices\n\nA tool can do build and deployment actions well, but it can't do more than that. You'd hope the GitHub CEO would know better <span class=\&quot;tweet-fake-link\&quot;>#ohdear</span> &quot;,&quot;username&quot;:&quot;SteveSmith_Tech&quot;,&quot;name&quot;:&quot;Steve Smith&quot;,&quot;profile_image_url&quot;:&quot;&quot;,&quot;date&quot;:&quot;Thu Nov 07 19:38:39 +0000 2019&quot;,&quot;photos&quot;:[],&quot;quoted_tweet&quot;:{&quot;full_text&quot;:&quot;&#127775; So excited to announce that GitHub now includes built-in CI/CD! https://t.co/QgCJdhe6cQ&quot;,&quot;username&quot;:&quot;natfriedman&quot;,&quot;name&quot;:&quot;Nat Friedman&quot;},&quot;reply_count&quot;:0,&quot;retweet_count&quot;:65,&quot;like_count&quot;:127,&quot;impression_count&quot;:0,&quot;expanded_url&quot;:{},&quot;video_url&quot;:null,&quot;belowTheFold&quot;:true}" data-component-name="Twitter2ToDOM"></div><ul><li><p>Pull Requests used in conjunction with feature branching imply anything but continuous integration. Although few ardent advocates of TBD and CD argue that a code kept &#8220;long enough&#8221; on local master instead of pushing it to remote &#8220;frequently&#8221; (at least once a day) is still a local branch, I&#8217;m only referring to long lived branches and explicit feature branching here.</p></li></ul><blockquote><p>&#8220;Feature branches are by design intended to hide changes. Continuous Integration is designed to expose changes. The two are mutually exclusive.&#8221; <em><a href="https://twitter.com/davefarley77">@DaveFarley</a></em></p></blockquote><p></p><h3>3. Prone to &#8220;Pseudo Rubber Stamping&#8221;</h3><ul><li><p>No one wants to stand in the way of a unit of work and block it from happening. The more critical or bigger the change-set to be reviewed is, the more time it is going to take to review it. The more time it will take to review, the more it will block. We&#8217;re more eager, in such cases, to just rubber stamp the PR with a &#8220;LGTM&#8221; (looks good to me) and let it move&nbsp;on.</p><div class="pullquote"><p><em>It is not that larger PRs either have too much or too little discussion, but rather they have a larger variability in their amount of discussion than that seen in smaller&nbsp;PRs.</em></p></div></li><li><p>There is an interesting and detailed study done by <a href="https://jellyfish.co/">Jellyfish</a> which is available in their <a href="https://jellyfish.co/blog/do-larger-pull-requests-receive-more-comments/">blog</a>, which suggests that amount of discussions (review comments and replies) vary greatly as the size of the PR increases. The variability in the discussion suggests that not all the PRs are getting the due attention that they require. As a result, not all the PRs are getting reviewed as we would like in the first place. This just defeats the very purpose of a code review&nbsp;itself.</p></li><li><p>It&#8217;s also implausible to expect the individuals (and not the team as a whole) to understand all the aspects of the system themselves. Eventually expecting them to be able to do all critical code reviews with due diligence is a fallacy! This starts becoming more evident as both the code and team grow in&nbsp;size.</p></li></ul><div class="pullquote"><p><em><strong>Woods&#8217; Theorem: </strong>As the complexity of a system increases, the accuracy of any single agent&#8217;s own model of that system decreases rapidly.</em></p></div><p></p><h3>4. Dilutes responsibility and ownership</h3><ul><li><p>In teams where there is over reliance on few seniors (maybe a tech lead or an architect) to be able to do critical reviews, not only have bigger bottlenecks, but also keep these seniors busy enough to keep them from picking up other meaningful and important work themselves.</p></li><li><p>The moment a code is sent for review, the ownership of the code shifts from the original dev (who wrote the code) to the reviewer. This can be a challenge. It gives a false signal to the devs that their work is &#8220;done&#8221;. In reality, it&#8217;s not done till its shipped and monitored briefly for sanity after deployment. Any other &#8220;done&#8221; is really just a&nbsp;facade!</p></li></ul><p></p><h3>5. Impedes effective knowledge sharing amongst the&nbsp;team</h3><p>It has been long argued and advocated in the community that code reviews help share knowledge within the team. With code reviews, not only the team aligns itself with the consistency in coding and designs, but also discovers and shares new and better techniques to do things. Adding on, I would argue that blocking and async fashioned code reviews are in general antithetical to knowledge sharing.</p><ul><li><p>With async code reviews, mostly the devs partaking in the code review are aware of the conversations. It&#8217;s quite likely that other team members will repeat the same mistakes/pattern unless the entire team becomes aware of the knowledge.</p></li><li><p>Knowledge sharing at the time of async code reviews is already too late in most cases! It&#8217;s being reactive as opposed to proactive. If the knowledge was shared upfront (and with the entire team), the time spent in reviewing and verifying the consistencies and design could&#8217;ve been saved and put better use&nbsp;of.</p></li></ul><h3></h3><div><hr></div><h2>Can we do things differently?</h2><p>We all agree without a doubt that code reviews are important. We also reasoned certain pitfalls when it comes to do code reviews in a blocking and async fashion. Is that the end of road or can we do things differently to reduce the pitfalls, and still achieve the same benefits that we set out to achieve in the first&nbsp;place?</p><p></p><h3>1. Pair programming and continuous code&nbsp;review</h3><p>With pair/mob programming, you get a continuous and instant feedback on the code. The review is happening for every line of code that is being put, in real&nbsp;time.</p><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://twitter.com/d_stepanovic/status/1452334281628569612?s=20&quot;,&quot;full_text&quot;:&quot;A regular monthly reminder that the optimal size of Pull Request is one line of code that is reviewed immediately as it's being typed.\n\nAnd I don't know of any other way to achieve it than by Pair/Mob programming.&quot;,&quot;username&quot;:&quot;d_stepanovic&quot;,&quot;name&quot;:&quot;Dragan Stepanovi&#263;&quot;,&quot;profile_image_url&quot;:&quot;&quot;,&quot;date&quot;:&quot;Sun Oct 24 18:00:50 +0000 2021&quot;,&quot;photos&quot;:[],&quot;quoted_tweet&quot;:{},&quot;reply_count&quot;:0,&quot;retweet_count&quot;:19,&quot;like_count&quot;:72,&quot;impression_count&quot;:0,&quot;expanded_url&quot;:{},&quot;video_url&quot;:null,&quot;belowTheFold&quot;:true}" data-component-name="Twitter2ToDOM"></div><ul><li><p>Least context switching happens. The pair&#8217;s or mob&#8217;s single-most and only responsibility at the given time is the code they are working on. Doing synchronous review as they code and reason along is a huge&nbsp;bonus!</p></li><li><p>There is no waiting for reviews and then making changes and getting reviewed again. In most cases, the cycle is longer. With pairing or mobbing, every participant is present all the&nbsp;time.</p></li></ul><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://twitter.com/petikoch/status/1461598739311865858?s=20&quot;,&quot;full_text&quot;:&quot;One benefit of Mob (Ensemble) Programming may be: no blocked persons anymore\n\n\&quot;In practice it usually feels like a bulldozer \nrather than a racecar - unstoppable and thorough.\&quot;\n- by <span class=\&quot;tweet-fake-link\&quot;>@techgreatness</span> \n\nJust tried to visualize that &#9997;&#65039; &quot;,&quot;username&quot;:&quot;petikoch&quot;,&quot;name&quot;:&quot;Peter Koch &#127464;&#127469;&quot;,&quot;profile_image_url&quot;:&quot;&quot;,&quot;date&quot;:&quot;Fri Nov 19 07:34:29 +0000 2021&quot;,&quot;photos&quot;:[{&quot;img_url&quot;:&quot;https://pbs.substack.com/media/FEikG-oWUAULwva.jpg&quot;,&quot;link_url&quot;:&quot;https://t.co/j5Y32mGaAO&quot;,&quot;alt_text&quot;:null}],&quot;quoted_tweet&quot;:{},&quot;reply_count&quot;:0,&quot;retweet_count&quot;:39,&quot;like_count&quot;:100,&quot;impression_count&quot;:0,&quot;expanded_url&quot;:{},&quot;video_url&quot;:null,&quot;belowTheFold&quot;:true}" data-component-name="Twitter2ToDOM"></div><ul><li><p>The Lead Time is immensely reduced.</p></li></ul><p></p><h3>2. Rotate your&nbsp;pairs</h3><ul><li><p>Effective pair rotation helps in keeping the knowledge silos to a&nbsp;minimum.</p></li><li><p>Frequent change in the pair of eyes looking at the functionality in progress can bring in fresh perspective as well as uncover things which previously were&nbsp;hidden.</p></li><li><p>Makes software a shared and social responsibility.</p></li></ul><p></p><h3>3. Host &#8220;Show and&nbsp;Tell&#8221;</h3><p>Organise frequent &#8220;Show and Tell&#8221; in your&nbsp;team.</p><ul><li><p>Talk about the design vision more&nbsp;often.</p></li><li><p>Showcase the new techniques of implementation that you discovered.</p></li><li><p>Talk about the desired way of writing&nbsp;code.</p></li><li><p>Discuss the debts that your code has accrued over time and how can it be dealt&nbsp;with.</p></li><li><p>Equally important, showcase the learnings from code failures and&nbsp;bugs.</p></li></ul><h3></h3><div><hr></div><h2>So Pair Programming is the silver bullet, you&nbsp;say?</h2><p>Well, it&#8217;s kind of a rhetorical question to ask. If every team and every org could work through pairing and mobbing, we would see it more often than we do&nbsp;now.</p><p>There are several cases where Pair Programming or Mobbing might not be effective:</p><ul><li><p>Lack of proper infrastructure and&nbsp;tooling.</p></li><li><p>The teams are more leveraged than they should be. The ratio of experience levels and tenure in the team is a skewed&nbsp;one.</p></li><li><p>There are multiple (sometimes even two are more than sufficient) geologically separated teams. The teams are dependendent on each other and neither truly distributed nor autonomous<em>.</em></p></li><li><p>Low to no psychological safety. In a low psychologically safe environment, pairing can be a daunting task. It can come across as being &#8220;monitored&#8221; or being &#8220;watched&nbsp;upon&#8221;.</p></li><li><p>Teams who do not understand pragmatic pairing. And treat it like&nbsp;dogma!</p></li><li><p>Critical code reviews, like pertaining to governance and compliance (often related to security) and only few in the org/teams having the complete knowledge of&nbsp;it.</p></li><li><p>Introduces fatigue if not done with agreed upon pairing session timings and&nbsp;breaks.</p></li></ul><h3></h3><div><hr></div><h2>Closing Thoughts&#8230;</h2><p>The aim of this article is not to propose adopting an absolutist approach. I understand that &#8220;it depends&#8221;. I understand that one methodology might not be applicable to different engineering teams. I also understand that the same methodology might not be applicable to the same team, all the&nbsp;time.</p><p>This article is rather an attempt to highlight the trade-offs which a team inherits when it employs blocking code reviews. These trade-offs might not be justified for every type of code review. Maybe there are few which require more detailed attention than the most. My advise would be to choose carefully. Don&#8217;t make it a dogma! Use your judgement wisely!</p><div><hr></div><p><a href="https://medium.com/geekculture/why-does-a-code-review-have-to-be-blocking-47622a28f265">Why does a code review have to be blocking?</a> was originally published in <a href="https://medium.com/geekculture">Geek Culture</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded></item><item><title><![CDATA[Why You Should Stop Representing Age As a Number in Your Code]]></title><description><![CDATA[Does the famous saying &#8220;Age is just a number&#8221; hold true in the programming world too?]]></description><link>https://www.riverandsoftware.com/p/why-you-should-stop-representing-age-as-a-number-in-your-code-ea1026a86bc8</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/why-you-should-stop-representing-age-as-a-number-in-your-code-ea1026a86bc8</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Fri, 13 Aug 2021 07:25:56 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/078047ad-1157-4b40-8219-e283bf840a1c_1024x1536.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4>Does the famous saying &#8220;Age is just a number&#8221; hold true in the programming world too? Can age be simply an <em>integer</em> type? Or is it something more evolved than just a naive primitive type? Can age ever be negative? I bet the primitive integer value can. So what is a better representation of age in programming languages then?</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aU7p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb777b3d0-edfb-4c67-afe3-690647efd755_1024x1536.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aU7p!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb777b3d0-edfb-4c67-afe3-690647efd755_1024x1536.jpeg 424w, https://substackcdn.com/image/fetch/$s_!aU7p!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb777b3d0-edfb-4c67-afe3-690647efd755_1024x1536.jpeg 848w, https://substackcdn.com/image/fetch/$s_!aU7p!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb777b3d0-edfb-4c67-afe3-690647efd755_1024x1536.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!aU7p!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb777b3d0-edfb-4c67-afe3-690647efd755_1024x1536.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aU7p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb777b3d0-edfb-4c67-afe3-690647efd755_1024x1536.jpeg" width="1024" height="1536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b777b3d0-edfb-4c67-afe3-690647efd755_1024x1536.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1536,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!aU7p!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb777b3d0-edfb-4c67-afe3-690647efd755_1024x1536.jpeg 424w, https://substackcdn.com/image/fetch/$s_!aU7p!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb777b3d0-edfb-4c67-afe3-690647efd755_1024x1536.jpeg 848w, https://substackcdn.com/image/fetch/$s_!aU7p!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb777b3d0-edfb-4c67-afe3-690647efd755_1024x1536.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!aU7p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb777b3d0-edfb-4c67-afe3-690647efd755_1024x1536.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@nate_dumlao?utm_source=medium&amp;utm_medium=referral">Nathan Dumlao</a> on&nbsp;<a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure></div><p><em>Age</em> and <em>Integer</em> (as much as they look like they were made for each other) are quite different <em>types</em> and have different properties and behaviours. Let's try to think out loud. An <em>integer</em> can be added to or subtracted from another <em>integer</em>, would you need to do that with <em>age</em>? Maybe. An <em>integer</em> can be multiplied with or divided by another <em>integer</em>, would you need to do that with <em>age</em>? Probably Not. An <em>integer</em> can be negative, can <em>age</em> ever be negative? Definitely not.</p><p>Just with some initial arguments, we see that <em>Integer </em>has started to diverge from being a quintessential representation of <em>Age</em>. This misrepresentation of richer constructs in programming with primitive types is often referred to as a <em>Primitive Obsession</em></p><blockquote><p><strong>Primitive Obsession</strong></p><p>is using primitive data types to represent domain ideas. For example, we use a String to represent a message, an Integer to represent an amount of money, or a Struct/Dictionary/Hash to represent a specific object.<br>&#8202;&#8212;&#8202;<a href="https://wiki.c2.com/?PrimitiveObsession">https://wiki.c2.com/?PrimitiveObsession</a></p></blockquote><p>So if <em>Age</em> is not merely an integer representation, then what is it? Let&#8217;s explore the idea in more details building on the complexity of representing <em>Age</em> correctly&#8230;</p><p><em>NOTE: The code examples listed below use TypeScript. However, the concepts are basic enough to be incorporated in other languages too.</em></p><p></p><div><hr></div><h2>First Cut</h2><p>Age can be represented in days, months and years, or even a combination of some/all of&nbsp;these.</p><p>If we simply used age as an integer variable, how do we get the other devs to know whether the age is in years, months or days? The most naive way I&#8217;ve seen this being addressed is through variable naming conventions.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aagQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d1ebef2-c30e-4416-bc40-f92e2ac082f9_1024x361.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aagQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d1ebef2-c30e-4416-bc40-f92e2ac082f9_1024x361.png 424w, https://substackcdn.com/image/fetch/$s_!aagQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d1ebef2-c30e-4416-bc40-f92e2ac082f9_1024x361.png 848w, https://substackcdn.com/image/fetch/$s_!aagQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d1ebef2-c30e-4416-bc40-f92e2ac082f9_1024x361.png 1272w, https://substackcdn.com/image/fetch/$s_!aagQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d1ebef2-c30e-4416-bc40-f92e2ac082f9_1024x361.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aagQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d1ebef2-c30e-4416-bc40-f92e2ac082f9_1024x361.png" width="1024" height="361" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3d1ebef2-c30e-4416-bc40-f92e2ac082f9_1024x361.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:361,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!aagQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d1ebef2-c30e-4416-bc40-f92e2ac082f9_1024x361.png 424w, https://substackcdn.com/image/fetch/$s_!aagQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d1ebef2-c30e-4416-bc40-f92e2ac082f9_1024x361.png 848w, https://substackcdn.com/image/fetch/$s_!aagQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d1ebef2-c30e-4416-bc40-f92e2ac082f9_1024x361.png 1272w, https://substackcdn.com/image/fetch/$s_!aagQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d1ebef2-c30e-4416-bc40-f92e2ac082f9_1024x361.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Isn&#8217;t it too much work for a dev to keep calculating the values for different representations? Also, we&#8217;re way too optimistic that the meaning wouldn&#8217;t be lost in translation. Imagine if this <em>age </em>variable was to be passed as parameters to other functions.</p><p>The problem with this approach is that it&#8217;s too prone to human error and interpretation to be comfortable with. If you&#8217;re not already familiar with, read about failure of <a href="https://en.wikipedia.org/wiki/Mars_Climate_Orbiter#Cause_of_failure">Mars Climate&nbsp;Orbiter</a>.</p><p>So how do we improve further? By building a basic abstraction&#8202;&#8212;&#8202;a&nbsp;class.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!t8eS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e88bcd-d61e-463d-a21b-96c92986ca18_1024x1039.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!t8eS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e88bcd-d61e-463d-a21b-96c92986ca18_1024x1039.png 424w, https://substackcdn.com/image/fetch/$s_!t8eS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e88bcd-d61e-463d-a21b-96c92986ca18_1024x1039.png 848w, https://substackcdn.com/image/fetch/$s_!t8eS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e88bcd-d61e-463d-a21b-96c92986ca18_1024x1039.png 1272w, https://substackcdn.com/image/fetch/$s_!t8eS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e88bcd-d61e-463d-a21b-96c92986ca18_1024x1039.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!t8eS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e88bcd-d61e-463d-a21b-96c92986ca18_1024x1039.png" width="1024" height="1039" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a7e88bcd-d61e-463d-a21b-96c92986ca18_1024x1039.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1039,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!t8eS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e88bcd-d61e-463d-a21b-96c92986ca18_1024x1039.png 424w, https://substackcdn.com/image/fetch/$s_!t8eS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e88bcd-d61e-463d-a21b-96c92986ca18_1024x1039.png 848w, https://substackcdn.com/image/fetch/$s_!t8eS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e88bcd-d61e-463d-a21b-96c92986ca18_1024x1039.png 1272w, https://substackcdn.com/image/fetch/$s_!t8eS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e88bcd-d61e-463d-a21b-96c92986ca18_1024x1039.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Alright, so we&#8217;ve gotten to a good start. Converted a primitive type to a good abstraction with some behaviours/methods to get <em>age </em>in different representations of days, months and&nbsp;years.</p><p>We can further improve our code. Remember we talked about the fact that <em>age</em> cannot be negative. But our above code accepts just any <em>number </em>values for years, months and days. So let&#8217;s fix that quickly in our constructor:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Qpna!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a983057-1daa-4c14-b75b-59d30df8ed2f_1024x740.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Qpna!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a983057-1daa-4c14-b75b-59d30df8ed2f_1024x740.png 424w, https://substackcdn.com/image/fetch/$s_!Qpna!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a983057-1daa-4c14-b75b-59d30df8ed2f_1024x740.png 848w, https://substackcdn.com/image/fetch/$s_!Qpna!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a983057-1daa-4c14-b75b-59d30df8ed2f_1024x740.png 1272w, https://substackcdn.com/image/fetch/$s_!Qpna!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a983057-1daa-4c14-b75b-59d30df8ed2f_1024x740.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Qpna!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a983057-1daa-4c14-b75b-59d30df8ed2f_1024x740.png" width="1024" height="740" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3a983057-1daa-4c14-b75b-59d30df8ed2f_1024x740.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:740,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Qpna!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a983057-1daa-4c14-b75b-59d30df8ed2f_1024x740.png 424w, https://substackcdn.com/image/fetch/$s_!Qpna!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a983057-1daa-4c14-b75b-59d30df8ed2f_1024x740.png 848w, https://substackcdn.com/image/fetch/$s_!Qpna!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a983057-1daa-4c14-b75b-59d30df8ed2f_1024x740.png 1272w, https://substackcdn.com/image/fetch/$s_!Qpna!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a983057-1daa-4c14-b75b-59d30df8ed2f_1024x740.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The above snippet makes sure that our <em>Age </em>object is constructed only with valid and allowed properties.</p><h3></h3><div><hr></div><h2>Final Cut</h2><p>So far we&#8217;ve built upon the basics of a much richer concept called <em><strong>Value&nbsp;Object.</strong></em></p><blockquote><p><strong>Value Object</strong>:<br>A value object is an object that contains attributes but has no conceptual identity. They should be treated as immutable.</p></blockquote><p>In simpler terms, taking age as an example, the age object doesn&#8217;t have any identity of its own. It's generally associated with another entity (an object which can be differentiated from other objects by a unique identification) like a person (every person will have a unique SSN number for&nbsp;e.g.).</p><p>The second concept about immutability is what makes value objects even more exciting. If the <em>age</em> changes, the existing object would spit out a new <em>age</em> object itself, leaving the original one untouched. For instance, when we add days/months/years to an <em>age</em> object, it would return a new object with the new attributes, as shown in the code&nbsp;below.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HCsX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F795cd4c8-ee97-4d0d-bfb0-70d1baa77032_1024x1201.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HCsX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F795cd4c8-ee97-4d0d-bfb0-70d1baa77032_1024x1201.png 424w, https://substackcdn.com/image/fetch/$s_!HCsX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F795cd4c8-ee97-4d0d-bfb0-70d1baa77032_1024x1201.png 848w, https://substackcdn.com/image/fetch/$s_!HCsX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F795cd4c8-ee97-4d0d-bfb0-70d1baa77032_1024x1201.png 1272w, https://substackcdn.com/image/fetch/$s_!HCsX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F795cd4c8-ee97-4d0d-bfb0-70d1baa77032_1024x1201.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HCsX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F795cd4c8-ee97-4d0d-bfb0-70d1baa77032_1024x1201.png" width="1024" height="1201" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/795cd4c8-ee97-4d0d-bfb0-70d1baa77032_1024x1201.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1201,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!HCsX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F795cd4c8-ee97-4d0d-bfb0-70d1baa77032_1024x1201.png 424w, https://substackcdn.com/image/fetch/$s_!HCsX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F795cd4c8-ee97-4d0d-bfb0-70d1baa77032_1024x1201.png 848w, https://substackcdn.com/image/fetch/$s_!HCsX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F795cd4c8-ee97-4d0d-bfb0-70d1baa77032_1024x1201.png 1272w, https://substackcdn.com/image/fetch/$s_!HCsX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F795cd4c8-ee97-4d0d-bfb0-70d1baa77032_1024x1201.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>With immutability, your code is more robust against multi-threaded programming because the referential integrity is intact for every object. It might add overhead in certain languages which were not designed keeping immutability as primary constructs, however, the tradeoff at this level is pretty minimal and you&#8217;ll almost always benefit in the multi-threaded world.</p><p>You may further enrich this model by including the comparison behaviour as well to help compare the two <em>age </em>objects with each other. Combining all the changes that we have made so far, our final Age representation would look like&nbsp;below:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!D8Fa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a981786-f238-444b-a7b5-f9cfc7006f71_1024x1662.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!D8Fa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a981786-f238-444b-a7b5-f9cfc7006f71_1024x1662.png 424w, https://substackcdn.com/image/fetch/$s_!D8Fa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a981786-f238-444b-a7b5-f9cfc7006f71_1024x1662.png 848w, https://substackcdn.com/image/fetch/$s_!D8Fa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a981786-f238-444b-a7b5-f9cfc7006f71_1024x1662.png 1272w, https://substackcdn.com/image/fetch/$s_!D8Fa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a981786-f238-444b-a7b5-f9cfc7006f71_1024x1662.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!D8Fa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a981786-f238-444b-a7b5-f9cfc7006f71_1024x1662.png" width="1024" height="1662" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5a981786-f238-444b-a7b5-f9cfc7006f71_1024x1662.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1662,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!D8Fa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a981786-f238-444b-a7b5-f9cfc7006f71_1024x1662.png 424w, https://substackcdn.com/image/fetch/$s_!D8Fa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a981786-f238-444b-a7b5-f9cfc7006f71_1024x1662.png 848w, https://substackcdn.com/image/fetch/$s_!D8Fa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a981786-f238-444b-a7b5-f9cfc7006f71_1024x1662.png 1272w, https://substackcdn.com/image/fetch/$s_!D8Fa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a981786-f238-444b-a7b5-f9cfc7006f71_1024x1662.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3></h3><div><hr></div><h2>Bonus (update)</h2><p>Even though I&#8217;ve used numbers (years, months and days) to construct the <em>age </em>object (to keep the blog simpler and shorter), effectively age is a difference between two points in time. So it might make more sense to accept a <em>Date/Time</em> object parameter in the constructor to denote the birth date &amp; time(if being used for a person, for e.g.).<br>Then, the other calculations like <em>getAgeInMonths</em>, <em>getAgeInYears</em> and <em>comparision</em> of ages etc could just be derived from the initial date/time itself.</p><p><strong>Thing to watch out for</strong>: Remember to take Timezone into consideration along with the date-time object.</p><h3></h3><div><hr></div><h2>Summary</h2><p>Always explore the richer abstractions aka Value Objects that you can build instead of prematurely obsessing over primitive types. Just like <em>Age, </em>there are several other constructs which are often misrepresented by just using the primitive types. <em>Money </em>is yet another example. Most of the codebases would portray <em>Money </em>as a float or a BigDecimal, completely missing the currency aspect of&nbsp;money.</p><p>So next time when you think about a type, conceptualise it using real-world scenarios and following their behaviour in real-world when put to different use&nbsp;cases.</p><p><em>More content at <a href="http://plainenglish.io/">plainenglish.io</a></em></p><div><hr></div><p><a href="https://javascript.plainenglish.io/why-you-should-stop-representing-age-as-a-number-in-your-code-ea1026a86bc8">Why You Should Stop Representing Age As a Number in Your Code</a> was originally published in <a href="https://javascript.plainenglish.io">JavaScript in Plain English</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded></item><item><title><![CDATA[Monolith vs Microservices : From the team’s perspective]]></title><description><![CDATA[Monolith vs Microservices : From the team&#8217;s perspective]]></description><link>https://www.riverandsoftware.com/p/monolith-vs-microservices-from-the-teams-perspective-cfed51231f05</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/monolith-vs-microservices-from-the-teams-perspective-cfed51231f05</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Mon, 05 Jul 2021 10:16:24 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/a27099d6-1ce7-43a4-89c6-a29066656f68_1024x570.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>Monolith vs Microservices&nbsp;: From the team&#8217;s perspective</h3><h4>Some top considerations while contemplating over Monolith vs Microservices are scalability, independent deployability, increased releasability &amp; maintainability. However, thinking only about application without considering how the choice would affect the team, is like looking at only one side of the&nbsp;coin.</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sqGU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e3bdc37-4d48-43c1-83e6-127f0eef6d47_1024x570.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sqGU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e3bdc37-4d48-43c1-83e6-127f0eef6d47_1024x570.jpeg 424w, https://substackcdn.com/image/fetch/$s_!sqGU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e3bdc37-4d48-43c1-83e6-127f0eef6d47_1024x570.jpeg 848w, https://substackcdn.com/image/fetch/$s_!sqGU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e3bdc37-4d48-43c1-83e6-127f0eef6d47_1024x570.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!sqGU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e3bdc37-4d48-43c1-83e6-127f0eef6d47_1024x570.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sqGU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e3bdc37-4d48-43c1-83e6-127f0eef6d47_1024x570.jpeg" width="1024" height="570" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1e3bdc37-4d48-43c1-83e6-127f0eef6d47_1024x570.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:570,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A never ending match&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A never ending match" title="A never ending match" srcset="https://substackcdn.com/image/fetch/$s_!sqGU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e3bdc37-4d48-43c1-83e6-127f0eef6d47_1024x570.jpeg 424w, https://substackcdn.com/image/fetch/$s_!sqGU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e3bdc37-4d48-43c1-83e6-127f0eef6d47_1024x570.jpeg 848w, https://substackcdn.com/image/fetch/$s_!sqGU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e3bdc37-4d48-43c1-83e6-127f0eef6d47_1024x570.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!sqGU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e3bdc37-4d48-43c1-83e6-127f0eef6d47_1024x570.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@hypefilms?utm_source=medium&amp;utm_medium=referral">David Guliciuc</a> on&nbsp;<a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure></div><p>Just as a &#8220;good&#8221; application which is easier to scale, maintain, release and test enables to serve more end-users (by handling more user requests), a &#8220;good&#8221; team helps is the force behind success of such applications. While a well structured ecosystem of applications/services is capable of shipping features faster and getting them out to users without having them to wait &#8220;too long&#8221;, in turn reducing <em>Time to Market,</em> the team is really the <strong>hero</strong> that makes it&nbsp;happen.</p><p></p><h2>Glossary</h2><p>Let&#8217;s begin by collectively visiting some of the terminologies used in this writeup. If you&#8217;re already familiar with them, jump straight to <em><strong>Considerations section.</strong></em></p><p></p><h3><strong>Modular Monolith:</strong></h3><ul><li><p>While referring to a <em>monolith </em>in this article, I&#8217;ll be referring to a &#8220;single process deployment&#8221;, i.e.; a system in which the code is deployed as a single process. There might be multiple instances of this process for scale, resilience etc. But conceptually the entire code is packed and deployed as a single process at a&nbsp;time.</p></li><li><p>Generally, we think of modularity only from code perspective. However, having modular code is just half the job done. The underlying persistence must also be made modular. So, when you structure your monolith into modules, also have a decomposed DB. Try hard not to have that foreign key reference to another module&#8217;s table even if it seems the most sane thing to&nbsp;do.</p></li><li><p>It might seem an overkill in the beginning to have so many DBs, and it makes sense to have this apprehension. But you can even harness the power of <em>schemas </em>that mostly all the DBs now provide and have separate schemas for different modules.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Pram!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16daa7a-7901-4cd9-b786-357fb2f7b5f8_1024x707.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Pram!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16daa7a-7901-4cd9-b786-357fb2f7b5f8_1024x707.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Pram!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16daa7a-7901-4cd9-b786-357fb2f7b5f8_1024x707.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Pram!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16daa7a-7901-4cd9-b786-357fb2f7b5f8_1024x707.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Pram!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16daa7a-7901-4cd9-b786-357fb2f7b5f8_1024x707.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Pram!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16daa7a-7901-4cd9-b786-357fb2f7b5f8_1024x707.jpeg" width="1024" height="707" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a16daa7a-7901-4cd9-b786-357fb2f7b5f8_1024x707.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:707,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Pram!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16daa7a-7901-4cd9-b786-357fb2f7b5f8_1024x707.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Pram!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16daa7a-7901-4cd9-b786-357fb2f7b5f8_1024x707.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Pram!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16daa7a-7901-4cd9-b786-357fb2f7b5f8_1024x707.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Pram!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16daa7a-7901-4cd9-b786-357fb2f7b5f8_1024x707.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Modular Monolith with decomposed modular Databases</figcaption></figure></div><blockquote><p><em>Segregating the code into microservices, still, is relatively easier as compared to separating the data into individual databases (owned by respective microservices) later and dealing with tedious migrations. DB migration is a </em>&#8220;hard problem&#8221;<em>.</em></p></blockquote><p></p><h3><strong>Feature based packaging:</strong></h3><p>Firstly, if you&#8217;re not familiar with <a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod">software packaging principles</a>, it&#8217;s a good place to begin with and understand the underlying concepts behind them. They are as fundamental to writing and structuring code as are SOLID principles.</p><p>&#8220;Package by layer&#8221; is typically what we&#8217;re all aware of and most widely used in projects. If say, we&#8217;re working on an API service, we&#8217;ll try to segregate the packages by <em>layers.</em> So all the code related to <em>routes </em>will go to a <em>route </em>directory, all the code related to <em>services (or adapters)</em> would fall into the infamous <em>services </em>package and then the pattern continues with <em>entities </em>and<em> repositories </em>and so on so&nbsp;forth.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EWyk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e95af45-a922-4a58-9d02-0f3b2f291789_1000x1238.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EWyk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e95af45-a922-4a58-9d02-0f3b2f291789_1000x1238.jpeg 424w, https://substackcdn.com/image/fetch/$s_!EWyk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e95af45-a922-4a58-9d02-0f3b2f291789_1000x1238.jpeg 848w, https://substackcdn.com/image/fetch/$s_!EWyk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e95af45-a922-4a58-9d02-0f3b2f291789_1000x1238.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!EWyk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e95af45-a922-4a58-9d02-0f3b2f291789_1000x1238.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EWyk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e95af45-a922-4a58-9d02-0f3b2f291789_1000x1238.jpeg" width="1000" height="1238" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7e95af45-a922-4a58-9d02-0f3b2f291789_1000x1238.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1238,&quot;width&quot;:1000,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!EWyk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e95af45-a922-4a58-9d02-0f3b2f291789_1000x1238.jpeg 424w, https://substackcdn.com/image/fetch/$s_!EWyk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e95af45-a922-4a58-9d02-0f3b2f291789_1000x1238.jpeg 848w, https://substackcdn.com/image/fetch/$s_!EWyk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e95af45-a922-4a58-9d02-0f3b2f291789_1000x1238.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!EWyk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e95af45-a922-4a58-9d02-0f3b2f291789_1000x1238.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">An example of code structure using package-by-layer packaging style</figcaption></figure></div><p>While the most easy to get started with<em>, Package by layer</em> is a maintenance hell, especially as the project grows, more people start contributing and more and more features get developed. Imagine browsing through the entire <em>entities </em>package to find out just the relevant entities that actually require change. Now imagine doing that for all such <em>layers </em>and imagine all the developers and teams doing that, the pain it would cause. In short, <em>discoverability</em> of code is very&nbsp;low.</p><p><em>&#8220;Package by Feature&#8221;, </em>on the other hand, uses packages to reflect the feature set. It&#8217;s an attempt to place all items related to a single feature (and <em><strong>only</strong></em> that feature) into a simple directory/package. This leads to packages with high cohesion and modularity, with minimal to no coupling between the packages. You may still have the layered architecture in the feature package to begin with, as shown below, but a good north star is to adopt a more Domain Driven Design based packaging structure. For, e.g. if &#8220;Food delivery App&#8221; had &#8220;Restaurant Search&#8221; &amp; &#8220;Delivery&#8221; as capabilities, each of them would end up as a feature package containing relevant layers/sub-packages within them as shown&nbsp;below:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ht9a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F848b8ced-385d-49a2-a2b6-718a51c1e685_1024x670.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ht9a!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F848b8ced-385d-49a2-a2b6-718a51c1e685_1024x670.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ht9a!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F848b8ced-385d-49a2-a2b6-718a51c1e685_1024x670.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ht9a!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F848b8ced-385d-49a2-a2b6-718a51c1e685_1024x670.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ht9a!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F848b8ced-385d-49a2-a2b6-718a51c1e685_1024x670.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ht9a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F848b8ced-385d-49a2-a2b6-718a51c1e685_1024x670.jpeg" width="1024" height="670" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/848b8ced-385d-49a2-a2b6-718a51c1e685_1024x670.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:670,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ht9a!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F848b8ced-385d-49a2-a2b6-718a51c1e685_1024x670.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ht9a!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F848b8ced-385d-49a2-a2b6-718a51c1e685_1024x670.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ht9a!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F848b8ced-385d-49a2-a2b6-718a51c1e685_1024x670.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ht9a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F848b8ced-385d-49a2-a2b6-718a51c1e685_1024x670.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Code structure using package-by-feature style of packaging</figcaption></figure></div><p>Each feature team can individually grow and maintain their feature packages with minimal conflict and bending their minds to search for the right code file to&nbsp;change.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0gSA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465fa65a-18e5-464c-bd46-1bfdcb0aa024_1024x516.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0gSA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465fa65a-18e5-464c-bd46-1bfdcb0aa024_1024x516.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0gSA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465fa65a-18e5-464c-bd46-1bfdcb0aa024_1024x516.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0gSA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465fa65a-18e5-464c-bd46-1bfdcb0aa024_1024x516.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0gSA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465fa65a-18e5-464c-bd46-1bfdcb0aa024_1024x516.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0gSA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465fa65a-18e5-464c-bd46-1bfdcb0aa024_1024x516.jpeg" width="1024" height="516" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/465fa65a-18e5-464c-bd46-1bfdcb0aa024_1024x516.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:516,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!0gSA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465fa65a-18e5-464c-bd46-1bfdcb0aa024_1024x516.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0gSA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465fa65a-18e5-464c-bd46-1bfdcb0aa024_1024x516.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0gSA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465fa65a-18e5-464c-bd46-1bfdcb0aa024_1024x516.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0gSA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465fa65a-18e5-464c-bd46-1bfdcb0aa024_1024x516.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">From package by layer towards package by feature code structure</figcaption></figure></div><p></p><h3><strong>Cross-Functional teams:</strong></h3><ul><li><p>Most conventional organisations have their teams set up in <em>functional</em> <em>silos</em>. A single Marketing team would be responsible for doing all the market evaluations and competitors study for various product lines/features. They&#8217;ll relay this to the Product team which is solely responsible to productise it into various features or suite of products. These feature epics would then be passed on Engineering team to execute, through a grandiose planning session. This relaying of <em>information-models</em> from one function to another is so fascinating that I began calling them as <em><strong>Relay-Functional teams</strong>, </em>analogous to a relay race, where one runner after finishing his leg, passes the baton to the next one to do his part. In large organisations, the individual functions might comprise of multiple teams within, however, conceptually the information model would still flow from one function (as a whole) to the&nbsp;other.</p></li><li><p>The most common model that comes to our mind when we think of cross-functional teams is engineering teams. We think of devops. We think of having Devs, architects and QAs as part of the same team and follow the same methodologies and choreograph the various ceremonies together.</p></li><li><p>That's good. Additionally, we should also strive for getting representatives from other business functions (like Product, Marketing, Sales etc) in the team. Imagine if Marketing person knew exactly what was being worked upon and could do the market-fit analysis alongside. Imagine the Sales person giving feedback ahead of the time what will fly with the customers and what&nbsp;won&#8217;t.</p></li><li><p>It&#8217;s difficult to have such a team in the place from the beginning, but it&#8217;s completely plausible. Such teams take a bit of sweat, experience and feedback from users to get to the right composition. But the core idea is to keep this at the back of your team&#8217;s mind throughout the journey, and not to be &#8220;comfortable&#8221; with what you&nbsp;have.</p></li></ul><h3></h3><div><hr></div><h2>Considerations while deciding monolith vs microservices:</h2><p>Before we dive into the considerations themselves, it&#8217;s worth pausing for a moment and understanding what does efficacy of a team really implies. While the ostensible idea of adding more people to the existing teams might seem quite reasonable to help scale the overall efficiency, however there is pretty good evidence in the industry that adding more people doesn&#8217;t really mean that the projects are going to be delivered faster. (If you haven&#8217;t already, it&#8217;s worth reading <a href="https://www.goodreads.com/book/show/13629.The_Mythical_Man_Month">The Mythical Man-Month</a> which has quintessential essays on this&nbsp;topic.)</p><p>Hence, while thinking about scalability, also think about how can existing teams be scaled up with respect to their capabilities and contribution capacity, and not just&nbsp;size.</p><p>With the above premise, let&#8217;s explore how various considerations play their role in influencing the choice of monolith vs microservices. Moreover, let&#8217;s also explore some <em>middle grounds </em>simultaneously<em>.</em></p><ul><li><p>A team can be scaled effectively on a well structured and modular monolith in a mono-repo codebase too. You don&#8217;t explicitly need a multi-repo Microservices based setup to do that. Been there, done that! The key however, is &#8220;well structured modular monolith with feature packaging around key sub-domains / business functionalities&#8221; (I know, it&#8217;s quite a mouthful).</p></li><li><p>Don&#8217;t forget to think about the right team composition. It plays a more crucial role in the overall architecture and structuring of the project than you might have thought of, especially in the longer run. (Oversimplified <a href="https://en.wikipedia.org/wiki/Conway%27s_law">Conway&#8217;s&nbsp;Law</a>)</p></li><li><p>If essentially you have <em>Relay-Functional teams </em>working in silos, then you&#8217;re way better off having a modular monolith backed by a mono-repo. Different code repos maintained by the same team might not be an exciting overhead to have. Some organisations are able to champion this very well. But requires enough maturity in the team. However, the overhead can get overwhelming as the team size increases beyond a threshold (Not quoting a number due to lack of actual research on the threshold. Sometimes wisdom precedes science and statistics)</p></li><li><p>However, if there are cross-functional teams, i.e. teams composed of Product, Engineering, Marketing etc and each team looks after individual sub-domains or product (sub-products or features too, if I may), then a solution around Microservices, and code split around well identified code repos (e.g. one repo per Microservice is a popular choice) might work wonders for you. Yet again the maturity of the team&nbsp;matters.</p></li><li><p>When the product is in its nascent stages, the domain is just evolving and very often misinterpreted. Without clear bounded contexts, premature modelling into Microservices might do more harm than benefit. I&#8217;m sure you&#8217;ve heard of horror stories of teams having to merge services and rethink the boundaries. Not a happy place to be&nbsp;at.</p></li><li><p>If this is the first time the team is diving into the microservices pool, it&#8217;s better to begin with feature teams working on a modular mono-repo codebase. Later split into microservices as the need arises and as the team gains more confidence.</p></li><li><p>Feature teams give the utmost confidence to Engineering and other business functions alike. It is relatively more comprehensible to think which feature requires more attention than the other, in turn allowing you to focus on particular teams at a time. Also, the approach helps in devising bespoke solutions for respective teams.</p></li><li><p>You may also go via the library/packages route of taking the modules in the monolith out into separate code bases that yield respective packages. Thereafter, combining them together to deploy the monolith as a single process. The repo separation of packages (suggested segregation based around business capabilities or &#8220;bounded-contexts&#8221;) helps different teams worry only about code that matters to them. But remember to keep the &#8220;<em>packaging principles</em>&#8221; in mind else unnecessary dependencies might slow things down instead of&nbsp;helping.</p></li><li><p>The releasability impedance is also caused by incorrectly identified bounded contexts while using Microservices. These are often termed as <em>&#8220;Distributed Monoliths&#8221;</em>. It might be easier to recover from a poor structured monolith than poorly structured labyrinth of microservices.</p></li></ul><h3></h3><div><hr></div><h2>Summary</h2><p><em>&#8220;It Depends&#8221;</em>. Just like most things in software, context is the key. An approach might work beautifully for a team and might not for the&nbsp;other.</p><p>When in doubt, try to begin with a monolith. Especially in a startup or when trying to explore the feasibility of a new product. Also stick with monolith if you&#8217;re unclear on what problems will Microservice actually solve for you. Use feature based packaging, it will help the team maintain the codebase better as it grows. Put in usage metrics and monitoring. Observe. Usage of the app by the end users is the real truth. See if it makes sense to split features lead by individual cross functional teams yet. Wait for it before going Microservices. You may never require them as well.<br>If the need occurs, your feature based packaged mono repo can further be decomposed into Microservices much easily as compared to codebases that are structured in a typical 3 tier architectural pattern. Feature packaging helps your team think more about business capabilities (bounded contexts) which are the building blocks of Microservices anyways.</p><p><strong>Bonus</strong>: Get to know more about <a href="https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html">Clean Architecture</a>, <a href="https://netflixtechblog.com/ready-for-changes-with-hexagonal-architecture-b315ec967749">Hexagonal Architecture</a> and <a href="https://jeffreypalermo.com/2008/07/the-onion-architecture-part-1/">Onion Architecture</a> to take the feature based packaging to the next level by incorporating Domain Driven Design into&nbsp;it.</p><div><hr></div><p><a href="https://medium.com/geekculture/monolith-vs-microservices-from-the-teams-perspective-cfed51231f05">Monolith vs Microservices&nbsp;: From the team&#8217;s perspective</a> was originally published in <a href="https://medium.com/geekculture">Geek Culture</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded></item><item><title><![CDATA[Unfurling Asynchronous Microservices]]></title><description><![CDATA[The talk compares the synchronous vs asynchronous communication approaches in Microservices and Distributed Systems.]]></description><link>https://www.riverandsoftware.com/p/unfurling-asynchronous-microservices-260b8d71c5ef</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/unfurling-asynchronous-microservices-260b8d71c5ef</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Tue, 20 Apr 2021 14:01:24 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/95cdd1a4-2ccd-47ef-a125-b68b4671ed3b_1024x768.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The talk compares the synchronous vs asynchronous communication approaches in Microservices and Distributed Systems. It highlights common patterns like Distributed Transactions, Distributed Queries, Orchestration vs Choreography and discusses pros and cons of&nbsp;each.</p><p>Hosted by <a href="https://technogise.com/">Technogise</a> <br><strong>Speakers</strong>: <a href="https://www.linkedin.com/in/siddiquinayab/">Nayab Siddiqui</a> and <a href="https://www.linkedin.com/in/pasarkargaurav/">Gaurav&nbsp;Pasarkar</a></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vhlG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51fae280-a792-4eb6-846d-19cc6f71e2c4_1024x768.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vhlG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51fae280-a792-4eb6-846d-19cc6f71e2c4_1024x768.jpeg 424w, https://substackcdn.com/image/fetch/$s_!vhlG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51fae280-a792-4eb6-846d-19cc6f71e2c4_1024x768.jpeg 848w, https://substackcdn.com/image/fetch/$s_!vhlG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51fae280-a792-4eb6-846d-19cc6f71e2c4_1024x768.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!vhlG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51fae280-a792-4eb6-846d-19cc6f71e2c4_1024x768.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vhlG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51fae280-a792-4eb6-846d-19cc6f71e2c4_1024x768.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/51fae280-a792-4eb6-846d-19cc6f71e2c4_1024x768.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!vhlG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51fae280-a792-4eb6-846d-19cc6f71e2c4_1024x768.jpeg 424w, https://substackcdn.com/image/fetch/$s_!vhlG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51fae280-a792-4eb6-846d-19cc6f71e2c4_1024x768.jpeg 848w, https://substackcdn.com/image/fetch/$s_!vhlG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51fae280-a792-4eb6-846d-19cc6f71e2c4_1024x768.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!vhlG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51fae280-a792-4eb6-846d-19cc6f71e2c4_1024x768.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@fabioha?utm_source=medium&amp;utm_medium=referral">fabio</a> on&nbsp;<a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure></div><blockquote><p><em>We compare the sync vs async approach and discuss in detail &#8220;the Good&#8221; and &#8220;Not so Good&#8221; things around each pattern and approach. Starting with a brief recap of Monoliths and Microservices, we&#8217;ll dive deep into Orchestration vs Choreography styles of designing workflows. Also we&#8217;ll explore and discuss different ways of implementing &#8220;Distributed Transactions&#8221; (like 2 Phase Commit and Saga) along with Distributed Queries using different patterns like replication, CQRS and&nbsp;more.</em></p></blockquote><h3>Sections |&nbsp;Topics</h3><p>Link to the timeline of each section/topic is as&nbsp;follows:</p><ul><li><p><a href="http://https//www.youtube.com/watch?v=TsVPQCxIH18&amp;t=0s">Intro to Technogise &amp; TechnoWise</a></p></li><li><p><a href="https://www.youtube.com/watch?v=TsVPQCxIH18&amp;t=544s">Agenda</a></p></li><li><p><a href="https://www.youtube.com/watch?v=TsVPQCxIH18&amp;t=799">Recap of Monolith &amp; Microservices</a></p></li><li><p><a href="https://www.youtube.com/watch?v=TsVPQCxIH18&amp;t=1413s">Orchestration vs Choreography</a></p></li><li><p><a href="https://www.youtube.com/watch?v=TsVPQCxIH18&amp;t=4311s">Commands vs&nbsp;Events</a></p></li><li><p><a href="https://www.youtube.com/watch?v=TsVPQCxIH18&amp;t=5162s">Distributed Transactions (2PC |&nbsp;Saga)</a></p></li><li><p><a href="https://www.youtube.com/watch?v=TsVPQCxIH18&amp;t=7321s">Distributed Queries (Replication |&nbsp;CQRS)</a></p></li></ul><p>Also, you can watch the full presentation down&nbsp;below:</p><p>&lt;a href="https://medium.com/media/461fb791d2fc8b584523694864d56ade/href"&gt;https://medium.com/media/461fb791d2fc8b584523694864d56ade/href&lt;/a&gt;</p><div><hr></div><p><a href="https://medium.com/technogise/unfurling-asynchronous-microservices-260b8d71c5ef">Unfurling Asynchronous Microservices</a> was originally published in <a href="https://medium.com/technogise">Technogise</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded></item><item><title><![CDATA[Learn, and empower to Learn!]]></title><description><![CDATA[Learn, and Empower Others to Learn!]]></description><link>https://www.riverandsoftware.com/p/learn-and-empower-to-learn-d04ca54f1710</link><guid isPermaLink="false">https://www.riverandsoftware.com/p/learn-and-empower-to-learn-d04ca54f1710</guid><dc:creator><![CDATA[Nayab Siddiqui]]></dc:creator><pubDate>Mon, 21 Sep 2020 13:22:53 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/927b2998-390c-4e78-a83a-2597259fa892_1024x680.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>Learn, and Empower Others to&nbsp;Learn!</h3><p>It often seems best to look out for another job to learn more, or better yet to learn more to get that new job. Often, it seems best decision to always hire people to fill the tech void within the company, and seems a waste of efforts to let people learn those new skills. Well, let me show you some of the positives which you&#8217;ve been missing out on, so&nbsp;far.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vADJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa89f2756-c1db-4440-9b07-2091eb9453c6_1024x680.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vADJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa89f2756-c1db-4440-9b07-2091eb9453c6_1024x680.jpeg 424w, https://substackcdn.com/image/fetch/$s_!vADJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa89f2756-c1db-4440-9b07-2091eb9453c6_1024x680.jpeg 848w, https://substackcdn.com/image/fetch/$s_!vADJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa89f2756-c1db-4440-9b07-2091eb9453c6_1024x680.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!vADJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa89f2756-c1db-4440-9b07-2091eb9453c6_1024x680.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vADJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa89f2756-c1db-4440-9b07-2091eb9453c6_1024x680.jpeg" width="1024" height="680" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a89f2756-c1db-4440-9b07-2091eb9453c6_1024x680.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:680,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Stack of books.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Stack of books." title="Stack of books." srcset="https://substackcdn.com/image/fetch/$s_!vADJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa89f2756-c1db-4440-9b07-2091eb9453c6_1024x680.jpeg 424w, https://substackcdn.com/image/fetch/$s_!vADJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa89f2756-c1db-4440-9b07-2091eb9453c6_1024x680.jpeg 848w, https://substackcdn.com/image/fetch/$s_!vADJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa89f2756-c1db-4440-9b07-2091eb9453c6_1024x680.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!vADJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa89f2756-c1db-4440-9b07-2091eb9453c6_1024x680.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@kimberlyfarmer?utm_source=medium&amp;utm_medium=referral">Kimberly Farmer</a> on&nbsp;<a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure></div><p>Technology around us is changing day by day. What was the norm yesterday is &#8220;un-cool&#8221; and outdated today. Newer projects are being written as you read through this blog. Every new project is trying to use the next-gen tech stack (if not the very bleeding edge technologies) in order to keep up, or at least try to. Some of these projects are also inventing new tech as they go, thereby complimenting the tech ecosystem&nbsp;. This trend is an over simplification of the theory of <em><a href="https://en.wikipedia.org/wiki/Diffusion_of_innovations">Diffusion of Innovation</a>s</em>&#8202;&#8212;&#8202;by <em>Everett Rogers</em>, and <em><a href="https://www.gartner.com/en/research/methodologies/gartner-hype-cycle">Gartner&#8217;s Hype&nbsp;Cycle</a></em>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!159-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d027e90-957c-4979-8ca9-7292cecd96a7_660x495.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!159-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d027e90-957c-4979-8ca9-7292cecd96a7_660x495.png 424w, https://substackcdn.com/image/fetch/$s_!159-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d027e90-957c-4979-8ca9-7292cecd96a7_660x495.png 848w, https://substackcdn.com/image/fetch/$s_!159-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d027e90-957c-4979-8ca9-7292cecd96a7_660x495.png 1272w, https://substackcdn.com/image/fetch/$s_!159-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d027e90-957c-4979-8ca9-7292cecd96a7_660x495.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!159-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d027e90-957c-4979-8ca9-7292cecd96a7_660x495.png" width="660" height="495" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5d027e90-957c-4979-8ca9-7292cecd96a7_660x495.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:495,&quot;width&quot;:660,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!159-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d027e90-957c-4979-8ca9-7292cecd96a7_660x495.png 424w, https://substackcdn.com/image/fetch/$s_!159-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d027e90-957c-4979-8ca9-7292cecd96a7_660x495.png 848w, https://substackcdn.com/image/fetch/$s_!159-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d027e90-957c-4979-8ca9-7292cecd96a7_660x495.png 1272w, https://substackcdn.com/image/fetch/$s_!159-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d027e90-957c-4979-8ca9-7292cecd96a7_660x495.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>The diffusion of innovations</strong> according to Rogers. With successive groups of consumers adopting the new technology (shown in blue), its <a href="https://en.wikipedia.org/wiki/Market_share">market share</a> (yellow) will eventually reach the saturation level. The blue curve is broken into sections of adopters.</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Balb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83ec2a1c-49a1-4cd1-be2f-a74de8a58243_1024x681.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Balb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83ec2a1c-49a1-4cd1-be2f-a74de8a58243_1024x681.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Balb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83ec2a1c-49a1-4cd1-be2f-a74de8a58243_1024x681.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Balb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83ec2a1c-49a1-4cd1-be2f-a74de8a58243_1024x681.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Balb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83ec2a1c-49a1-4cd1-be2f-a74de8a58243_1024x681.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Balb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83ec2a1c-49a1-4cd1-be2f-a74de8a58243_1024x681.jpeg" width="1024" height="681" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/83ec2a1c-49a1-4cd1-be2f-a74de8a58243_1024x681.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:681,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Balb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83ec2a1c-49a1-4cd1-be2f-a74de8a58243_1024x681.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Balb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83ec2a1c-49a1-4cd1-be2f-a74de8a58243_1024x681.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Balb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83ec2a1c-49a1-4cd1-be2f-a74de8a58243_1024x681.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Balb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83ec2a1c-49a1-4cd1-be2f-a74de8a58243_1024x681.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><strong>Gartner&#8217;s Hype</strong> <strong>cycle</strong> is a branded graphical presentation developed and used by the American research, advisory and <a href="https://en.wikipedia.org/wiki/Information_technology">information technology</a> firm <a href="https://en.wikipedia.org/wiki/Gartner">Gartner</a> to represent the maturity, adoption, and social application of specific <a href="https://en.wikipedia.org/wiki/Technology">technologies</a>. The hype cycle claims to provide a graphical and conceptual presentation of the maturity of emerging technologies through five&nbsp;phases.</figcaption></figure></div><p>As a result, the demand for developers well versed with such &#8216;new(er)&#8217; technologies is increasing by the day (if not by the hour in certain cases). The companies are expecting devs to know more (than ever) and the job descriptions are getting heftier in their expectations. In turn, this is creating a serious deficit of talent in the pool, which in turn impedes the recruitment for a company and even worse, makes the projects compromise on the right tech stack that they could/should have&nbsp;used.</p><p>So what do we do about this&nbsp;? Well, encourage learning on the job more than&nbsp;ever!</p><p></p><h2>What&#8217;s in it for the companies&nbsp;?</h2><blockquote><p>Investing in people often results in the best returns for both the company and its employees.</p></blockquote><ul><li><p>Existing devs already have domain context. <em><a href="https://twitter.com/ericevans0">Eric Evans</a> </em>explains the benefits of thinking in terms of <em>bounded contexts</em> in a quintessential manner in his book <em><a href="https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215">Domain Driven Design</a>. </em>Adding new tech skills in the arsenal beside domain knowledge is a proven winner in solving real problems pertaining to the company/business.</p></li><li><p>Companies which empower learning on the job, are often the companies which attract and work with some of the best minds in the industry. People who are able to adopt and apply newer knowledge are often proven to be ahead of the evolution curve and generally layout the future path for others through their thought leadership. Conducive environments for these people is simply a &#8216;<em>straight flush&#8217; </em>and a win-win for both the devs and companies. Continuous improvement (<em><a href="https://en.wikipedia.org/wiki/Kaizen">kaizen</a>) </em>and meaningful innovation is the key to success and sustainability for every tech company (product and consulting alike). People who are curious to learn play the biggest hand in making this a&nbsp;reality.</p></li><li><p>It generates a path of learning and career growth within the company. It encourages people to challenge themselves in a healthy fashion and keeps them from falling in the &#8216;comfort zone&#8217; trap. There is nothing more harmful than a cohort of staff which continues to &#8216;not&#8217; reflect and think alternatives to what they&#8217;ve been used&nbsp;to.</p></li><li><p>With the new(er) stack, there are only so many devs experienced in it, and even lesser &#8216;available&#8217;. Everyone is already going after them. And why should these devs leave their current environment which helped them be who they are, in the first place. Imagine you empower devs in your org to achieve that. Not only you don&#8217;t have to keep scratching your head figuring out how to &#8216;lure&#8217; them in, but you&#8217;ve also managed to create a sustainable phenomena on your own. Imagine not having to stall projects because of unavailability of devs. Imagine not having to go empty handed in the meetings with your VPs/CXOs and disappoint them by telling them that their brilliant idea won&#8217;t see the light because you don&#8217;t have people to execute it. Imagine not being afraid in choosing the best stack suited to solve your problem. Imagine NOT BEING CONFINED!</p></li></ul><p></p><h2>What&#8217;s in it for the developers (YOU)&nbsp;?</h2><ul><li><p>Software engineering is akin to craftsmanship. Like almost all the other arts, its also majorly self-taught. Its imperative that you focus and keep investing in yourself. The day you choose not to learn anymore, is sadly going to be also the day you&#8217;ll stop being of much value. <em>Don&#8217;t!!</em> Grab a new book, follow a new blog, listen to an exciting keynote, write a &#8216;Hello World&#8217; in new&#8230; <em>BE INSPIRED</em>!</p></li><li><p>Stand out from the crowd. Become a thought leader. How frequently do you Google (yes, I&#8217;m aware of duckduckgo. And no!! I&#8217;m never using bing in a sentence) your answers vs answering others&#8217; queries on the net/in your company? Get ahead!! Experiment, build hobby projects, share your wisdom, write a micro blog, tweet something interesting. The community needs more forerunners like&nbsp;you.</p></li><li><p>There are high chances that you&#8217;re already surrounded by seasoned devs in your org. Having them play mentors for your learnings is a phenomenal idea. They might not be experienced with the stack that you&#8217;re chasing after, but they must have done this for themselves when they were in your shoes (or they&#8217;re still doing it). Having such mentors can make a world of difference to how you approach learning a new stack. They can pitch in the pragmatic ways and often warn you of the unknowns that you might not be looking out&nbsp;for.</p></li><li><p>You need &#8216;more&#8217; to get to the next level. You&#8217;ll need to own more responsibilities than you do now. You&#8217;ll have to guide and mentor people. You&#8217;ll have to &#8216;serve&#8217; more than you do currently. Are you planning on doing all of that without being better than you already are right now&nbsp;?</p></li></ul><p>&#8216;Learning new&#8217; is not just about learning that new shiny language, or knowing about that new reactive framework in town, or going DevOps crazy (maybe DevSecOps is the new big thing eh! Oh wait, it is!). Nope! it&#8217;s <em>NOT</em> <em>JUST</em> that! It can be even finding alternate ways of writing the same piece of code, learning better ways of refactoring without halting your stories further, finding alternate ways of structuring your tests (Does it surprise you if I tell you can write BDD tests without using a BDD framework&nbsp;;) ), or even just brainstorming with your fellow geeks on what&#8217;s not so right in the architecture right now and what can be done in the least disruptive and continuous way.</p><p>Don&#8217;t be fooled by thinking that the next job is going to be better. Don&#8217;t be naive in thinking it&#8217;s just this project manager who is always strong arming you into doing more than you signed up for. Don&#8217;t be fooled by thinking that getting an expert on that stack is going to solve your existing&nbsp;problem.</p><p>Think about what&#8217;s the guarantee that the next job is not going to turn up the same? And if it does turn out similar, will you not be on the lookout again? Think about whether &#8216;that new geek&#8217; that you hired, is not going to be obsolete soon in your environment, because after all people are not learning in your environment.</p><p>I&#8217;m not suggesting you keep lingering on to your job no matter what. Even if its near impossible to find time to learn, because lets face it, they hired you to <em>DO </em>the job and <em>NOT</em> to &#8220;waste your productive time in learning and not being the code monkey to just write off those user stories&#8221;. Yup, such floors do exist, unfortunately! But what I am suggesting is to give it a fair chance. I know there are some &#8216;awesome&#8217; companies which have dedicated 1 day off, 80&#8211;20 rule (God knows when engineers will stop using this ratio!) and what not to let people explore and invest in themselves. And yours might be rather more humble. But its worth a try. Not all projects are the same, not all teams are same and not all times within the same project and team are same. Find the right opportunity and time and utilise it to the fullest. Better yet, use that time to fix things in your project or help them look at better solutions. Chances are you&#8217;re that catalyst which the company has been waiting upon to realise it needs to motivate people to learn more on that paid&nbsp;time.</p><p>On the other hand, there is nothing wrong with hiring people to fill in the deficits of knowledge pool. Its always good to bring in fresh perspective to already existing staff. However, whats wrong is to almost always prioritise this, over enabling people to learn new things. This phenomena is more prevalent in consulting companies which do project specific hiring to suit the dynamic clientele and projects. Please take note that people are going to stay even after the project is over (well, more often than you think&nbsp;:) ). Moroever, newer projects are going to come in as well, which may command a different tech set than the existing ones. If everytime we got out to hire a new batch, we might be jeopardising more than just the values and vision the company stands tall&nbsp;upon.</p><p>Don&#8217;t get me wrong here. I&#8217;m not concluding that a newer batch is not capable of doing so or they don&#8217;t come from a background where these values are already practiced and cherished. What I am trying to convey is that with the similar values and vision, every company has its signature way of materialising them in to tangible means, which creates its identity, and it takes time to get to know and adapt this mannerism.</p><p>If you have any <em>Pro Tips</em> on how to keep learning, or how to help people learn in your team/company, please do share/comment. If you have any other thoughts or there are things you disagreed within the blog, I&#8217;m more than happy to hear you out, discuss and debate&nbsp;:).</p><p>Nevertheless, let me leave you with the following thought:</p><blockquote><p>If you have always done it that way, it is probably wrong.<br>&#8202;&#8212;&#8202;Charles F. Kettering</p></blockquote>]]></content:encoded></item></channel></rss>