<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>version2beta</title>
    <link>https://version2beta.com/</link>
    <description>Essays on software, complexity, and engineering practice by M. Robert Martin. Hands-on engineering, architecture, and coding-agent workflows.</description>
    <language>en-US</language>
    <atom:link href="https://version2beta.com/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Simplify, Simplify, Simplify</title>
      <link>https://version2beta.com/writing/simplify-simplify-simplify/</link>
      <guid isPermaLink="true">https://version2beta.com/writing/simplify-simplify-simplify/</guid>
      <pubDate>Thu, 15 Oct 2026 00:00:00 +0000</pubDate>
      <dc:creator>M. Robert Martin</dc:creator>
      <description>&lt;p&gt;Back when the most advanced programming language a geeky teen could find was BASICA (it had ADVANCED right in the name!), we were not very empathetic. We created sayings like “users are losers,” “PEBCAK: problem exists between chair and keyboard,” and “RTFM.” We could be quite mean.&lt;/p&gt;
&lt;p&gt;Our code was even worse than our behavior. Our tools were horrible. Our expectations were dreadful. When code got long, we expected to keep it all in our heads. When we couldn’t, we’d question whether we were cut out for programming. Failing to reason about code, no matter how bad the code, was a personal failing.&lt;/p&gt;
&lt;p&gt;Fortunately, we&amp;rsquo;ve learned that we don&amp;rsquo;t have to work so hard. Here are three ways to simplify.&lt;/p&gt;
&lt;h2 id=&#34;part-one-simplify&#34;&gt;Part one: Simplify&lt;/h2&gt;
&lt;p&gt;Sandi Metz carved out some programming advice on the Ruby Rogues podcast in 2013.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; Advice might not be a strong enough word. “Commandments” may be better. Her advice is aimed primarily at object-oriented Ruby programmers, but three numerical constraints and a rule for breaking them are worth trying elsewhere too.&lt;/p&gt;
&lt;h3 id=&#34;classes-may-not-have-more-than-100-lines-of-code&#34;&gt;Classes may not have more than 100 lines of code&lt;/h3&gt;
&lt;p&gt;Long ago, I worked with two women who always paired. They spent a month refactoring a single class: 10,000 lines of Java 7, including one method that was 5,000 lines long. Their work was a master class in refactoring.&lt;/p&gt;
&lt;p&gt;Proposing a hundred-line limit would have gotten me kicked out of their space. But the number isn&amp;rsquo;t a measurement of good design. Splitting that class into a hundred files wouldn&amp;rsquo;t help if we still needed to understand all of them to change any one of them.&lt;/p&gt;
&lt;p&gt;David Parnas explored this problem in his 1972 paper, &lt;em&gt;On the Criteria To Be Used in Decomposing Systems into Modules&lt;/em&gt;.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; He took a small text-indexing system and decomposed it in two different ways. One followed the steps of processing the data. The other organized modules around design decisions they could conceal from the rest of the system.&lt;/p&gt;
&lt;p&gt;Both worked. But changes to the data representation affected multiple parts of the first design, while the second was organized to confine such changes behind a module interface.&lt;/p&gt;
&lt;p&gt;John Ousterhout takes this further in &lt;em&gt;A Philosophy of Software Design&lt;/em&gt;.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; He describes &lt;strong&gt;deep modules&lt;/strong&gt;: substantial functionality hidden behind simple interfaces. Sometimes a larger class is better precisely because it keeps more complexity to itself.&lt;/p&gt;
&lt;p&gt;So the useful question isn&amp;rsquo;t how many lines a class contains. It&amp;rsquo;s what belongs together. Which design decisions does it hide? Can we change those decisions without changing unrelated parts of the application? Can we understand and use the class without understanding its implementation?&lt;/p&gt;
&lt;p&gt;A line limit doesn&amp;rsquo;t give us answers; it gives us a reason to stop and ask.&lt;/p&gt;
&lt;p&gt;Start with a constraint. See what it reveals.&lt;/p&gt;
&lt;h3 id=&#34;methods-may-not-have-more-than-five-lines-of-code&#34;&gt;Methods may not have more than five lines of code&lt;/h3&gt;
&lt;p&gt;Metz&amp;rsquo;s five-line rule encourages us to look for pieces of work that can be given meaningful names. A good name lets us understand what a function does without needing to read how it does it.&lt;/p&gt;
&lt;p&gt;But moving five lines into another function doesn&amp;rsquo;t necessarily make anything simpler. We need to find a useful boundary, one that allows us to understand one part of the program without understanding another.&lt;/p&gt;
&lt;p&gt;Every implementation detail we need to keep in our head adds a little to our cognitive load. It&amp;rsquo;s like piling snowflakes onto a tree branch, or straw on a camel&amp;rsquo;s back. Each weighs almost nothing, but eventually something is going to break. A well-named function lets us set some of that weight aside.&lt;/p&gt;
&lt;p&gt;For an example, let&amp;rsquo;s borrow a small decision from Apollo 11&amp;rsquo;s lunar-module software, developed at MIT&amp;rsquo;s Instrumentation Laboratory, where Margaret Hamilton led the software engineering effort.&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;The computer&amp;rsquo;s Executive program managed jobs and their working storage. To start an interpretive job, it needed two kinds of resources: one of five working-storage areas, called VAC areas, and one of seven core sets. It raised alarm 1201 when no VAC area was available, or 1202 when no core set was available.&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s borrow those rules for a deliberately simplified Python example—not a translation of the flight software. We&amp;rsquo;ll represent the two resource pools with Boolean values, where &lt;code&gt;True&lt;/code&gt; means a slot is free:&lt;/p&gt;
&lt;figure class=&#34;codeblock&#34;&gt;&lt;figcaption class=&#34;lang&#34;&gt;python&lt;/figcaption&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;vac&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;free&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;enumerate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vac_areas&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;free&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vac&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;report_alarm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mo&#34;&gt;0o1201&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;core&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;free&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;enumerate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;core_sets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;free&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;core&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;report_alarm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mo&#34;&gt;0o1202&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;reserve_resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vac&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;core&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;The alarm codes are written in octal, as they were in the original. We have a small piece of resource-allocation policy mixed with its consequences. To understand the caller, we have to follow the search, the order in which resources are checked, and both failure paths.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s give that decision a name:&lt;/p&gt;
&lt;figure class=&#34;codeblock&#34;&gt;&lt;figcaption class=&#34;lang&#34;&gt;python&lt;/figcaption&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;plan_interpretive_job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vac_areas&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;core_sets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;vac&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;free&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;enumerate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vac_areas&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;free&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vac&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mo&#34;&gt;0o1201&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;core&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;free&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;enumerate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;core_sets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;free&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;core&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mo&#34;&gt;0o1202&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vac&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;core&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;Now the caller has less to consider:&lt;/p&gt;
&lt;figure class=&#34;codeblock&#34;&gt;&lt;figcaption class=&#34;lang&#34;&gt;python&lt;/figcaption&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;alarm&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;plan_interpretive_job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vac_areas&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;core_sets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;alarm&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;report_alarm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;alarm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;vac&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;core&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;resources&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;reserve_resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vac&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;core&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;This isn&amp;rsquo;t just a standard-library search given another name. The helper expresses a policy: an interpretive job needs both kinds of storage; failure to find a VAC area produces 1201; failure to find a core set produces 1202. A caller can rely on that contract without reopening the implementation.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s also more than five lines long. Splitting it further just to meet the rule could scatter a small, coherent decision across several functions. The rule has given us a reason to examine the code; it hasn&amp;rsquo;t settled the design for us.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s what I want from a small function: a meaningful piece of work with a name I can rely on. Not merely five lines moved somewhere else.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve also exposed another question: who owns &lt;code&gt;vac_areas&lt;/code&gt; and &lt;code&gt;core_sets&lt;/code&gt;, and what guarantees that their availability won&amp;rsquo;t change between planning and reservation? The real Executive wasn&amp;rsquo;t written as a separate plan-then-commit operation; the separation here is illustrative. A real allocator must coordinate those steps.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll come back to that.&lt;/p&gt;
&lt;h3 id=&#34;pass-no-more-than-four-parameters-to-a-method&#34;&gt;Pass no more than four parameters to a method&lt;/h3&gt;
&lt;p&gt;A function&amp;rsquo;s parameters tell us what it needs to know to do its work, and looking at its list of parameters can tell us quite a lot about the function itself. Do the parameters describe one coherent operation? Do some seem unrelated to the others? Are several parameters always used together? Does the function need different parameters depending on which path it takes?&lt;/p&gt;
&lt;p&gt;A long parameter list can reveal a function that is doing too much. But it can also reveal several values that belong to one concept. Martin Fowler calls the latter &lt;em&gt;data clumps&lt;/em&gt;.&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; If we repeatedly pass a start date and an end date together, perhaps what we really have is an interval. Giving that concept a name lets us put its meaning, constraints, and perhaps some of its behavior in one place.&lt;/p&gt;
&lt;p&gt;Parameters can also reveal unnecessary decisions. Consider a function that accepts a Boolean telling it which of two operations to perform. Fowler calls this a &lt;em&gt;flag argument&lt;/em&gt;.&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt; Sometimes two well-named functions would express the available operations more clearly.&lt;/p&gt;
&lt;p&gt;But shortening the list is not the goal. Putting eight unrelated arguments in a &lt;code&gt;context&lt;/code&gt; object doesn&amp;rsquo;t make them related. Moving them into global state makes the signature shorter while making the function&amp;rsquo;s needs harder to see. Remember &lt;code&gt;plan_interpretive_job(vac_areas, core_sets)&lt;/code&gt; from our Apollo example? Its two inputs describe two distinct resource pools. Changing it to &lt;code&gt;plan_interpretive_job()&lt;/code&gt; would hide where that information comes from: an object field, a global variable, or something retrieved elsewhere. We&amp;rsquo;d have removed something useful from the signature.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d rather have an honest parameter list that tells me whether the work should be divided, whether related values deserve a name, or whether the function depends on things it shouldn&amp;rsquo;t need.&lt;/p&gt;
&lt;p&gt;Four parameters isn&amp;rsquo;t a measure of good design. It&amp;rsquo;s another reason to stop and ask questions.&lt;/p&gt;
&lt;h3 id=&#34;break-these-rules-only-if-your-pair-agrees&#34;&gt;Break these rules only if your pair agrees&lt;/h3&gt;
&lt;p&gt;Sometimes breaking a rule produces better code. Maybe a longer method keeps a coherent calculation together. Maybe another parameter makes a dependency explicit. Maybe extracting one more helper would scatter an idea that&amp;rsquo;s already easy to follow.&lt;/p&gt;
&lt;p&gt;When breaking a rule makes the code better, try explaining the rule and your reason for breaking it to another developer or in a pull request. Someone else may see something we&amp;rsquo;ve missed. Perhaps the longer method really does contain two responsibilities. Perhaps the extra parameter belongs to a concept we haven&amp;rsquo;t recognized. Or perhaps the exception is exactly the right choice.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re not looking for permission. We&amp;rsquo;re not looking for consensus. We&amp;rsquo;re testing our reasoning against another person&amp;rsquo;s understanding. If we can&amp;rsquo;t explain why breaking the rule improves the code, we may not understand the trade-off well enough.&lt;/p&gt;
&lt;p&gt;The rule has served its purpose even when we decide to break it.&lt;/p&gt;
&lt;h3 id=&#34;net-effect&#34;&gt;Net effect&lt;/h3&gt;
&lt;p&gt;Sandi describes the purpose of object-oriented design as reducing the cost of change.&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt; I find that a little too transactional. I prefer to think of these constraints as ways to protect my cognitive load.&lt;/p&gt;
&lt;p&gt;I enjoy my work best—and find it most rewarding—when I can focus on the problem in front of me without keeping tens, hundreds, or thousands of lines of semi-related code in my head.&lt;/p&gt;
&lt;p&gt;Smaller classes and methods can help, but only when they reduce what I need to understand. If I have to follow a dozen functions across half a dozen files to understand one operation, we haven&amp;rsquo;t necessarily simplified anything. We&amp;rsquo;ve just moved the complexity around.&lt;/p&gt;
&lt;p&gt;The goal isn&amp;rsquo;t to write less code or divide it into smaller pieces. It&amp;rsquo;s to reduce how much we need to know at once.&lt;/p&gt;
&lt;h2 id=&#34;part-two-simplify&#34;&gt;Part two: Simplify&lt;/h2&gt;
&lt;p&gt;One of my favorite programming adages is &amp;ldquo;Don&amp;rsquo;t comment your code.&amp;rdquo; This can be counterintuitive, counterproductive, or just plain countered by others on your team. But it does have merit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Comments lie&lt;/strong&gt;. More precisely, they can describe what we intended long after the implementation has changed. When this happens, we have two conflicting accounts, and we need to work out which one matches the requirement.&lt;/p&gt;
&lt;p&gt;Before writing a comment, I like to consider a few alternatives.&lt;/p&gt;
&lt;h3 id=&#34;can-i-write-a-well-named-function-instead&#34;&gt;Can I write a well-named function instead?&lt;/h3&gt;
&lt;p&gt;We already have one: &lt;code&gt;plan_interpretive_job&lt;/code&gt;. At the call site, that name lets us think about the resource-allocation decision without following two searches and two different alarm conditions.&lt;/p&gt;
&lt;p&gt;But the implementation has to earn the name. If &lt;code&gt;plan_interpretive_job&lt;/code&gt; also reserves the resources, the caller&amp;rsquo;s separate &lt;code&gt;reserve_resources&lt;/code&gt; operation becomes suspicious. Are we reserving the same slots twice? Could the second operation fail? What other behavior might the name be hiding? Perhaps we need a different name, or perhaps we&amp;rsquo;ve combined two responsibilities that should be separate. Names aren&amp;rsquo;t decoration. They&amp;rsquo;re part of how we explain what another programmer can rely on, without requiring them to inspect the implementation each time.&lt;/p&gt;
&lt;h3 id=&#34;can-i-write-a-test-instead&#34;&gt;Can I write a test instead?&lt;/h3&gt;
&lt;p&gt;Suppose we add this comment to our Apollo-inspired planner:&lt;/p&gt;
&lt;figure class=&#34;codeblock&#34;&gt;&lt;figcaption class=&#34;lang&#34;&gt;python&lt;/figcaption&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Choose available VAC and core slots; report 1201 or 1202 if exhausted.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;That tells a reader what we intend. But we can express the same expectations in a test:&lt;/p&gt;
&lt;figure class=&#34;codeblock&#34;&gt;&lt;figcaption class=&#34;lang&#34;&gt;python&lt;/figcaption&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test_plan_interpretive_job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;vacs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;cores&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;plan_interpretive_job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vacs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cores&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;plan_interpretive_job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cores&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mo&#34;&gt;0o1201&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;plan_interpretive_job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vacs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mo&#34;&gt;0o1202&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;plan_interpretive_job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mo&#34;&gt;0o1201&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;The first assertion checks that we select the first available slot in each pool. The next two distinguish exhausted VAC areas from exhausted core sets. The last establishes which alarm takes precedence if both are exhausted. Unlike the comment, these expectations can be checked against the implementation. If someone changes the allocation policy, the tests can catch it.&lt;/p&gt;
&lt;p&gt;Tests can be wrong, too. They can express a mistaken requirement or leave out an important case. A passing test demonstrates agreement with the expectations we&amp;rsquo;ve written, not that we&amp;rsquo;ve expressed every necessary expectation.&lt;/p&gt;
&lt;p&gt;Still, an executable example gives a reader something useful: a concrete statement of behavior that can be checked.&lt;/p&gt;
&lt;h3 id=&#34;does-the-comment-preserve-something-the-code-cannot-say&#34;&gt;Does the comment preserve something the code cannot say?&lt;/h3&gt;
&lt;p&gt;The Apollo 11 Executive source includes this comment beside the instructions that reserve a working-storage area:&lt;/p&gt;
&lt;figure class=&#34;codeblock&#34;&gt;&lt;figcaption class=&#34;lang&#34;&gt;text&lt;/figcaption&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;RESERVE THIS VAC AREA BY STORING A ZERO
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;IN ITS VAC USE REGISTER&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;The full comment also explains how the address of the reserved area is stored in the job&amp;rsquo;s priority word.&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Our Python example uses &lt;code&gt;True&lt;/code&gt; to indicate an available slot. The Apollo code uses a different representation: storing zero in a VAC use register marks the area as reserved. That comment helps explain what the assembly instructions accomplish, including a detail that isn&amp;rsquo;t obvious from the instructions themselves.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s useful information. Removing it because &amp;ldquo;good code doesn&amp;rsquo;t need comments&amp;rdquo; would not make the original easier to understand.&lt;/p&gt;
&lt;p&gt;Of course, this does not justify comments to excuse confusing code. If a comment is necessary to understand an ordinary calculation, perhaps the calculation needs a better name, a clearer representation, or a simpler implementation. Chances are excellent that the code can communicate this better.&lt;/p&gt;
&lt;p&gt;Sometimes information genuinely belongs outside the code. A hardware constraint, an external specification, a compatibility requirement, or the reason an apparently simpler approach is unsafe may not be expressible in the implementation itself. First ask whether the code could make the idea clear. If it cannot, explain what a capable reader couldn&amp;rsquo;t reasonably infer.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t want fewer comments at the expense of understanding. I want code, tests, and comments all to contribute to understanding.&lt;/p&gt;
&lt;h2 id=&#34;part-three-simplify&#34;&gt;Part three: Simplify&lt;/h2&gt;
&lt;p&gt;Pure functions give us another way to make code easier to understand. They let us separate calculations from changes to application state, so we can reason about one without needing to understand the other.&lt;/p&gt;
&lt;h3 id=&#34;what-makes-a-function-pure&#34;&gt;What makes a function pure?&lt;/h3&gt;
&lt;p&gt;A pure function returns the same result for the same input values and has no observable side effects. It doesn&amp;rsquo;t read the clock, fetch a database record, or modify an object supplied by its caller.&lt;/p&gt;
&lt;p&gt;This gives us &lt;strong&gt;referential transparency&lt;/strong&gt;: we can replace a function call with its result without changing the program&amp;rsquo;s meaning.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s return to the Apollo 11 Executive, this time to a different operation.&lt;/p&gt;
&lt;p&gt;When a job finished, the Executive&amp;rsquo;s &lt;code&gt;ENDJOB1&lt;/code&gt; routine released its working storage and searched for the highest-priority active job.&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt; Imagine a simplified scheduler that keeps job priorities in a collection, with &lt;code&gt;None&lt;/code&gt; representing an unused slot. We might write:&lt;/p&gt;
&lt;figure class=&#34;codeblock&#34;&gt;&lt;figcaption class=&#34;lang&#34;&gt;python&lt;/figcaption&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;complete_job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;scheduler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;priorities&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;scheduler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dispatch_next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;This function has an implicit dependency on &lt;code&gt;scheduler&lt;/code&gt;. It changes the scheduler&amp;rsquo;s state and starts another operation. To understand its behavior, we need to know what &lt;code&gt;scheduler&lt;/code&gt; is, what state it holds, and what &lt;code&gt;dispatch_next&lt;/code&gt; does.&lt;/p&gt;
&lt;p&gt;We can separate part of that work into a pure function:&lt;/p&gt;
&lt;figure class=&#34;codeblock&#34;&gt;&lt;figcaption class=&#34;lang&#34;&gt;python&lt;/figcaption&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;priorities_after_completion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;priorities&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;index&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;priorities&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;IndexError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;priorities&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;priorities&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;Here, &lt;code&gt;priorities&lt;/code&gt; is an immutable tuple containing priority numbers or &lt;code&gt;None&lt;/code&gt;. The function calculates a new state without modifying the original. It doesn&amp;rsquo;t know about the scheduler, release any actual resources, or dispatch another job. We&amp;rsquo;ve made its dependencies explicit and separated the decision about the new state from the operation that applies it.&lt;/p&gt;
&lt;h3 id=&#34;simple-to-understand-simple-to-test&#34;&gt;Simple to understand, simple to test&lt;/h3&gt;
&lt;p&gt;We can demonstrate its behavior with a few assertions:&lt;/p&gt;
&lt;figure class=&#34;codeblock&#34;&gt;&lt;figcaption class=&#34;lang&#34;&gt;python&lt;/figcaption&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;before&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;40&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;after&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;priorities_after_completion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;before&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;after&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;before&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;40&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;priorities_after_completion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;before&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;after&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;The first assertion verifies the result. The second demonstrates that the original state hasn&amp;rsquo;t changed. The third checks that the same inputs produce the same output. We can understand and test this behavior without starting a scheduler, creating a mock, or reproducing the state of a guidance computer. Everything the function needs is in its arguments.&lt;/p&gt;
&lt;p&gt;Of course, we still need code that applies the change and dispatches the next job. In a concurrent system, that work must be coordinated so another operation can&amp;rsquo;t change the authoritative state between our calculation and its application. The pure function doesn&amp;rsquo;t solve that problem. It gives us one small piece of the problem that we can understand independently.&lt;/p&gt;
&lt;p&gt;And this Python example isn&amp;rsquo;t a translation of Apollo&amp;rsquo;s implementation. It leaves out the actual machine representation, resource management, interrupt handling, and scheduling behavior. We&amp;rsquo;re borrowing an operation to examine, not redesigning a spacecraft.&lt;/p&gt;
&lt;h3 id=&#34;useful-not-magical&#34;&gt;Useful, not magical&lt;/h3&gt;
&lt;p&gt;Pure functions aren&amp;rsquo;t automatically simple or correct. A pure function can implement the wrong rule, contain a complicated algorithm, or consume unreasonable amounts of resources. Nor does purity make an entire application immune to concurrency problems. We still need to coordinate state changes, manage resources, and handle failures.&lt;/p&gt;
&lt;p&gt;What purity offers is more modest, but remarkably useful: we can understand a calculation from its inputs and test it without setting up the world around it.&lt;/p&gt;
&lt;p&gt;Gary Bernhardt demonstrates a practical way to organize applications around this principle in his 2012 &lt;em&gt;Destroy All Software&lt;/em&gt; screencast, &lt;em&gt;Functional Core, Imperative Shell&lt;/em&gt;.&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt; The idea is to keep decisions and calculations in a functional core, while an imperative shell handles interactions with the outside world. The core contains behavior we can reason about independently. The shell obtains inputs, calls the core, and applies its results.&lt;/p&gt;
&lt;p&gt;Our example is a small instance of that separation. One function calculates what the scheduler&amp;rsquo;s state should become. Other code is responsible for making the change happen.&lt;/p&gt;
&lt;p&gt;We can use this approach in almost any language. We don&amp;rsquo;t need to turn the entire application into a functional-programming exercise to benefit.&lt;/p&gt;
&lt;h2 id=&#34;room-to-think&#34;&gt;Room to think&lt;/h2&gt;
&lt;p&gt;Shorter classes, smaller methods, useful tests, and pure functions are not ends in themselves. They help when they let us see what matters right now.&lt;/p&gt;
&lt;p&gt;A useful boundary lets us understand a caller without tracing every implementation detail. A test lets us check behavior without relying on memory or assumptions alone. A pure function lets us reason about a calculation without reconstructing the state of the world around it.&lt;/p&gt;
&lt;p&gt;But simplicity requires judgment. Sometimes extracting a function hides complexity; sometimes it scatters it. Sometimes a test communicates more than a comment; sometimes a comment preserves something neither the code nor the test can say. Sometimes adding a parameter makes a function easier to understand, not harder. These are small decisions, but their effects accumulate. They can make a working day quite different.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t want to prove that I can keep an entire system in my head. I want to understand what I&amp;rsquo;m changing and have useful evidence that it works.&lt;/p&gt;
&lt;p&gt;I want to think about less, so I have more room to think about the problem in front of me.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Sandi Metz&amp;rsquo;s original rules were discussed on &lt;em&gt;Ruby Rogues&lt;/em&gt; in January 2013. The transcript and rule list&lt;sup class=&#34;link-note-ref&#34; id=&#34;link-note-ref-1&#34;&gt;&lt;a href=&#34;#link-note-1&#34; role=&#34;doc-noteref&#34; aria-label=&#34;Reference 1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; give three numerical limits, a Rails controller/view rule, and permission to break the rules when a pair agrees. The fourth heading here discusses that exception, not the original Rails-specific rule.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;D. L. Parnas, &lt;em&gt;On the Criteria To Be Used in Decomposing Systems into Modules&lt;/em&gt;&lt;sup class=&#34;link-note-ref&#34; id=&#34;link-note-ref-2&#34;&gt;&lt;a href=&#34;#link-note-2&#34; role=&#34;doc-noteref&#34; aria-label=&#34;Reference 2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, &lt;em&gt;Communications of the ACM&lt;/em&gt;, December 1972. His contrasting decompositions of a key-word-in-context index illustrate information hiding: modules should conceal decisions likely to change, rather than merely follow processing steps.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;John Ousterhout, &lt;em&gt;A Philosophy of Software Design&lt;/em&gt;&lt;sup class=&#34;link-note-ref&#34; id=&#34;link-note-ref-3&#34;&gt;&lt;a href=&#34;#link-note-3&#34; role=&#34;doc-noteref&#34; aria-label=&#34;Reference 3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;, particularly the discussion of &lt;em&gt;deep modules&lt;/em&gt;. A simple interface can hide substantial complexity; splitting code into more, shallower modules may increase what callers must understand.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Margaret Hamilton led MIT&amp;rsquo;s Apollo onboard-flight-software effort. Reflecting on that work, she said, “Looking back, we were the luckiest people in the world; there was no choice but to be pioneers.” MIT&amp;rsquo;s October 7, 2026 remembrance&lt;sup class=&#34;link-note-ref&#34; id=&#34;link-note-ref-4&#34;&gt;&lt;a href=&#34;#link-note-4&#34; role=&#34;doc-noteref&#34; aria-label=&#34;Reference 4&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; confirms that she died on September 30, 2026, at age 90. The flight software was the work of a team.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;Apollo 11 Lunar Module software, Luminary 099, &lt;code&gt;EXECUTIVE.agc&lt;/code&gt;&lt;sup class=&#34;link-note-ref&#34; id=&#34;link-note-ref-5&#34;&gt;&lt;a href=&#34;#link-note-5&#34; role=&#34;doc-noteref&#34; aria-label=&#34;Reference 5&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;, &lt;code&gt;FINDVAC2&lt;/code&gt;, &lt;code&gt;VACFOUND&lt;/code&gt;, and &lt;code&gt;NOVAC2&lt;/code&gt;, printed pages 1106–1107. The source searches five VAC-use registers, raising octal alarm &lt;code&gt;1201&lt;/code&gt; when none is available, then searches seven core sets, raising &lt;code&gt;1202&lt;/code&gt; when none is available. Unlike this simplified plan-before-commit model, the original reserves the VAC area before searching for a core set. The source also includes entry paths for jobs that do not require VAC storage. The Python snippets illustrate a resource decision rather than reproduce the flight software.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;Martin Fowler, “Data Clump”&lt;sup class=&#34;link-note-ref&#34; id=&#34;link-note-ref-6&#34;&gt;&lt;a href=&#34;#link-note-6&#34; role=&#34;doc-noteref&#34; aria-label=&#34;Reference 6&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;, January 5, 2006. Repeatedly passing related values together may suggest a missing domain value such as an interval.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;Martin Fowler, “Flag Argument”&lt;sup class=&#34;link-note-ref&#34; id=&#34;link-note-ref-7&#34;&gt;&lt;a href=&#34;#link-note-7&#34; role=&#34;doc-noteref&#34; aria-label=&#34;Reference 7&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;, June 23, 2011. A parameter that selects between distinct operations can obscure caller intent; separate named operations may communicate it better.&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;Sandi Metz, “How Shall We Define Design?”&lt;sup class=&#34;link-note-ref&#34; id=&#34;link-note-ref-8&#34;&gt;&lt;a href=&#34;#link-note-8&#34; role=&#34;doc-noteref&#34; aria-label=&#34;Reference 8&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;, July 5, 2012. Metz explicitly describes the purpose of object-oriented design as reducing the cost of change.&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;Luminary 099, &lt;code&gt;EXECUTIVE.agc&lt;/code&gt;&lt;sup class=&#34;link-note-ref&#34; id=&#34;link-note-ref-9&#34;&gt;&lt;a href=&#34;#link-note-9&#34; role=&#34;doc-noteref&#34; aria-label=&#34;Reference 9&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;, &lt;code&gt;VACFOUND&lt;/code&gt;, printed page 1106. The source comment explains that writing zero marks a VAC area as reserved and that the area&amp;rsquo;s address is stored in the low nine bits of a priority word.&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34;&gt;
&lt;p&gt;Luminary 099, &lt;code&gt;EXECUTIVE.agc&lt;/code&gt;&lt;sup class=&#34;link-note-ref&#34; id=&#34;link-note-ref-10&#34;&gt;&lt;a href=&#34;#link-note-10&#34; role=&#34;doc-noteref&#34; aria-label=&#34;Reference 10&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;, &lt;code&gt;ENDJOB1&lt;/code&gt; and &lt;code&gt;EJSCAN&lt;/code&gt;, printed pages 1113–1115. The routines release a completed job&amp;rsquo;s core set and VAC area and scan for the highest active priority. The Python model omits much of the real scheduler&amp;rsquo;s behavior.&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:11&#34;&gt;
&lt;p&gt;Gary Bernhardt, &lt;em&gt;Functional Core, Imperative Shell&lt;/em&gt;&lt;sup class=&#34;link-note-ref&#34; id=&#34;link-note-ref-11&#34;&gt;&lt;a href=&#34;#link-note-11&#34; role=&#34;doc-noteref&#34; aria-label=&#34;Reference 11&#34;&gt;11&lt;/a&gt;&lt;/sup&gt;, &lt;em&gt;Destroy All Software&lt;/em&gt;, July 12, 2012. The screencast demonstrates pure application logic surrounded by a shell responsible for input/output, persistence, and network effects.&amp;#160;&lt;a href=&#34;#fnref:11&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;section class=&#34;footnotes link-notes&#34; role=&#34;doc-endnotes&#34;&gt;&lt;h2&gt;References&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;&lt;a href=&#34;https://gist.github.com/henrik/4509394&#34;&gt;https://gist.github.com/henrik/4509394&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://doi.org/10.1145/361598.361623&#34;&gt;https://doi.org/10.1145/361598.361623&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://web.stanford.edu/~ouster/cgi-bin/aposd.php&#34;&gt;https://web.stanford.edu/~ouster/cgi-bin/aposd.php&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://news.mit.edu/2026/margaret-hamilton-computing-pioneer-dies-1007&#34;&gt;https://news.mit.edu/2026/margaret-hamilton-computing-pioneer-dies-1007&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://github.com/chrislgarry/Apollo-11/blob/master/Luminary099/EXECUTIVE.agc&#34;&gt;https://github.com/chrislgarry/Apollo-11/blob/master/Luminary099/EXECUTIVE.agc&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://martinfowler.com/bliki/DataClump.html&#34;&gt;https://martinfowler.com/bliki/DataClump.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://martinfowler.com/bliki/FlagArgument.html&#34;&gt;https://martinfowler.com/bliki/FlagArgument.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://sandimetz.com/blog/2012/07/05/how-shall-we-define-design&#34;&gt;https://sandimetz.com/blog/2012/07/05/how-shall-we-define-design&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://github.com/chrislgarry/Apollo-11/blob/master/Luminary099/EXECUTIVE.agc&#34;&gt;https://github.com/chrislgarry/Apollo-11/blob/master/Luminary099/EXECUTIVE.agc&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://github.com/chrislgarry/Apollo-11/blob/master/Luminary099/EXECUTIVE.agc&#34;&gt;https://github.com/chrislgarry/Apollo-11/blob/master/Luminary099/EXECUTIVE.agc&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell&#34;&gt;https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/section&gt;</description>
    </item>
    
    <item>
      <title>Reviews worth the interruption</title>
      <link>https://version2beta.com/writing/reviews-worth-the-interruption/</link>
      <guid isPermaLink="true">https://version2beta.com/writing/reviews-worth-the-interruption/</guid>
      <pubDate>Thu, 17 Oct 2024 00:00:00 +0000</pubDate>
      <dc:creator>M. Robert Martin</dc:creator>
      <description>&lt;h2 id=&#34;the-interruption&#34;&gt;The interruption&lt;/h2&gt;
&lt;p&gt;A code review usually begins with a pull request and an interruption. Someone has to stop what they are doing, find enough context to understand the change, and follow the author&amp;rsquo;s logic. When the pull request leaves an important question unanswered, the conversation is necessarily asynchronous. By the time an answer arrives, both people may have to recover that context again.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s no surprise that we sometimes have difficulty finding someone to review our code.&lt;/p&gt;
&lt;p&gt;The author may have spent days working through the problem, considering alternatives, and deciding how to implement a change. The reviewer gets a diff. They have to work backward from the code to understand the problem, the decisions that were made, and whether the result makes sense.&lt;/p&gt;
&lt;p&gt;A review isn&amp;rsquo;t a favor we ask after the important work is finished. It&amp;rsquo;s part of the important work. We ask another person to look for problems we may not see, question decisions that worry them, and tell us whether the change fits the code around it.&lt;/p&gt;
&lt;p&gt;A good review happens in three stages. First, the author makes the change understandable and explains why it matters. Second, the reviewer examines the change in context and offers useful feedback. Finally, the author considers that feedback, reexamines their decisions, and improves the code where needed.&lt;/p&gt;
&lt;p&gt;We can make that work easier on the reviewer — and easier on ourselves.&lt;/p&gt;
&lt;h2 id=&#34;show-the-change&#34;&gt;Show the change&lt;/h2&gt;
&lt;p&gt;Small pull requests are usually easier to review. There&amp;rsquo;s less to read, less to remember, and less opportunity for unrelated changes to obscure the work. But small isn&amp;rsquo;t a measurement of a good pull request.&lt;/p&gt;
&lt;p&gt;A feature may require replacing a library and changing all the code that uses it. The resulting diff might be large, but it represents one decision. Splitting it into several pull requests just to make each one smaller can leave reviewers mentally reconstructing the complete change across multiple reviews.&lt;/p&gt;
&lt;p&gt;On the other hand, a library replacement that can be completed independently might be worth reviewing separately. Unrelated renames and formatting changes should probably stay out of the way. The question isn&amp;rsquo;t how many lines changed. It&amp;rsquo;s whether the reviewer can understand what changed and why.&lt;/p&gt;
&lt;p&gt;The description and the code have different jobs. The description explains the change; the code has to stand up to inspection. A good pull-request description gives the reviewer somewhere to start. What problem are we solving? What behavior should change? What should remain the same? Are there constraints or decisions that aren&amp;rsquo;t obvious from the code?&lt;/p&gt;
&lt;p&gt;Sometimes a written explanation isn&amp;rsquo;t enough, and we really want to walk a reviewer through the change. Show them the difficult parts, explain the alternatives you considered, and answer questions while you&amp;rsquo;re both looking at the code. Go synchronous. A short conversation can be more effective than exchanging comments over several hours, particularly when the reviewer needs context the diff doesn&amp;rsquo;t provide. We don&amp;rsquo;t need to turn every pull request into a meeting, either. We&amp;rsquo;re trying to make review easier, not fill everyone&amp;rsquo;s calendar.&lt;/p&gt;
&lt;h2 id=&#34;give-names-to-your-claims&#34;&gt;Give names to your claims&lt;/h2&gt;
&lt;p&gt;A descriptive name gives a reviewer a claim to examine.&lt;/p&gt;
&lt;p&gt;Consider a function named &lt;code&gt;is_authorized&lt;/code&gt;. That&amp;rsquo;s a useful name because it tells us what function the function performs. But does it actually check authorization, or merely whether someone is logged in? The name communicates intent. The reviewer will use the implementation to determine if that claim holds.&lt;/p&gt;
&lt;p&gt;Functions with one clear purpose help in the same way. We can examine what a function promises without having to understand several unrelated operations alongside it. Breaking a function into smaller pieces helps when the new boundaries make those promises clearer. More functions aren&amp;rsquo;t automatically better.&lt;/p&gt;
&lt;p&gt;Conventions are useful, too. An established pattern tells reviewers where to look for input validation, error handling, and changes to state. When code follows those conventions, reviewers can spend less time finding their way around. When it departs from them, the difference is easier to notice.&lt;/p&gt;
&lt;p&gt;Comments can preserve information that names and structure cannot: an external constraint, an unexpected behavior, or why an apparently simpler solution won&amp;rsquo;t work. A comment that merely describes the next line of code doesn&amp;rsquo;t tell the reviewer much. One that explains why the obvious implementation would be wrong might save everyone considerable trouble.&lt;/p&gt;
&lt;h2 id=&#34;answer-questions-before-theyre-asked&#34;&gt;Answer questions before they&amp;rsquo;re asked&lt;/h2&gt;
&lt;p&gt;Tests make pull requests easier to review when they show the behavior being changed. An acceptance test can show what a user is expected to be able to do. Tests for error conditions and edge cases can show what should happen when things don&amp;rsquo;t go according to plan.&lt;/p&gt;
&lt;p&gt;But tests aren&amp;rsquo;t certificates of correctness. A passing test can check the wrong expectation. Coverage can tell us which code ran without telling us whether the tests checked what matters. That&amp;rsquo;s part of the reviewer&amp;rsquo;s job: examine the claims made by the tests, not just whether they passed.&lt;/p&gt;
&lt;p&gt;What behavior changed? What happens when an input is missing or invalid? What happens when a dependency fails? Does the code do only what it&amp;rsquo;s authorized to do? Are we testing the intended behavior, or merely confirming what the implementation already does? Different changes deserve different questions. A change to a security boundary needs scrutiny that a renamed variable probably doesn&amp;rsquo;t. A new database operation raises questions about data integrity. A change to a busy service may need attention to performance, instrumentation, and behavior under load.&lt;/p&gt;
&lt;p&gt;We don&amp;rsquo;t need to ask every question of every pull request. We need to understand enough about the change to know which questions matter.&lt;/p&gt;
&lt;h2 id=&#34;the-next-review&#34;&gt;The next review&lt;/h2&gt;
&lt;p&gt;A review isn&amp;rsquo;t finished when the reviewer leaves a comment. The author still has to consider the feedback, address the problems it reveals, and ask questions when a concern isn&amp;rsquo;t clear. Reviewers have a responsibility here, too. An actionable comment should explain the concern well enough that the author can investigate it. It doesn&amp;rsquo;t always need to prescribe the solution.&lt;/p&gt;
&lt;p&gt;Sometimes the most useful review comment is a question that exposes an assumption neither person had noticed. We can all learn from the process. When the same questions come up in review after review, perhaps our code, conventions, tests, or pull-request descriptions aren&amp;rsquo;t communicating something they should.&lt;/p&gt;
&lt;p&gt;And reviewers remember. If your pull requests consistently make the work understandable, people learn what to expect. You may find it easier to get reviews, and your reviewers can spend more of their attention examining the change rather than figuring out what they&amp;rsquo;re looking at. That helps the next review, and the one after that. It also helps future you, who will eventually have to understand and maintain the code.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s easier to question a decision while a change is still under review than to discover its consequences in production. Good reviews are a pound of prevention. Cures aren&amp;rsquo;t sold anymore by the ounce.&lt;/p&gt;
&lt;p&gt;A code review cannot establish the quality of an entire system. But it can help us understand a change, examine evidence that it works, and find problems before they become production problems.&lt;/p&gt;
&lt;p&gt;We started by interrupting another person&amp;rsquo;s work. A good pull request and a thoughtful review can make that interruption worthwhile.&lt;/p&gt;
&lt;p&gt;If all else fails, use dark mode. Light attracts bugs.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
