<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2026-05-15T09:02:25+00:00</updated><id>/feed.xml</id><title type="html">Sohaib Baig</title><subtitle></subtitle><entry><title type="html">Deterministic Infrastructure for AI-Assisted Coding</title><link href="/coding-practices/ai/2026/05/15/deterministic-infrastructure-for-ai-coding.html" rel="alternate" type="text/html" title="Deterministic Infrastructure for AI-Assisted Coding" /><published>2026-05-15T00:00:00+00:00</published><updated>2026-05-15T00:00:00+00:00</updated><id>/coding-practices/ai/2026/05/15/deterministic-infrastructure-for-ai-coding</id><content type="html" xml:base="/coding-practices/ai/2026/05/15/deterministic-infrastructure-for-ai-coding.html"><![CDATA[<p>Following is an excerpt from Martin Fowler’s recent <a href="https://martinfowler.com/fragments/2026-05-14.html">Fragments post</a> that references also remarks made by James Pritchard <a href="https://james-pritchard.com/blog/llms-are-functions">here</a>:</p>

<blockquote>
  <p>Most “agent” use cases are actually workflows, a known sequence of steps where one or two of those steps happen to involve an LLM. You don’t need autonomy for that. You need a function call.</p>
</blockquote>

<blockquote>
  <p>He points out that functions compose predictably, so if you know the workflow, then composing in a program text is better than agents figuring out how to coordinate themselves. It’s faster, and needs less tokens. It’s usually easier to deal with failures, since the scope of the interaction is smaller.</p>
</blockquote>

<hr />

<blockquote>
  <p>Pritchard also thinks that people use skills far more than they should. He thinks people accumulate folders of markdown skill files but LLMs use them inconsistently, often missing them when they’re needed, or bloating context when they are not. Many things that should go in skills should be other parts of a harness, preferably computational. Skills should only be used with deliberate, infrequent workflows.</p>
</blockquote>

<blockquote>
  <p>The skills obsession is a symptom of a deeper pattern: people reaching for configuration when they should be reaching for architecture.</p>
</blockquote>

<p>Consider that ArchUnit can let you build tests like the following:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@AnalyzeClasses</span><span class="o">(</span><span class="n">packages</span><span class="o">=</span><span class="s">"com.example"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SinglePublicMethodRuleTest</span> <span class="o">{</span>

    <span class="nd">@ArchTest</span>
    <span class="kd">static</span> <span class="kd">final</span> <span class="kt">var</span> <span class="n">usecases_should_have_only_one_public_method</span> <span class="o">=</span>
        <span class="n">classes</span><span class="o">()</span>
            <span class="o">.</span><span class="na">that</span><span class="o">()</span>
            <span class="o">.</span><span class="na">resideInAPackage</span><span class="o">(</span><span class="s">"..usecases.."</span><span class="o">)</span>
            <span class="o">.</span><span class="na">should</span><span class="o">(</span><span class="n">haveOnlyOnePublicMethod</span><span class="o">())</span>
<span class="o">}</span>
</code></pre></div></div>

<p>The actual rules should of course be specific to your project and modular to the modules within. This kind of stuff often gets leaked to skills files when it can be done perfectly well with deterministic tools.</p>

<p>Keeping code maintainable largely means keeping it comprehensible. Comprehensibility comes with architecture that enforces relationships across “entities” that are easier to reason about. When the entities are code, the architecture includes abstractions, adherence to using terminology from the domain of the system, and style heuristics.</p>

<p>Style heuristics include things like immutability, method lengths, line lengths against nesting, condition lengths before they’re refactored into explainer variables, all that makes cyclomatic complexity balloon up. With good style heuristics, you require less cognitive load to build abstractions, and you build better abstractions as a result. With poor style heuristics, your abstractions need to abstract such large surface areas that namespaces tend to collapse, and code reviews become a headache.</p>

<p>When I started agent-assisted coding, I struggled between setting the agent instructions, and wanting it to do things my way in a manner that “skills” was too unreliable for. Your “feedback loop” is not just the sum of tools you have fitted into your agentic workflow, you can also further categorize your prompts broadly into domain-feature/bug resolution/migration instructions (the meat of the chore), and refactoring instructions like how functionality is grouped, how you want variables to be named, etc.</p>

<p>When these style heuristics were violated during my earlier exploration with Claude Code, I thrashed with finding the balance between using the agent for feature work vs refactoring work. Refactoring work felt like it was bogging down the feedback loop, it was pedantic and it felt non-idiomatic.</p>

<p>It felt non-idiomatic because agents should essentially be seen as injections of non-determinism in our systems. Trying to reimagine those computing systems as inherently non-deterministic now because of AI and the need for reinvention is not just terribly misguided, but it also reflects the lack of an engineering intuition and bone in one’s perspective.</p>

<p>When we know agents are making our code quality worse, as engineers, our job is break problems down into smaller problems and solve them, not wish for Anthropic to fix it in the next Opus model.</p>

<p>Code style heuristics are like a developer’s handwriting, or an organization’s culture. They cannot be passed by a singular organization like Anthropic anyway. Abandoning them is not just not necessary, but these heuristics are in fact shortcuts that save extra work from being done. That “non-determinism” (AI generated code) does not need to be corrected in the form of a human feedback loop and those decisions can be automatically enforced by some tests and rules on code “styles” instead, instead of just the code’s behavior and execution path.</p>

<p>If these heuristics can be encoded as deterministic tests and rules using ArchUnit and SonarQube, it frees us up into breaking down “coding” itself as a problem and solve those individually with AI. I categorize code, or work that I do in writing features, as dealing with:</p>

<ul>
  <li><strong>Architecture</strong> (what goes where and how modularly)</li>
  <li><strong>Abstractions</strong></li>
  <li><strong>Naming</strong> (classes, variables, methods)</li>
  <li><strong>Performance and security</strong> considerations</li>
</ul>

<p>For architecture, one can study books, learn from good codebases, study different styles like functional programming, and gain practice and experience at their job for improvement. For better abstractions, one must understand the business domain better. For naming skills, it is simply your skills in the English language, and for performance and security, it is what we learn in academia with respect to algorithms and maths.</p>

<p>In agent assisted coding the same things map to the use of artifacts and tools. The interesting part is not skills, but how well you can inject the context and make use of deterministic tooling to restrain the agent from making mistakes. And it remains work that requires human interaction, comprehension and decision making, that LLMs fundamentally cannot do, and which is what keeps these tasks interesting and within the realm of “engineering”.</p>

<p>For architecture, explore ArchUnit. For the business domain, inter-departmental interaction requires human communication for identification and resolution of misunderstandings and scopes of work. The artifact is documentation. How is this going to be injected? Naming is done well enough automatically by the LLM if the architecture is good enough to keep namespaces well spaced. Maybe add some rules about explainer variables and condition complexity in conditional clauses using ArchUnit and SonarQube. For performance and security, again SonarQube can be used, but also other SaaS tools that are in use today by large organizations.</p>

<p>Again, that all these things are yet to become commonplace makes me still feel relevant as a software engineer.</p>]]></content><author><name></name></author><category term="coding-practices" /><category term="ai" /><summary type="html"><![CDATA[Following is an excerpt from Martin Fowler’s recent Fragments post that references also remarks made by James Pritchard here:]]></summary></entry><entry><title type="html">Shrinking the Search Space for Code Reviews</title><link href="/coding-practices/2026/04/28/tightening-feedback-loop-with-coding-styles.html" rel="alternate" type="text/html" title="Shrinking the Search Space for Code Reviews" /><published>2026-04-28T00:00:00+00:00</published><updated>2026-04-28T00:00:00+00:00</updated><id>/coding-practices/2026/04/28/tightening-feedback-loop-with-coding-styles</id><content type="html" xml:base="/coding-practices/2026/04/28/tightening-feedback-loop-with-coding-styles.html"><![CDATA[<p>Tightening the human feedback loop is prominent now as a bottleneck with agent assisted coding. Whilst coding “practices” like continuous deployment and TDD are already espoused by many, I wanted to mention “styles”, instead, of coding.</p>

<p>The core idea is learning to code in a style that makes the boundaries of change clear, such that when changes are made, typically by an AI agent, you can be confident that unexpected “side-effects” will not occur as a result. This entails using practices like guard clauses and immutability which come from functional programming.</p>

<p>Over time it will help evolve in you a sense of seeing code as states and outcomes, a level of abstraction higher than seeing code “imperatively”, i.e. in loops and conditions. Working at a higher abstraction level = more comprehension with less effort, which is something that also goes far with LLMs.</p>

<p>The benefit is twofold: not only do code reviews become faster, but the codebase is left in a more maintainable state. Changes become easier to reason about, reducing both the cognitive load on human reviewers and token use with AI agents.</p>

<p>These examples depict real world usecases of existing code + a delta of change representing challenges with maintainability of code. By the way, “memory” features like Claude.md make inculcating these patterns trivial, it is your human brain you must train to see the patterns in this style of coding.</p>

<h2 id="1-early-return-patternusing-guard-clauses">1. Early Return Pattern/Using Guard Clauses</h2>

<p>Consider the following example, which I have frequently seen in codebases, of nested statements.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">assemblyCheck</span><span class="o">()</span> <span class="o">{</span>
    <span class="kt">boolean</span> <span class="n">result</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(</span><span class="n">pants</span><span class="o">.</span><span class="na">arePressed</span><span class="o">())</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">belt</span><span class="o">.</span><span class="na">isBuckled</span><span class="o">())</span> <span class="o">{</span>
            <span class="k">if</span> <span class="o">(</span><span class="n">collar</span><span class="o">.</span><span class="na">isFixed</span><span class="o">())</span> <span class="o">{</span>
                <span class="k">if</span> <span class="o">(</span><span class="n">buttons</span><span class="o">.</span><span class="na">areFastened</span><span class="o">())</span> <span class="o">{</span>
                    <span class="k">if</span> <span class="o">(</span><span class="n">jacket</span><span class="o">.</span><span class="na">isBrushed</span><span class="o">())</span> <span class="o">{</span>
                        <span class="k">if</span> <span class="o">(</span><span class="n">cuffs</span><span class="o">.</span><span class="na">areAdjusted</span><span class="o">())</span> <span class="o">{</span>
                            <span class="k">if</span> <span class="o">(</span><span class="n">tie</span><span class="o">.</span><span class="na">isStraightened</span><span class="o">())</span> <span class="o">{</span>
                                <span class="n">result</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span>
                            <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
                                <span class="n">teacher</span><span class="o">.</span><span class="na">straighten</span><span class="o">(</span><span class="n">tie</span><span class="o">);</span>
                                <span class="n">result</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
                            <span class="o">}</span>
                        <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
                            <span class="n">result</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
                        <span class="o">}</span>
                    <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
                        <span class="n">student</span><span class="o">.</span><span class="na">remove</span><span class="o">(</span><span class="n">jacket</span><span class="o">);</span>
                        <span class="n">result</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
                    <span class="o">}</span>
                <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
                    <span class="n">result</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
                <span class="o">}</span>
            <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
                <span class="n">teacher</span><span class="o">.</span><span class="na">fix</span><span class="o">(</span><span class="n">collar</span><span class="o">);</span>
                <span class="n">result</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
            <span class="o">}</span>
        <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
            <span class="n">result</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
        <span class="o">}</span>
    <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
        <span class="n">result</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
    <span class="o">}</span>
    <span class="k">return</span> <span class="n">result</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Suppose an agent made a change as the BasketService is now meant to be used. Can you spot the error?</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">assemblyCheck</span><span class="o">()</span> <span class="o">{</span>
    <span class="kt">boolean</span> <span class="n">result</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(</span><span class="n">pants</span><span class="o">.</span><span class="na">arePressed</span><span class="o">())</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">belt</span><span class="o">.</span><span class="na">isBuckled</span><span class="o">())</span> <span class="o">{</span>
            <span class="k">if</span> <span class="o">(</span><span class="n">jacket</span><span class="o">.</span><span class="na">isBrushed</span><span class="o">())</span> <span class="o">{</span>
                <span class="k">if</span> <span class="o">(</span><span class="n">collar</span><span class="o">.</span><span class="na">isFixed</span><span class="o">())</span> <span class="o">{</span>
                    <span class="k">if</span> <span class="o">(</span><span class="n">buttons</span><span class="o">.</span><span class="na">areFastened</span><span class="o">())</span> <span class="o">{</span>
                        <span class="k">if</span> <span class="o">(</span><span class="n">cuffs</span><span class="o">.</span><span class="na">areAdjusted</span><span class="o">())</span> <span class="o">{</span>
                            <span class="k">if</span> <span class="o">(</span><span class="n">tie</span><span class="o">.</span><span class="na">isStraightened</span><span class="o">())</span> <span class="o">{</span>
                                <span class="n">result</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span>
                            <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
                                <span class="n">teacher</span><span class="o">.</span><span class="na">straighten</span><span class="o">(</span><span class="n">tie</span><span class="o">);</span>
                                <span class="n">result</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
                            <span class="o">}</span>
                        <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
                            <span class="n">result</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
                        <span class="o">}</span>
                    <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
                        <span class="n">result</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
                    <span class="o">}</span>
                <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
                    <span class="n">student</span><span class="o">.</span><span class="na">remove</span><span class="o">(</span><span class="n">jacket</span><span class="o">);</span>
                    <span class="nc">Jacket</span> <span class="n">substituteJacket</span> <span class="o">=</span> <span class="n">basketService</span><span class="o">.</span><span class="na">fetchSubstitute</span><span class="o">();</span>
                    <span class="n">student</span><span class="o">.</span><span class="na">wear</span><span class="o">(</span><span class="n">substituteJacket</span><span class="o">);</span>
                    <span class="n">result</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
                <span class="o">}</span>
            <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
                <span class="n">result</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
            <span class="o">}</span>
        <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
            <span class="n">result</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
        <span class="o">}</span>
    <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
        <span class="n">result</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
    <span class="o">}</span>
    <span class="k">return</span> <span class="n">result</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Consider below the functionally equivalent case with guard clauses.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">assemblyCheck</span><span class="o">()</span> <span class="o">{</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">shirt</span><span class="o">.</span><span class="na">isIroned</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">shoelaces</span><span class="o">.</span><span class="na">areTied</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">shoes</span><span class="o">.</span><span class="na">arePolished</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">pants</span><span class="o">.</span><span class="na">arePressed</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">belt</span><span class="o">.</span><span class="na">isBuckled</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">collar</span><span class="o">.</span><span class="na">isFixed</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">buttons</span><span class="o">.</span><span class="na">areFastened</span><span class="o">())</span> <span class="o">{</span>
        <span class="n">student</span><span class="o">.</span><span class="na">remove</span><span class="o">(</span><span class="n">jacket</span><span class="o">);</span>
        <span class="nc">Jacket</span> <span class="n">substituteJacket</span> <span class="o">=</span> <span class="n">basketService</span><span class="o">.</span><span class="na">fetchSubstitute</span><span class="o">();</span>
        <span class="n">student</span><span class="o">.</span><span class="na">wear</span><span class="o">(</span><span class="n">substituteJacket</span><span class="o">);</span>
        <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="o">}</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">jacket</span><span class="o">.</span><span class="na">isBrushed</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">cuffs</span><span class="o">.</span><span class="na">areAdjusted</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">tie</span><span class="o">.</span><span class="na">isStraightened</span><span class="o">())</span> <span class="o">{</span>
        <span class="n">teacher</span><span class="o">.</span><span class="na">straighten</span><span class="o">(</span><span class="n">tie</span><span class="o">);</span>
        <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="o">}</span>
    <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Can you spot the error now? (The nested and early return code snippets are functionally equivalent.)</p>

<p>As computer scientists, our ability to break problems into sub problems before solving them is core to a systems approach. Similarly, in inductive reasoning in maths, we identify and get rid of simpler cases first to make our lives easier.</p>

<p>The error is that the <code class="language-plaintext highlighter-rouge">basketService</code> code is tied to the <code class="language-plaintext highlighter-rouge">collar.isFixed()</code> condition instead of the <code class="language-plaintext highlighter-rouge">jacket.isBrushed()</code> condition where it should be. Nesting clauses fling “else” clauses far down the line, making it non trivial to decipher which code is logically coupled to which case.</p>

<p>Where would you add the new condition, <code class="language-plaintext highlighter-rouge">pants.areTheRightSize()</code>?</p>

<p>In nested code, introducing another level of nesting at the deepest level can feel intuitive, before any else statements require you to shuffle around brackets. Switching up the order of if-cases is jarring with moving braces and logic to be deciphered to ensure correctness is maintained.</p>

<p>With the early-return style, reordering conditions in most IDEs is a simple select then Alt+Up or Alt+Down, versus nested code where braces have to be carefully aligned.</p>

<p>Consider how much easier it is to add a new condition to the early-return style code. It is much easier to notice in this style also that there is already a condition coupled with pants in the method (<code class="language-plaintext highlighter-rouge">if(!pants.arePressed())</code>) in this style, and factor it out into a separate method.</p>

<p>For example, here’s the refactored version with pants checks extracted:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">assemblyCheck</span><span class="o">()</span> <span class="o">{</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">shirt</span><span class="o">.</span><span class="na">isIroned</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">shoelaces</span><span class="o">.</span><span class="na">areTied</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">shoes</span><span class="o">.</span><span class="na">arePolished</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">checkPants</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">belt</span><span class="o">.</span><span class="na">isBuckled</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">collar</span><span class="o">.</span><span class="na">isFixed</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">buttons</span><span class="o">.</span><span class="na">areFastened</span><span class="o">())</span> <span class="o">{</span>
        <span class="n">student</span><span class="o">.</span><span class="na">remove</span><span class="o">(</span><span class="n">jacket</span><span class="o">);</span>
        <span class="nc">Jacket</span> <span class="n">substituteJacket</span> <span class="o">=</span> <span class="n">basketService</span><span class="o">.</span><span class="na">fetchSubstitute</span><span class="o">();</span>
        <span class="n">student</span><span class="o">.</span><span class="na">wear</span><span class="o">(</span><span class="n">substituteJacket</span><span class="o">);</span>
        <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="o">}</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">jacket</span><span class="o">.</span><span class="na">isBrushed</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">cuffs</span><span class="o">.</span><span class="na">areAdjusted</span><span class="o">())</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">tie</span><span class="o">.</span><span class="na">isStraightened</span><span class="o">())</span> <span class="o">{</span>
        <span class="n">teacher</span><span class="o">.</span><span class="na">straighten</span><span class="o">(</span><span class="n">tie</span><span class="o">);</span>
        <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="o">}</span>
    <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>

<span class="kd">private</span> <span class="kt">boolean</span> <span class="nf">checkPants</span><span class="o">()</span> <span class="o">{</span>
    <span class="k">return</span> <span class="n">pants</span><span class="o">.</span><span class="na">arePressed</span><span class="o">()</span> <span class="o">&amp;&amp;</span> <span class="n">pants</span><span class="o">.</span><span class="na">areTheRightSize</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>

<p>It is no surprise that in codebases where nesting is preferred, scopes are not regularly extracted and methods tend to run very long.</p>

<p>This harms readability: In 1 huge method, the search space for changes is much larger, compared to the same method split into 5, where you might safely be able to ignore scopes that haven’t been touched by changes.</p>

<h2 id="2-smaller-methods-and-the-namespace-advantage">2. Smaller Methods and the Namespace Advantage</h2>

<p>Refactoring into smaller methods has an often overlooked benefit: better naming. In long methods with large scopes, the namespace shrinks, leading to variable names with 3-4 prefixes that ultimately don’t make immediate sense either. In smaller methods, you can use simpler names because the method name itself is part of your mental context window.</p>

<p>Consider this typical long method:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kt">void</span> <span class="nf">processUserOrder</span><span class="o">()</span> <span class="o">{</span>
    <span class="c1">// ... 50 lines of code ...</span>
    
    <span class="kt">boolean</span> <span class="n">userOrderPaymentVerified</span> <span class="o">=</span> <span class="n">paymentService</span><span class="o">.</span><span class="na">verify</span><span class="o">(</span><span class="n">order</span><span class="o">);</span>
    <span class="nc">String</span> <span class="n">userOrderPaymentTransactionId</span> <span class="o">=</span> <span class="n">payment</span><span class="o">.</span><span class="na">getTransactionId</span><span class="o">();</span>
    <span class="kt">boolean</span> <span class="n">userOrderInventoryAvailable</span> <span class="o">=</span> <span class="n">inventory</span><span class="o">.</span><span class="na">check</span><span class="o">(</span><span class="n">order</span><span class="o">.</span><span class="na">items</span><span class="o">);</span>
    <span class="nc">String</span> <span class="n">userOrderInventoryReservationId</span> <span class="o">=</span> <span class="n">inventory</span><span class="o">.</span><span class="na">reserve</span><span class="o">(</span><span class="n">order</span><span class="o">.</span><span class="na">items</span><span class="o">);</span>
    <span class="kt">boolean</span> <span class="n">userOrderShippingAddressValid</span> <span class="o">=</span> <span class="n">validateAddress</span><span class="o">(</span><span class="n">user</span><span class="o">.</span><span class="na">shippingAddress</span><span class="o">);</span>
    <span class="nc">String</span> <span class="n">userOrderShippingTrackingNumber</span> <span class="o">=</span> <span class="n">shipping</span><span class="o">.</span><span class="na">createLabel</span><span class="o">(</span><span class="n">order</span><span class="o">);</span>
    
    <span class="k">if</span> <span class="o">(</span><span class="n">userOrderPaymentVerified</span> <span class="o">&amp;&amp;</span> <span class="n">userOrderInventoryAvailable</span> <span class="o">&amp;&amp;</span> <span class="n">userOrderShippingAddressValid</span><span class="o">)</span> <span class="o">{</span>
        <span class="c1">// ... more code with these long names ...</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Every variable needs a prefix (<code class="language-plaintext highlighter-rouge">userOrder</code> + <code class="language-plaintext highlighter-rouge">Payment</code> + <code class="language-plaintext highlighter-rouge">Verified</code>) because in a large scope with many concerns, you need to disambiguate. The method handles payment, inventory, and shipping all at once, so variable names become bloated.</p>

<p>Now contrast with smaller, focused methods:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kt">void</span> <span class="nf">processUserOrder</span><span class="o">()</span> <span class="o">{</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">verifyPayment</span><span class="o">(</span><span class="n">order</span><span class="o">))</span> <span class="k">return</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">reserveInventory</span><span class="o">(</span><span class="n">order</span><span class="o">))</span> <span class="k">return</span><span class="o">;</span>
    <span class="k">if</span> <span class="o">(!</span><span class="n">scheduleShipping</span><span class="o">(</span><span class="n">order</span><span class="o">))</span> <span class="k">return</span><span class="o">;</span>
    <span class="n">completeOrder</span><span class="o">(</span><span class="n">order</span><span class="o">);</span>
<span class="o">}</span>

<span class="kd">private</span> <span class="kt">boolean</span> <span class="nf">verifyPayment</span><span class="o">(</span><span class="nc">Order</span> <span class="n">order</span><span class="o">)</span> <span class="o">{</span>
    <span class="kt">boolean</span> <span class="n">isVerified</span> <span class="o">=</span> <span class="n">paymentService</span><span class="o">.</span><span class="na">verify</span><span class="o">(</span><span class="n">order</span><span class="o">);</span>
    <span class="nc">String</span> <span class="n">transactionId</span> <span class="o">=</span> <span class="n">payment</span><span class="o">.</span><span class="na">getTransactionId</span><span class="o">();</span>
    
    <span class="k">if</span> <span class="o">(</span><span class="n">isVerified</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">order</span><span class="o">.</span><span class="na">setTransactionId</span><span class="o">(</span><span class="n">transactionId</span><span class="o">);</span>
        <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
    <span class="o">}</span>
    <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span>

<span class="kd">private</span> <span class="kt">boolean</span> <span class="nf">reserveInventory</span><span class="o">(</span><span class="nc">Order</span> <span class="n">order</span><span class="o">)</span> <span class="o">{</span>
    <span class="kt">boolean</span> <span class="n">isAvailable</span> <span class="o">=</span> <span class="n">inventory</span><span class="o">.</span><span class="na">check</span><span class="o">(</span><span class="n">order</span><span class="o">.</span><span class="na">items</span><span class="o">);</span>
    <span class="nc">String</span> <span class="n">reservationId</span> <span class="o">=</span> <span class="n">inventory</span><span class="o">.</span><span class="na">reserve</span><span class="o">(</span><span class="n">order</span><span class="o">.</span><span class="na">items</span><span class="o">);</span>
    
    <span class="k">if</span> <span class="o">(</span><span class="n">isAvailable</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">order</span><span class="o">.</span><span class="na">setReservationId</span><span class="o">(</span><span class="n">reservationId</span><span class="o">);</span>
        <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
    <span class="o">}</span>
    <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span>

<span class="kd">private</span> <span class="kt">boolean</span> <span class="nf">scheduleShipping</span><span class="o">(</span><span class="nc">Order</span> <span class="n">order</span><span class="o">)</span> <span class="o">{</span>
    <span class="kt">boolean</span> <span class="n">isAddressValid</span> <span class="o">=</span> <span class="n">validateAddress</span><span class="o">(</span><span class="n">user</span><span class="o">.</span><span class="na">shippingAddress</span><span class="o">);</span>
    <span class="nc">String</span> <span class="n">trackingNumber</span> <span class="o">=</span> <span class="n">shipping</span><span class="o">.</span><span class="na">createLabel</span><span class="o">(</span><span class="n">order</span><span class="o">);</span>
    
    <span class="k">if</span> <span class="o">(</span><span class="n">isAddressValid</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">order</span><span class="o">.</span><span class="na">setTrackingNumber</span><span class="o">(</span><span class="n">trackingNumber</span><span class="o">);</span>
        <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
    <span class="o">}</span>
    <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<p>In small methods, the method name can be relied upon to already be in your mental context window, so you don’t need to repeat yourself. The freer namespace enables you to assign more specific, relevant and less ambiguous names.</p>

<h2 id="3-scattered-state-mutation-and-function-purity">3. Scattered State Mutation and Function Purity</h2>

<p>Consider the following shopping basket implementation:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ShoppingBasket</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">LineItem</span><span class="o">&gt;</span> <span class="n">items</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kt">double</span> <span class="n">totalCost</span><span class="o">;</span>
    
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">addItem</span><span class="o">(</span><span class="nc">String</span> <span class="n">productId</span><span class="o">,</span> <span class="kt">int</span> <span class="n">quantity</span><span class="o">,</span> <span class="kt">double</span> <span class="n">unitPrice</span><span class="o">)</span> <span class="o">{</span>
        <span class="nc">LineItem</span> <span class="n">item</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">LineItem</span><span class="o">(</span><span class="n">productId</span><span class="o">,</span> <span class="n">quantity</span><span class="o">,</span> <span class="n">unitPrice</span><span class="o">);</span>
        <span class="n">items</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">item</span><span class="o">);</span>
        <span class="n">totalCost</span> <span class="o">+=</span> <span class="n">unitPrice</span> <span class="o">*</span> <span class="n">quantity</span><span class="o">;</span>
    <span class="o">}</span>
    
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">removeItem</span><span class="o">(</span><span class="nc">String</span> <span class="n">productId</span><span class="o">)</span> <span class="o">{</span>
        <span class="nc">LineItem</span> <span class="n">item</span> <span class="o">=</span> <span class="n">findItem</span><span class="o">(</span><span class="n">productId</span><span class="o">);</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">item</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
            <span class="n">items</span><span class="o">.</span><span class="na">remove</span><span class="o">(</span><span class="n">item</span><span class="o">);</span>
            <span class="n">totalCost</span> <span class="o">-=</span> <span class="n">item</span><span class="o">.</span><span class="na">getUnitPrice</span><span class="o">()</span> <span class="o">*</span> <span class="n">item</span><span class="o">.</span><span class="na">getQuantity</span><span class="o">();</span>
        <span class="o">}</span>
    <span class="o">}</span>
    
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">updateQuantity</span><span class="o">(</span><span class="nc">String</span> <span class="n">productId</span><span class="o">,</span> <span class="kt">int</span> <span class="n">newQuantity</span><span class="o">)</span> <span class="o">{</span>
        <span class="nc">LineItem</span> <span class="n">item</span> <span class="o">=</span> <span class="n">findItem</span><span class="o">(</span><span class="n">productId</span><span class="o">);</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">item</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
            <span class="kt">int</span> <span class="n">oldQuantity</span> <span class="o">=</span> <span class="n">item</span><span class="o">.</span><span class="na">getQuantity</span><span class="o">();</span>
            <span class="n">item</span><span class="o">.</span><span class="na">setQuantity</span><span class="o">(</span><span class="n">newQuantity</span><span class="o">);</span>
            <span class="n">totalCost</span> <span class="o">+=</span> <span class="n">item</span><span class="o">.</span><span class="na">getUnitPrice</span><span class="o">()</span> <span class="o">*</span> <span class="o">(</span><span class="n">newQuantity</span> <span class="o">-</span> <span class="n">oldQuantity</span><span class="o">);</span>
        <span class="o">}</span>
    <span class="o">}</span>
    
    <span class="kd">public</span> <span class="kt">double</span> <span class="nf">getTotalCost</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">totalCost</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">totalCost</code> is a property of the class. Each method is like an event that updates its value. Can you spot the bug here?</p>

<p>Mutable state is typically obscuring two realities about your code:</p>
<ol>
  <li>Every control flow of every method where that property is mutated (<code class="language-plaintext highlighter-rouge">totalCost += whatever</code>) represents a scattered logic. This logic can be extracted from across those methods and unified into one, new, communicatively named method (such as <code class="language-plaintext highlighter-rouge">calculateTotalCost()</code> in our case). Doing this leaves methods lighter and more maintainable.</li>
  <li>Your methods have deceptive return types. The output of your methods is not just the returned object/void, but also the delta of change to each mutated property.</li>
</ol>

<p>Your job then must be to realize that there is a scope one level above this current scope that is both (1) using your methods, and (2) relying on the state they are mutating. Here is where you should process the mutating state.</p>

<p>Realize the object value in this scope, only when needed, in the proximity of where it is actually being used to make it easier to understand <em>how</em> its being used, and name it specific to this context, not reusing names from a scope below that breaks the mental model of encapsulation.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// ViewModel uses calculateTotalCost() and names it for UI context</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">BasketView</span> <span class="o">{</span>
    <span class="kd">public</span> <span class="kt">double</span> <span class="nf">projectedBillWidget</span><span class="o">(</span><span class="nc">ShoppingBasket</span> <span class="n">basket</span><span class="o">)</span> <span class="o">{</span>
        <span class="o">...</span>
        <span class="c1">// the "total" in method name is specific to the</span>
        <span class="c1">// shopping basket scope, its a total over the</span>
        <span class="c1">// line items. variable name "lineItemsCost" is</span>
        <span class="c1">// specific to this context. this is better</span>
        <span class="c1">// encapsulation. in the view, "total"</span>
        <span class="c1">// may otherwise be confused with the basket</span>
        <span class="c1">// total, post discount total, maybe the payment</span>
        <span class="c1">// is split with a redeemed voucher and loyalty</span>
        <span class="c1">// points. a new variable automatically forces you</span>
        <span class="c1">// to be more specific about naming</span>
        <span class="kd">final</span> <span class="n">lineItemsCost</span> <span class="o">=</span> <span class="n">basket</span><span class="o">.</span><span class="na">calculateTotalCost</span><span class="o">();</span>
        <span class="kd">final</span> <span class="n">discounts</span> <span class="o">=</span> <span class="o">...</span>
        <span class="kd">final</span> <span class="n">costCharged</span> <span class="o">=</span> <span class="n">basketCost</span> <span class="o">-</span> <span class="n">discounts</span><span class="o">;</span>
        <span class="k">return</span> <span class="nf">Column</span><span class="o">(</span>
            <span class="s">"lineItemsCost"</span><span class="o">:</span> <span class="s">"$"</span> <span class="o">+</span> <span class="n">lineItemsCost</span><span class="o">.</span><span class="na">with2Decimals</span><span class="o">,</span>
            <span class="s">"discounts"</span><span class="o">:</span> <span class="s">"- $"</span> <span class="o">+</span> <span class="n">discount</span><span class="o">.</span><span class="na">with2Decimals</span><span class="o">,</span>
            <span class="s">"=========="</span>
            <span class="s">"costCharged"</span><span class="o">:</span> <span class="s">"$"</span> <span class="o">+</span> <span class="n">costCharged</span><span class="o">.</span><span class="na">with2Decimals</span><span class="o">,</span>
        <span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span>

<span class="c1">// Service uses it and names it for business context</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">OrderService</span> <span class="o">{</span>
    <span class="kd">public</span> <span class="nc">OrderResponse</span> <span class="nf">processOrder</span><span class="o">(</span><span class="nc">ShoppingBasket</span> <span class="n">basket</span><span class="o">)</span> <span class="o">{</span>
        <span class="kt">double</span> <span class="n">chargedAmount</span> <span class="o">=</span> <span class="n">basket</span><span class="o">.</span><span class="na">calculateTotalCost</span><span class="o">()</span> <span class="o">+</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span> <span class="o">+</span> <span class="n">z</span><span class="o">;</span>
        <span class="c1">// ... process payment ...</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nf">OrderResponse</span><span class="o">(</span><span class="n">chargedAmount</span><span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">OrderResponse</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="kt">double</span> <span class="n">chargedTotalCost</span><span class="o">;</span>
    
    <span class="kd">public</span> <span class="nf">OrderResponse</span><span class="o">(</span><span class="kt">double</span> <span class="n">chargedTotalCost</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">chargedTotalCost</span> <span class="o">=</span> <span class="n">chargedTotalCost</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Those who resist this approach often cite the memory cost of immutability over mutable state. But in most cases, defaulting to mutability for memory reasons is premature optimization. The garbage collection of immutable variables in small methods is trivial. If there actually is a memory constraint, profiling should be done and cache mechanisms could be considered, mutability being seen as one such cache mechanism.</p>

<p>Additionally, this is easier to maintain. Tomorrow if you realize you want to change totalCost based on time specific discounts for Christmas or Labor Day or so, you can do that swapping the calculated value with an output from a service that can be swapped at runtime. Just one maintenance scenario that would have been trickier to otherwise accomplish with deeply rooted mutating state.</p>

<h3 id="function-purity-as-a-spectrum">Function Purity as a Spectrum</h3>

<p>The definition for functions was taught to me in grade school, a function is something that, for a given input, always maps it to the same output.</p>

<p>The input for a function is its arguments. You only need to understand the arguments passed and the method body to be able to make changes to it.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">static</span> <span class="kt">double</span> <span class="nf">calculateDiscount</span><span class="o">(</span><span class="kt">double</span> <span class="n">price</span><span class="o">,</span> <span class="kt">double</span> <span class="n">rate</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">return</span> <span class="n">price</span> <span class="o">*</span> <span class="n">rate</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<p>The input for methods is their arguments + the properties the object its called on has access to. To make changes to a method, you need to understand the arguments, the method body, and additionally these object properties.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">PricingCalculator</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="kt">double</span> <span class="n">discountRate</span><span class="o">;</span>
    
    <span class="kd">public</span> <span class="nf">PricingCalculator</span><span class="o">(</span><span class="kt">double</span> <span class="n">discountRate</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">discountRate</span> <span class="o">=</span> <span class="n">discountRate</span><span class="o">;</span>
    <span class="o">}</span>
    
    <span class="kd">public</span> <span class="kt">double</span> <span class="nf">calculateDiscount</span><span class="o">(</span><span class="kt">double</span> <span class="n">price</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">price</span> <span class="o">*</span> <span class="n">discountRate</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>

<span class="c1">// Usage</span>
<span class="nc">PricingCalculator</span> <span class="n">calculator</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PricingCalculator</span><span class="o">(</span><span class="mf">0.1</span><span class="o">);</span>
<span class="kt">double</span> <span class="n">discount</span> <span class="o">=</span> <span class="n">calculator</span><span class="o">.</span><span class="na">calculateDiscount</span><span class="o">(</span><span class="mf">100.0</span><span class="o">);</span>
</code></pre></div></div>

<p>If these object properties were immutable/final, you only need to look at one place, i.e. where the object was initialized, to understand how their value may vary. When these properties are <em>mutable</em> however, you have to understand <em>every</em> place where this property is mutated.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ShoppingCart</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="kt">double</span> <span class="n">discountRate</span><span class="o">;</span>  <span class="c1">// ← mutable state</span>
    
    <span class="kd">public</span> <span class="nf">ShoppingCart</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">discountRate</span> <span class="o">=</span> <span class="mf">0.0</span><span class="o">;</span>  <span class="c1">// mutation #1</span>
    <span class="o">}</span>
    
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">applyMemberDiscount</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">discountRate</span> <span class="o">=</span> <span class="mf">0.1</span><span class="o">;</span>  <span class="c1">// mutation #2</span>
    <span class="o">}</span>
    
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">applySeasonalDiscount</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">discountRate</span> <span class="o">=</span> <span class="mf">0.15</span><span class="o">;</span>  <span class="c1">// mutation #3</span>
    <span class="o">}</span>
    
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">applyLoyaltyBonus</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">discountRate</span> <span class="o">+=</span> <span class="mf">0.05</span><span class="o">;</span>  <span class="c1">// mutation #4</span>
    <span class="o">}</span>
    
    <span class="kd">public</span> <span class="kt">double</span> <span class="nf">calculateDiscount</span><span class="o">(</span><span class="kt">double</span> <span class="n">price</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">price</span> <span class="o">*</span> <span class="n">discountRate</span><span class="o">;</span>  <span class="c1">// depends on mutations #1-4</span>
    <span class="o">}</span>
<span class="o">}</span>

<span class="c1">// Usage</span>
<span class="nc">ShoppingCart</span> <span class="n">cart</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ShoppingCart</span><span class="o">();</span>
<span class="n">cart</span><span class="o">.</span><span class="na">applyMemberDiscount</span><span class="o">();</span>
<span class="n">cart</span><span class="o">.</span><span class="na">applyLoyaltyBonus</span><span class="o">();</span>
<span class="kt">double</span> <span class="n">discount</span> <span class="o">=</span> <span class="n">cart</span><span class="o">.</span><span class="na">calculateDiscount</span><span class="o">(</span><span class="mf">100.0</span><span class="o">);</span> <span class="c1">// What is discountRate now?</span>
</code></pre></div></div>

<p>Every place where this value is mutated gives rise to n more states that your function now has to cater to. Not catering to these states risks leaving your application in an invalid state. It may be fine today but in a year’s time doing this will leave your system riddled with bugs regarding “unexpected” use cases.</p>

<p>It is often even much much worse than this example, because when folks are not careful about mutation, in reality they will be mutating state far beyond the scope of one class into other classes which mutate other classes, and building a mental model of this will be complex in a way that you could mathematically even then demonstrate.</p>

<p>The more immutable properties being used by your methods, the more “impure” your function is, impurity here referring to how dependent your output is on mutable, external variables. For a human or an AI agent, this makes it difficult to reason about, as the search space for changes explodes exponentially, and making changes to such classes becomes slow and risky.</p>

<p>Using the term “function purity” has a tendency to upset software engineers however, and you will find accusations of rigidity and impracticality common in such discussions at the mere mention of this word.</p>

<p>What is important to remember is that purity is a spectrum that you can slide both high and low on. Don’t uproot your whole codebase to start implementing this advice. You don’t have to be 100% pure 100% of the time. But you do need to understand what it means so you can use it as a warning sign of your code quality.</p>

<h3 id="when-to-break-the-rules">When to Break the Rules</h3>

<p>These guidelines aren’t absolute. There are times when mutable state is the right choice: performance-critical loops, large data structures where copying is prohibitively expensive, stateful systems like game engines or UI frameworks where state machines are idiomatic.</p>

<p>But here’s the key: <strong>you yourself will be a bad judge of the exceptions</strong>. The things that are obvious and simple to you as the author of the code will not be similarly obvious to another maintainer or yourself in a week’s time.</p>

<p>These styles require learning to see code in a certain way. They don’t ask you to refactor a whole codebase today. They’re defaults, not additional structures, that keep you in flow state for longer by shrinking the search space for code reviews. Hopefully they will make coding more joyful and less adversarial with AI agents when you have to deal with the 23423th suggested code review of the day.</p>

<p>Comments welcome here;
https://www.linkedin.com/posts/sohaibbaig1_shrinking-the-search-space-for-code-reviews-activity-7456003268729692161-cDW6</p>]]></content><author><name></name></author><category term="coding-practices" /><summary type="html"><![CDATA[Tightening the human feedback loop is prominent now as a bottleneck with agent assisted coding. Whilst coding “practices” like continuous deployment and TDD are already espoused by many, I wanted to mention “styles”, instead, of coding.]]></summary></entry></feed>