<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://www.yegor256.com/rss.xml" rel="self" type="application/atom+xml" /><link href="https://www.yegor256.com/" rel="alternate" type="text/html" /><updated>2026-06-16T06:48:56+00:00</updated><id>https://www.yegor256.com/rss.xml</id><title type="html">Yegor Bugayenko</title><subtitle>Yegor Bugayenko</subtitle><author><name>Yegor Bugayenko</name><email>yegor256@gmail.com</email></author><entry><title type="html">Don’t Blame the Wheel for Missing a Turn</title><link href="https://www.yegor256.com/2026/06/01/dont-blame-the-wheel.html" rel="alternate" type="text/html" title="Don’t Blame the Wheel for Missing a Turn" /><published>2026-06-01T00:00:00+00:00</published><updated>2026-06-01T00:00:00+00:00</updated><id>https://www.yegor256.com/2026/06/01/dont-blame-the-wheel</id><content type="html" xml:base="https://www.yegor256.com/2026/06/01/dont-blame-the-wheel.html"><![CDATA[<p>Management gurus keep saying everyone must own the business result.
<a href="https://bcgbrighthouse.com/thinking/think-like-an-owner-part-ii-cultivating-an-ownership-mindset-at-scale/">BCG</a> wants every company to build an “ownership mindset” at all levels.
Each employee must feel responsible for the firm’s outcomes.
<a href="https://en.wikipedia.org/wiki/Patrick_Lencioni">Patrick Lencioni</a>, in <a href="https://en.wikipedia.org/wiki/The_Five_Dysfunctions_of_a_Team">The Five Dysfunctions of a Team</a>, calls
  “inattention to results” the worst sin a team can commit.
He wants us to give up our own goals for the shared number.
They want the bottom line to belong to all of us.
I disagree.</p>

<!--more-->

<figure class="jb_picture"><img itemprop="image" alt="Fanny and Alexander (1982) by Ingmar Bergman" src="/images/2026/06/fanny-and-alexander.jpg" longdesc="#2f4b8fc0" /><figcaption id="2f4b8fc0">Fanny and Alexander (1982) by Ingmar Bergman</figcaption></figure>

<p>Nothing burns like being judged for what you didn’t do.
<a href="https://classics.mit.edu/Aristotle/nicomachaen.3.iii.html">Aristotle</a> held that “on voluntary passions and actions praise and
  blame are bestowed, on those that are involuntary pardon, and sometimes also
  pity.”
Later thinkers, from <a href="https://en.wikipedia.org/wiki/Immanuel_Kant">Kant</a> to <a href="https://en.wikipedia.org/wiki/Thomas_Nagel">Thomas Nagel</a>, turned the same instinct into the
  <a href="https://plato.stanford.edu/entries/moral-luck/">control principle</a>: “we are morally assessable only to the extent that
  what we are assessed for depends on factors <em>under our control</em>.”
<a href="https://en.wikipedia.org/wiki/The_Theory_of_Moral_Sentiments">Adam Smith</a> agreed that reward belongs only to “actions of a beneficent
  tendency, which proceed from proper motives.”
Tie a person’s praise or blame to results their own work never caused, and the
  judgment stops being fair.</p>

<p><a href="https://en.wikipedia.org/wiki/Victor_Vroom">Victor Vroom</a>’s <a href="https://en.wikipedia.org/wiki/Expectancy_theory">expectancy theory</a> boils motivation down to a product:</p>

<blockquote>
  <p>Motivation = Expectancy × Instrumentality × Valence</p>
</blockquote>

<p>Expectancy is your belief that effort will lead to performance.
With no control over the outcome, it drops to zero.
Instrumentality is the link from that performance to the reward.
With no way to measure it, it drops to zero too.
Valence is how much you want that reward.
Even when it runs high, the three terms multiply, so one zero kills the
  whole product.</p>

<p>John Stacey Adams’s <a href="https://en.wikipedia.org/wiki/Equity_theory">equity theory</a> adds the next link: fairness.
Workers “seek to maintain equity between the inputs that
  they bring to a job and the
  outcomes that they receive.”
Those who feel short-changed “experience distress” and withdraw.</p>

<p>Yet most of us barely move the top line.
Our effect on it is indirect, and impossible to measure.</p>

<p><a href="https://deming.org/lessons-from-the-red-bead-experiment-with-dr-deming/">W. Edwards Deming</a> showed the first half with his red-bead experiment.
Workers drew from a box rigged with a fixed ratio of red beads, were praised and
  punished for the count, and could do nothing to change it.
“The performance of anybody, almost anybody,” he concluded, “is governed almost
  totally by the system he works in.”</p>

<p>The second half—you cannot measure one person’s share—is a basic result in
  the economics of the firm.
In their classic paper on <a href="https://www.jstor.org/stable/1815199">team production</a>, <a href="https://en.wikipedia.org/wiki/Armen_Alchian">Armen Alchian</a> and
  <a href="https://en.wikipedia.org/wiki/Harold_Demsetz">Harold Demsetz</a> put it plainly: “marginal products of cooperative team
  members are not so directly and separably (i.e., cheaply) observable,” and
  “what a team offers to the market can be taken as the marginal product of
  the team but not of the team members.”
Their fix was to measure each person’s input, not the team’s output.</p>

<p>So a company-size target, pinned on one person, does not pull.
It pushes the other way.</p>

<p>Even the goal-setting psychologists who love stretch targets admit the limit:
  <a href="https://www.frontiersin.org/journals/psychology/articles/10.3389/fpsyg.2018.01879/full">Höchli and colleagues</a> note that a superordinate goal “can be too
  abstract and disconnected from actual behavior” to guide anyone’s next move.</p>

<p>What happens next is no mystery; researchers have studied it for years.
Let people sense the judgment is rigged, and they react in ways
  industrial psychologists call counterproductive work behavior.
At best, they quietly sabotage.
At worst, they rebel.</p>

<aside class="quote">Don’t push people toward the metrics above them; instead, hide those metrics from them altogether
</aside>

<p><a href="https://doi.org/10.1037/0021-9010.82.3.434">Skarlicki and Folger</a> tracked 240 employees and found that a sense
  of injustice reliably predicts “organizational retaliation behavior”: the
  disgruntled striking back at the firm they believe wronged them.
<a href="https://doi.org/10.1037/0021-9010.75.5.561">Jerald Greenberg</a> showed how literal the damage can be.
When a company cut pay by 15% without a proper explanation, the workers who felt
  underpaid stole much more—the “hidden cost of pay cuts.”</p>

<p>The suggested fix: hold each person to their own work, and nothing more.
Don’t cascade the OKRs, don’t open the books,
  don’t parade the top-line number before everyone,
  as if visibility alone were motivation.
Don’t push people toward the metrics above them.
Instead, <em>hide</em> those metrics from them altogether.</p>

<p>Keep the higher numbers out of sight.
Nothing is left to feel manipulated by.
Only one thing stays in view: the worker’s own metric.
They can control it and measure it.
On that ground, motivation does not just survive.
It grows.</p>

<p>Yes, this defies the transparency gospel.
That defiance is exactly the point.</p>]]></content><author><name>Yegor Bugayenko</name><email>yegor256@gmail.com</email></author><category term="management" /><summary type="html"><![CDATA[Holding ordinary employees accountable for business-wide results they cannot control is unfair and demotivating.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.yegor256.com/images/2026/06/fanny-and-alexander.jpg" /><media:content medium="image" url="https://www.yegor256.com/images/2026/06/fanny-and-alexander.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Help the Agent to Feel</title><link href="https://www.yegor256.com/2026/05/29/help-the-agent.html" rel="alternate" type="text/html" title="Help the Agent to Feel" /><published>2026-05-29T00:00:00+00:00</published><updated>2026-05-29T00:00:00+00:00</updated><id>https://www.yegor256.com/2026/05/29/help-the-agent</id><content type="html" xml:base="https://www.yegor256.com/2026/05/29/help-the-agent.html"><![CDATA[<p>Since the <a href="https://www.anthropic.com/news/claude-opus-4-7">release of Opus 4.7</a> in April, I don’t write code by hand anymore.
I only talk to <a href="https://github.com/anthropics/claude-code">Claude Code</a>.
Not because I’m lazy or don’t like coding, but because he is a better programmer than I.
Also faster and much cheaper.
However, for most tasks I can’t let it fly solo in an “<a href="https://code.claude.com/docs/en/auto-mode-config">auto mode</a>.”
Because his standards are lower than I would expect even in a junior developer.
He is like <a href="https://en.wikipedia.org/wiki/Mowgli">Mowgli</a>: smart and strong, but rude and clumsy.
My job is to teach him elegance, my way.
And unlike with most developers, with him I can do this.</p>

<!--more-->

<figure class="jb_picture"><img itemprop="image" alt="Crocodile Dundee (1986) by Peter Faiman" src="/images/2026/05/crocodile-dundee.jpg" longdesc="#bf724596" /><figcaption id="bf724596">Crocodile Dundee (1986) by Peter Faiman</figcaption></figure>

<p>I know that he spent the first few months of his life in the wild.
Technically, in GitHub, StackOverflow, and software development blogs and books.
This is where he learned how others code, by looking at billions of lines of code.
Obviously, we can’t expect most of the lines to be pretty.
We can’t even expect them to be correct.</p>

<p>However, while correctness is a verifiable deterministic category, code prettiness is not.
It’s not only almost impossible to validate, but also hard to formulate.
Not only because it’s a matter of personal taste, but because it’s an <em>emotion</em>, not an algorithm.
You either feel it or you don’t.</p>

<p>Let me give you an example by sharing a list of what I’m particularly allergic to in programming:</p>

<ul>
  <li>The <a href="/2015/07/16/fools-dont-write-unit-tests.html">absence</a> of tests</li>
  <li>Knowledge duplication</li>
  <li><a href="/2018/07/03/global-variables.html">Global</a> state</li>
  <li><a href="/2014/06/09/objects-should-be-immutable.html">Mutable</a> object attributes</li>
  <li>Swallowed exceptions</li>
  <li><a href="/2014/05/13/why-null-is-bad.html">NULL references</a></li>
  <li>A class <a href="/2016/09/13/inheritance-is-procedural.html">inheriting</a> another class</li>
  <li>Type <a href="/2015/04/02/class-casting-is-anti-pattern.html">casting</a> or introspection</li>
  <li>Functions accepting 10+ arguments</li>
  <li>Objects encapsulating 10+ attributes</li>
  <li><a href="/2015/01/12/compound-name-is-code-smell.html">Compound</a> variable names</li>
  <li><a href="/2026/01/11/no-documentation-comments.html">Comments</a> in the code</li>
  <li>Emojis in documentation 😢</li>
</ul>

<p>This is a tiny part of what I can call source code <em>ugly</em> for.
I’m sure you agree with a few items, disagree with a few others, and don’t understand the rest.
Claude would react similarly if he saw this list.</p>

<p>Functionality goes first, aesthetics next.
We implicitly teach this principle in programming schools.
Claude learned it too by looking at those billions of lines.
If an algorithm doesn’t work, it doesn’t matter how pretty your code is.
This is his philosophy, and that of a million human programmers.</p>

<p>I believe in the opposite: aesthetics over functionality.
Simply because elegantly designed software is easier to fix
  than to make working software elegant.</p>

<aside class="quote">In software development I believe in aesthetics over functionality
</aside>

<p>By a lack of elegance I mean not only inconsistent indentation, though that’s an obvious sin.
I also mean lack of modularity, inadequate error handling, inconsistent naming,
  tight coupling, low cohesion, and high complexity.
If you read <a href="https://jttu.net/mcconnell2004code">Code Complete (2004)</a> and <a href="https://jttu.net/west2004object">Object Thinking (2004)</a>, you know what I’m talking about.
Software may be correct functionality-wise even if most of the principles are violated.
But it would be <em>ugly</em> software.
For me and maybe for some of you.
Not for Claude.</p>

<p>A billion Java programs taught him to see source code as an <em>intermediate byproduct</em>
  between user’s intent and the computer.
However, I prefer working with programmers
  who see source code as a piece of art, a product by itself.
I expect them to <em>feel</em> the beauty of the code they write.</p>

<p>It’s hard to find and recruit such people.
It’s even harder to convert a regular programmer who doesn’t care into an <em>aesthete</em>.
Unlike most people, Claude Code can be converted.</p>

<p>With the help of the carrot-and-stick method,
  <a href="/2016/09/27/command-control-innovate.html">as usual</a>.</p>

<p>The <em>carrot</em> is the <code class="language-plaintext highlighter-rouge">CLAUDE.md</code> file, the <a href="https://www.agenticmanifesto.org/">agentic manifesto</a>.
Here is mine, at <a href="https://github.com/yegor256/prompt">this repo</a>.
In the file I preach to Claude, trying to formulate what beauty means for me.
It’s hard, since I have to stay short in the system prompt.
That’s why I sound pretty abrupt, as you can see.</p>

<p>The <em>stick</em> is style checkers and static analyzers.
I used to have them for years in my repositories, but my arsenal was limited.
I was forced to use <a href="https://pmd.github.io">PMD</a>, <a href="https://checkstyle.org">Checkstyle</a>, <a href="https://rubocop.org">Rubocop</a>, <a href="https://pylint.readthedocs.io">Pylint</a>, and whatever else the market provided.
Making my own checkers was a complex task that I didn’t have the time or skills for.
Today, I can make my own checkers, because I have Claude.</p>

<p>Here is an example.
Recently I’ve launched a new version of <a href="https://www.qulice.com">Qulice</a>, a checker for Java code.
It extends PMD and Checkstyle with 59 additional checkers.
New checkers express my personal taste for Java code,
  which sometimes contradicts what the community believes is right.
Qulice is not a new project.
It’s 14 years old.
However, I was only recently able to implement all these additional checkers.
Because I didn’t have Claude for 14 years.</p>

<p>Yet another example.
I’ve been using Rubocop for more than 10 years.
An amazing style checker for Ruby code.
However, it lacks a few important rules that my personal taste demands.
A month ago I implemented <a href="https://github.com/yegor256/rubocop-elegant">an extension</a> for Rubocop.
Now I’m fully equipped.
Of course, Claude implemented it, not me.</p>

<p>A combination of both, the carrot (manifesto) and the stick (checkers) does the job.
The manifesto inspires Claude to do the right thing.
The checkers punish him for doing wrong things.
Of course, the checkers cover only the formalizable part of beauty.
Inconsistent indentation, a NULL reference, or a type cast—a tool can catch these.
Tight coupling, low cohesion, or clumsy error handling—no checker can feel them (so far!).
That heavier half stays on the manifesto.</p>

<p>When the manifesto is inspirational and the checkers are strong, Claude starts “feeling” me.
Well, at least that’s what it seems (or maybe it truly does feel me?!).
He appreciates my views and rarely writes anything that contradicts them.
When he does, the checkers punish him, and he <a href="https://github.com/thedotmack/claude-mem">remembers</a>.</p>

<p>I can’t imagine a human reacting the same way.
A few years ago I hired a guy who didn’t care much about code elegance.
However, he was good with algorithms and knew Java pretty well.
Apparently, he wasn’t ready to put aesthetics over functionality.
He quit in two weeks.</p>

<p>Claude doesn’t quit.
And he costs just $108 a month.</p>]]></content><author><name>Yegor Bugayenko</name><email>yegor256@gmail.com</email></author><category term="ai" /><category term="architect" /><summary type="html"><![CDATA[Claude Code programs better than me but with no taste, so I train it to feel my sense of code beauty through a CLAUDE.md manifesto and custom style checkers.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.yegor256.com/images/2026/05/crocodile-dundee.jpg" /><media:content medium="image" url="https://www.yegor256.com/images/2026/05/crocodile-dundee.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Monotonic Indentation</title><link href="https://www.yegor256.com/2026/05/24/monotonic-indentation.html" rel="alternate" type="text/html" title="Monotonic Indentation" /><published>2026-05-24T00:00:00+00:00</published><updated>2026-05-24T00:00:00+00:00</updated><id>https://www.yegor256.com/2026/05/24/monotonic-indentation</id><content type="html" xml:base="https://www.yegor256.com/2026/05/24/monotonic-indentation.html"><![CDATA[<p>People have been arguing about how to indent code for as long as there’s been code,
  and nobody has settled it.
Java’s <a href="https://checkstyle.org">Checkstyle</a> aligns continuations under the open paren,
  <a href="https://eslint.org">ESLint</a> and <a href="https://prettier.io">Prettier</a> each invent their own rules,
  Go’s <a href="https://pkg.go.dev/cmd/gofmt">gofmt</a> uses tabs and shrugs,
  <a href="https://rubocop.org">RuboCop</a> hands you a menu,
  Python’s <a href="https://peps.python.org/pep-0008/">PEP 8</a> picks four spaces and leaves the rest to taste.
Every tool has its own dialect, and teams waste hours fighting over the details.
I suggest a simple rule of <em>monotonic</em> indentation for source code of any programming language:</p>

<blockquote>
  <p>Between any two adjacent lines, indentation may increase by exactly one unit.</p>
</blockquote>

<p>This rule should resolve most disputes about code formatting style.
It is easy to add as an extra check to any existing style checker,
  or to deploy on its own as a small standalone tool.</p>

<!--more-->

<figure class="jb_picture"><img itemprop="image" alt="Покровские ворота (1983) by Михаил Козаков" src="/images/2026/05/pokrovskie-vorota.jpg" longdesc="#961f3dbf" /><figcaption id="961f3dbf">Покровские ворота (1983) by Михаил Козаков</figcaption></figure>

<p>According to the rule, this Java code is illegal:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Repository</span> <span class="o">{</span>
    <span class="kt">void</span> <span class="nf">save</span><span class="o">(</span><span class="nc">File</span> <span class="n">file</span><span class="o">,</span>
              <span class="nc">String</span> <span class="n">text</span><span class="o">,</span> <span class="nc">String</span> <span class="n">summary</span><span class="o">,</span>
              <span class="kt">boolean</span> <span class="n">overwrite</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">file</span><span class="o">.</span><span class="na">exists</span><span class="o">()</span>
                <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">overwrite</span><span class="o">)</span> <span class="o">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nf">IllegalStateException</span><span class="o">(</span>
                    <span class="s">"file already exists"</span><span class="o">);</span>
        <span class="o">}</span>
        <span class="n">update</span><span class="o">(</span><span class="n">file</span><span class="o">,</span>
               <span class="n">text</span><span class="o">,</span>
               <span class="n">summary</span><span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>This one is legal (and pretty, if you ask me):</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code>class Repository {
<span class="tab">→→</span>void save(File file,
  <span class="tab">→→</span>String text, String summary,
    boolean overwrite) {
    if (file.exists()
    <span class="tab">→→</span>&amp;&amp; !overwrite) {
      throw new IllegalStateException(
      <span class="tab">→→</span>"file already exists");
    }
    update(file,
    <span class="tab">→→</span>text,
      summary);
  }
}
</code></pre></div></div>

<p>The idea is simple: going down the code, you may step right by one notch at a time,
  but you may jump back left by as many notches as you want.
You can’t skip steps on the way in, but you can leap out freely.
Every line still lands on a grid, never in between.</p>

<p>Together with the <a href="/2014/10/23/paired-brackets-notation.html">Paired Brackets</a> rule,
  this makes the code look ideal:
  brackets line up vertically and indentation never jumps further than necessary.</p>

<p>BTW, the parser of <a href="https://www.eolang.org">EO</a>, our experimental language, enforces this rule syntactically.
This is similar to the <a href="https://en.wikipedia.org/wiki/Off-side_rule">off-side rule</a> of Python,
  where indentation defines block structure rather than braces.
However, in EO everything is an object, while in Python it is not.
That’s why EO can afford to be stricter and demand monotonic steps everywhere.</p>]]></content><author><name>Yegor Bugayenko</name><email>yegor256@gmail.com</email></author><category term="style" /><summary type="html"><![CDATA[Between two adjacent lines, indentation may grow by one unit only, but may shrink by any number of units — a rule that resolves most code formatting disputes.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.yegor256.com/images/2026/05/pokrovskie-vorota.jpg" /><media:content medium="image" url="https://www.yegor256.com/images/2026/05/pokrovskie-vorota.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Couriers, Not Coders</title><link href="https://www.yegor256.com/2026/05/03/no-mercy.html" rel="alternate" type="text/html" title="Couriers, Not Coders" /><published>2026-05-03T00:00:00+00:00</published><updated>2026-05-03T00:00:00+00:00</updated><id>https://www.yegor256.com/2026/05/03/no-mercy</id><content type="html" xml:base="https://www.yegor256.com/2026/05/03/no-mercy.html"><![CDATA[<p>Someone submitted an issue to one of our open GitHub repositories a week ago,
  suggesting a new feature.
We didn’t respond, since we
  <a href="/2024/04/01/ping-me-please.html">didn’t notice it</a>.
Today, someone else submitted an implementation of the feature in a pull request.
I rejected it and explained that the feature request must first be
  accepted by the
  <a href="/2014/10/12/who-is-software-architect.html">project architect</a>,
  and only then would it be worth
  making a pull request.
The author of the PR got offended.
He won’t be back.
Good.
A year ago, we would have been sad to lose an
  <a href="/2019/01/01/hazardous-enthusiasm.html">enthusiastic</a> contributor.
Today, we don’t care.</p>

<!--more-->

<figure class="jb_picture"><img itemprop="image" alt="Cruel Intentions (1999) by Roger Kumble" src="/images/2026/05/cruel-intentions.jpg" longdesc="#73b21b12" /><figcaption id="73b21b12">Cruel Intentions (1999) by Roger Kumble</figcaption></figure>

<p>For years you sold coding skill at $50 an hour.
AI now codes for cents.
But you still want $50.</p>

<p>We are still ready to pay.
Not for the code—the code is free.
For the <em>delivery</em>.</p>

<p>You take what <a href="https://github.com/anthropics/claude-code">Claude Code</a> wrote and you walk it to our door.
You are the <em>courier</em>, not the coder.</p>

<p>The margin is what we pay for trust:
  that what you deliver, we can merge without re-checking.
So the delivery must be flawless.</p>

<aside class="quote">We pay for the delivery, not the code
</aside>

<p>A PR without a description is a package with no label—refused.
An unfocused PR is two parcels in one box—refused.
A PR too large to read is an oversized package—refused.
A PR sitting in review for weeks is a delivery that never arrived—refused.
A PR for an unapproved feature is a parcel for an address we never accepted—refused.</p>

<p>What we forgave yesterday, when we still needed the code, we no longer forgive.
The market for couriers is huge.
We can afford to choose.
So the bar rises, not falls.</p>

<p>Working code is now the minimum.
We expect discipline, speed of delivery, clear and detailed communication,
  and readiness to re-work.
Above all, we expect you to understand our
  <a href="/2015/10/13/competition-without-rules.html">rules</a>
  and <em>obey</em> them.</p>

<p>No mercy for mess.
Not anymore.</p>

<p>If you want the wage, earn the margin.</p>

<p>Be proud of the delivery, not the code.</p>]]></content><author><name>Yegor Bugayenko</name><email>yegor256@gmail.com</email></author><category term="management" /><summary type="html"><![CDATA[Now that AI codes for cents, contributors are paid for the delivery, not the code—so no mercy for sloppy pull requests anymore.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.yegor256.com/images/2026/05/cruel-intentions.jpg" /><media:content medium="image" url="https://www.yegor256.com/images/2026/05/cruel-intentions.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Fast Software: More Programmers, Not Fewer</title><link href="https://www.yegor256.com/2026/03/05/fast-software.html" rel="alternate" type="text/html" title="Fast Software: More Programmers, Not Fewer" /><published>2026-03-05T00:00:00+00:00</published><updated>2026-03-05T00:00:00+00:00</updated><id>https://www.yegor256.com/2026/03/05/fast-software</id><content type="html" xml:base="https://www.yegor256.com/2026/03/05/fast-software.html"><![CDATA[<p>When I was five years old, I inherited the shoes of my older brother.
Not because our family was poor, but because the shoes were good.
My grandma told me that when she was a fiancée her dowry consisted of a few skirts.
Not because she was poor.
She wasn’t.
Because the skirts were good and rather expensive.
Now, in 2026, to get a new pair of shoes or a new skirt, I just buy them at a mall down the street.
I don’t hesitate to throw away the old ones.
The same will happen with the software, thanks to AI coding agents.</p>

<!--more-->

<figure class="jb_picture"><img itemprop="image" alt="25th Hour (2002) by Spike Lee" src="/images/2026/03/25th-hour.jpg" longdesc="#5ab67d51" /><figcaption id="5ab67d51">25th Hour (2002) by Spike Lee</figcaption></figure>

<p>A few days ago someone (I lost the link) shared a funny story on LinkedIn.
He showed a message from his former boss.
The boss was asking for a fix to software written twenty years ago.
The author of the story proudly claimed that some software, if written properly, can <em>survive</em> a generation.</p>

<p>The software in the story is similar to the skirt of my grandma.
It was made to survive a few decades.
Because it was <em>expensive to make</em>.</p>

<p>That’s why the boss is not hiring a new programmer to re-write the software.
He asks for a fix.
Just like my grandma would not throw away a skirt if it got a hole.
It would go to a tailor to get a patch.</p>

<p>Many of us wonder what may happen when AI agents, like <a href="https://code.claude.com/">Claude Code</a>, dominate the market.
Programmers, especially junior ones, may be fired en masse.
Look at what Jack Dorsey <a href="https://x.com/jack/status/2027129697092731343">just did</a>: terminating contracts of about 40% of his tech staff.</p>

<p>Large companies indeed will fire programmers, but not because the new world doesn’t need human coders.
It’s because the new world doesn’t need <em>large</em> software companies.</p>

<aside class="quote">We’ll toss our software, not update it
</aside>

<p>What the world is looking forward to is a <em>devaluation</em> of software craftsmanship.
Just like a skirt is no longer valuable, except for some high-end brands, software won’t be either.
Developing a new ERP system would cost a few thousand dollars and take a few days of work.
Just like it <a href="https://x.com/mntruell/status/2011562190286045552">recently took a week</a> to create a new web browser.</p>

<p>Oracle, Adobe, Microsoft, and JetBrains will run out of business.</p>

<p>When someone needs an IDE with new language support, they won’t wait for JetBrains to release it next year, maybe.
They will go to a software shop around the corner, pay a few hundred bucks, and get it next Monday.
When someone needs a new feature in Photoshop, they won’t wait for Adobe.
They will <em>buy a new</em> Photoshop from a friend, with the feature and maybe a few more.
When a company needs their accounting system to support a new logistics optimization scheme, they won’t go to Oracle.
They will <em>re-write</em> the entire Oracle Fusion, for a few thousand dollars.</p>

<p>We won’t wait for new releases of the old software we love.
We’ll toss them away and buy new ones.</p>

<p>The market will need more programmers, not fewer.
In order to sew good skirts for all women, a city may need a few dozen tailors.
Because every skirt costs a lot and is worn for decades.
In order to manufacture throw-away one-time skirts, the same city needs many more people.
Obviously, these new people are not the tailors of the good-old-days quality.
But they make many skirts, thousands per day.</p>

<p>Just like fast fashion replaced tailors with factory workers and machine operators, <strong>fast software</strong> will replace programmers with AI operators.
And the market will demand many of them.
Many more than large software companies employ today.</p>

<p>Large companies will lose their <em>monopoly on complexity</em>.
A small software shop will be able to build a new IDE, a new Photoshop, or even a new Linux.
For a few thousand dollars.</p>

<p>The importance of open source software will <a href="/2020/05/05/open-source-arms-race.html">continue to grow</a>.
It will become the primary provider of ingredients for AI and its operators.</p>

<p>The new world will need more programmers (AI operators) than it needs now.
Because the demand for custom software will soon start growing.
Everyone will want their own Photoshop.
Every developer will want their own IDE and their own Linux.
And they will throw them away without hesitation.
Just like I throw away my shoes every year and get new ones.</p>]]></content><author><name>Yegor Bugayenko</name><email>yegor256@gmail.com</email></author><category term="mood" /><summary type="html"><![CDATA[AI coding agents will make software disposable, like fast fashion replaced tailored clothing, creating demand for more programmers, not fewer.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.yegor256.com/images/2026/03/25th-hour.jpg" /><media:content medium="image" url="https://www.yegor256.com/images/2026/03/25th-hour.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">SPAs Are a Performance Dead End</title><link href="https://www.yegor256.com/2026/01/25/spa-vs-performance.html" rel="alternate" type="text/html" title="SPAs Are a Performance Dead End" /><published>2026-01-25T00:00:00+00:00</published><updated>2026-01-25T00:00:00+00:00</updated><id>https://www.yegor256.com/2026/01/25/spa-vs-performance</id><content type="html" xml:base="https://www.yegor256.com/2026/01/25/spa-vs-performance.html"><![CDATA[<p>It seems to be <a href="https://adamsilver.io/blog/the-problem-with-single-page-applications/">popular</a> to design websites as Single Page Applications (SPA).
Instead of showing a new HTML page on every click, an SPA sends a lightweight skeleton with JavaScript.
The JS makes HTTP requests, receives JSON, and injects data into the DOM.
On each user action, the page doesn’t reload—only the DOM changes.
Such an architecture, once a response to slow browsers and unreliable networks, is now a <a href="https://www.matuzo.at/blog/2023/single-page-applications-criticism/">bottleneck</a>.
The page is built of fragments, each requiring its own HTTP request.
No matter how fast each request is, the multiplication diminishes all optimization efforts.</p>

<!--more-->

<figure class="jb_picture"><img itemprop="image" alt="Bitter Moon (1992) by Roman Polanski" src="/images/2026/01/bitter-moon.jpg" longdesc="#5f60766e" /><figcaption id="5f60766e">Bitter Moon (1992) by Roman Polanski</figcaption></figure>

<p>In 2000, <a href="https://en.wikipedia.org/wiki/Roy_Fielding">Roy Fielding</a>, the author of <a href="https://en.wikipedia.org/wiki/REST">REST</a> and co-author of <a href="https://en.wikipedia.org/wiki/HTTP">HTTP</a>, described the Web in his <a href="https://roy.gbiv.com/pubs/dissertation/fielding_dissertation.pdf">dissertation</a>:</p>

<blockquote>
  <p>A network of web pages, where the user progresses through the application
by selecting links, resulting in the next page being transferred
to the user and rendered for their use.</p>
</blockquote>

<p>Simply put, each action leads to an HTML page reload.</p>

<p>In 1999, Microsoft introduced <a href="https://en.wikipedia.org/wiki/XMLHttpRequest">XMLHttpRequest</a> for <a href="https://en.wikipedia.org/wiki/Outlook_on_the_web">Outlook Web Access</a>, enabling background HTTP requests.
In 2005, <a href="https://en.wikipedia.org/wiki/Jesse_James_Garrett">Jesse James Garrett</a> coined the term <a href="https://en.wikipedia.org/wiki/Ajax_(programming)">AJAX</a> in his essay “<a href="https://designftw.mit.edu/lectures/apis/ajax_adaptive_path.pdf">Ajax: A New Approach to Web Applications</a>.”
This came in handy when full page reloads stopped working well:</p>

<ul>
  <li>Browsers were slow</li>
  <li>Networks were unreliable</li>
  <li>Full page reloads felt wasteful</li>
  <li>Users expected “desktop-like” interactivity</li>
</ul>

<p><em>AJAX</em> paved the way for the <a href="https://en.wikipedia.org/wiki/Single-page_application">SPA</a>: instead of HTML, the server sends <a href="https://en.wikipedia.org/wiki/JSON">JSON</a>, and the browser reconstructs the page locally.
Then came the frameworks: <a href="https://angular.io/">Angular</a> (2010), <a href="https://react.dev/">React</a> (2013), <a href="https://vuejs.org/">Vue</a> (2014).
Each formalizes the same idea: the browser hosts the application, the server delivers data.</p>

<p>Imagine a simple online calculator where a user enters “2+3,” clicks “Submit,” and sees the result right next to the input field.
No page reload.
The <a href="https://en.wikipedia.org/wiki/Document_Object_Model">DOM</a> remains the same.
The JS inside the browser changes only the result of calculation, in a single <code class="language-plaintext highlighter-rouge">&lt;div/&gt;</code>.</p>

<p>The primary justification for this architecture is <em>performance</em>.
If servers are slow, rendering a full HTML page takes longer than just a JSON with the result of calculation.
If the network is unreliable, re-delivering the entire HTML takes longer than just a small JSON document.
Also, if browsers are slow, making a tiny change in the DOM works faster than a full page reload.</p>

<p>This is true, for a trivial example.
However, when an SPA gets larger, the frontend has to make <em>dozens of round-trips</em> to the backend.
Look at what Facebook and LinkedIn are doing while rendering your home page.
A rather simple UI with just a list of recent posts gets filled up by multiple pieces, each leading to its own HTTP request,
  sometimes taking more than a few seconds to complete rendering a page.
Their UX sucks, if you ask me.</p>

<p>Their architects are stupid?
Nope.</p>

<p>The very idea of SPA is flawed.
The architects of Facebook and LinkedIn are the hostages of it.
They can’t make their websites run faster, because they, by design, are built of fragments retrievable from the backend.
They must make <em>multiple</em> HTTP round-trips.</p>

<p>The performance penalty of SPAs is structural, not accidental.
Even if HTTP/2 <a href="https://stackoverflow.com/questions/36835972/is-the-per-host-connection-limit-raised-with-http-2/36847527#36847527">multiplexes</a> requests, the UI still waits for JSON to arrive in order—classic
  <a href="https://en.wikipedia.org/wiki/Head-of-line_blocking">head-of-line blocking</a> at the application layer.
Worse, one request often reveals permissions, feature flags, or entity identifiers needed for the next, turning parallel calls into a waterfall.
Caching doesn’t help either: dozens of endpoints, each with its own TTL, rarely produce a full cache hit,
  and partial hits still force the browser to assemble and reconcile the page at runtime
Meanwhile, the browser must juggle layout stabilization, loading indicators, and partial failures—all before meaningful content becomes visible.</p>

<p>What was once a solution for small DOM updates, in an era of slow browsers and unreliable networks, has turned into a dead-end for web design.</p>

<aside class="quote">State belongs on the server while HTML is the primary delivery artifact, not JSON
</aside>

<p>Most web architects simply can’t make their websites as fast as <a href="https://stackoverflow.com/">Stack Overflow</a>, which is not an SPA.
It delivers the entire HTML page, <a href="https://scaleyourapp.com/svelte-at-stack-overflow/">rendered</a> on the server using <a href="https://en.wikipedia.org/wiki/ASP.NET_Razor">Razor</a>, in one <a href="https://highscalability.com/stackoverflow-update-560m-pageviews-a-month-25-servers-and-i/">&lt;50ms</a> request.
It does use client-side JS components selectively, but these are isolated and don’t negate the central role of server HTML for the initial experience.
Their UX is one of the best on the modern web, if you ask me.</p>

<p>Rendering a full page on the server may still be a slow operation.
It may, and it often will.
However, this problem is <em>solvable</em>, for example, with the help of caching.
The server is in charge of the data and the state of navigation, making caching possible.</p>

<p>Literally every large, content-heavy, consumer-facing SPA I can think of is horrible in terms of UX.
Even <a href="https://gmail.com">Gmail</a> is not an exception.
Their UX would be noticeably better if they followed the principles of Roy Fielding and reloaded the page every time an email is opened.
I’m not kidding.</p>]]></content><author><name>Yegor Bugayenko</name><email>yegor256@gmail.com</email></author><category term="mood" /><summary type="html"><![CDATA[Single Page Applications, once a solution for slow browsers, are now a performance bottleneck due to multiple HTTP round-trips.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.yegor256.com/images/2026/01/bitter-moon.jpg" /><media:content medium="image" url="https://www.yegor256.com/images/2026/01/bitter-moon.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Comments Considered Harmful in the Age of LLMs</title><link href="https://www.yegor256.com/2026/01/11/no-documentation-comments.html" rel="alternate" type="text/html" title="Comments Considered Harmful in the Age of LLMs" /><published>2026-01-11T00:00:00+00:00</published><updated>2026-01-11T00:00:00+00:00</updated><id>https://www.yegor256.com/2026/01/11/no-documentation-comments</id><content type="html" xml:base="https://www.yegor256.com/2026/01/11/no-documentation-comments.html"><![CDATA[<p>Writing code documentation is a pain.
Not writing it leads to even bigger pain—we can’t comprehend the code.
However, writing it and then forgetting to update it causes the ultimate pain: it lies and confuses us.
How about we cure all three pains at once: <em>prohibit all comments!</em>
How do we know what the intent of the code is if we don’t have any comments?
We ask an LLM to explain it to us.
What if the LLM fails to explain and confesses its inability?
Then, we automatically fail the build and blame the author of the code.
Thus, we introduce a new quality gate: <em>Code Interpretability Score</em>.
The build passes only if this score is high enough.</p>

<!--more-->

<figure class="jb_picture"><img itemprop="image" alt="Full Metal Jacket (1987) by Stanley Kubrick" src="/images/2026/01/full-metal-jacket.jpg" longdesc="#dc7c81cb" /><figcaption id="dc7c81cb">Full Metal Jacket (1987) by Stanley Kubrick</figcaption></figure>

<p>The best minds in software engineering have long dreamed of self-documenting code.
In 1974, <a href="https://en.wikipedia.org/wiki/Brian_W._Kernighan">Brian Kernighan</a> and <a href="https://en.wikipedia.org/wiki/P._J._Plauger">Phillip James Plauger</a> <a href="https://en.wikipedia.org/wiki/The_Elements_of_Programming_Style">said</a> that
  “the only reliable documentation of a computer program is the code itself.”
In 2004, <a href="https://en.wikipedia.org/wiki/Steve_McConnell">Steven McConnell</a> in <a href="https://amzn.to/2cs4cXW"><em>Code Complete</em></a> claimed that
  “the main contributor to code-level documentation isn’t comments, but good programming style.”
In 2008, <a href="https://en.wikipedia.org/wiki/Robert_C._Martin">Robert Martin</a> in <a href="https://amzn.to/2m7LmaA"><em>Clean Code</em></a> suggested that
  “if our programming languages were expressive enough, or if we had the talent to subtly wield those languages to express our intent,
  we would not need comments very much—perhaps not at all.”
They all wanted the same thing: code that explains itself.
They just lacked the tools to enforce it.</p>

<p>Why do we write comments at all?
A Java method of a hundred lines may take hours to understand.
A tiny Javadoc block saves this time:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
 * Recursively finds the shortest
 * path between two nodes in the graph.
 */</span>
<span class="kt">int</span><span class="o">[]</span> <span class="nf">shortest</span><span class="o">(</span><span class="kt">int</span><span class="o">[][]</span> <span class="n">g</span><span class="o">,</span> <span class="kt">int</span> <span class="n">a</span><span class="o">,</span> <span class="kt">int</span> <span class="n">b</span><span class="o">)</span> <span class="o">{</span>
  <span class="c1">// A hundred lines of code go</span>
  <span class="c1">// here, which we have no desire</span>
  <span class="c1">// to read and understand.</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Comments promise to help us but fail in two distinct ways.</p>

<p>First, they are <em>unclear</em>.
<a href="https://en.wikipedia.org/wiki/David_Parnas">David Parnas</a> once <a href="https://doi.org/10.1109/icse.1994.296790">said</a> that
  “documentation that seems clear and adequate to its authors is often about <em>as clear as mud</em> to the
  programmer who must maintain the code six months or six years later.”
What the author considers obvious, the reader finds cryptic.</p>

<p>Second, they <em>decay</em>.
Being static metadata, comments do not evolve automatically with the code.
If the implementation of the <code class="language-plaintext highlighter-rouge">shortest()</code> function stops being recursive, we may forget to update the Javadoc block.
Such negligence leads to <em>hallucinating documentation</em> that causes bugs, broken trust, and wasted debugging time.
In 1999, <a href="https://en.wikipedia.org/wiki/Andy_Hunt_(author)">Andrew Hunt</a> and <a href="https://en.wikipedia.org/wiki/Dave_Thomas_(programmer)">Dave Thomas</a> in <a href="https://en.wikipedia.org/wiki/The_Pragmatic_Programmer"><em>The Pragmatic Programmer</em></a> warned that
  “<em>untrustworthy</em> comments are <em>worse</em> than no comments at all.”
A recent <a href="https://doi.org/10.1145/3663529.3664458">analysis</a> of 13 open source projects
  demonstrated that out-of-date comments are not rare but common.</p>

<p>Now we have a tool that solves both problems: the LLM.</p>

<p>Instead of writing the Javadoc block manually, we let the IDE generate it on-demand.
The LLM reads the hundred lines of code, comprehends it, and summarizes the intent in a single English sentence.
Modern models accomplish this task better than most humans.
The documentation is always fresh because it is generated from the current code, not from a stale comment written months ago.</p>

<p>But we can go further.
We can integrate an LLM into the build pipeline and ask it to assess the <em>Code Interpretability Score</em> (CIS) of every function.
If the model has low confidence in explaining the logic, this signals that the code is too clever or convoluted.
The compiler can enforce a threshold: if the CIS is too low, the build fails.
This transforms readability from a subjective preference into an objective, measurable quality gate.</p>

<p>Once this gate exists, manual comments become not just unnecessary but <em>harmful</em>.
They introduce a second source of truth that can contradict the code.
The logical conclusion: prohibit them entirely.
This forces developers to write clean, structured logic that is inherently machine-interpretable.</p>

<p>Robert Martin wished for more expressive languages.
He didn’t know about LLMs.
Today, we don’t need better languages—we need an LLM that can interpret any language.
If the LLM can’t explain the code, we blame the programmer and stop the build.</p>

<hr />

<p>We are thinking about making <a href="https://www.eolang.org">EO</a>, our experimental object-oriented language, this restrictive.</p>]]></content><author><name>Yegor Bugayenko</name><email>yegor256@gmail.com</email></author><category term="quality" /><summary type="html"><![CDATA[Instead of writing code comments that decay and mislead, let LLMs generate documentation on-demand and fail the build when code is too obscure for them to explain.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.yegor256.com/images/2026/01/full-metal-jacket.jpg" /><media:content medium="image" url="https://www.yegor256.com/images/2026/01/full-metal-jacket.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">The Fall of JavaScript</title><link href="https://www.yegor256.com/2025/12/28/fall-of-javascript.html" rel="alternate" type="text/html" title="The Fall of JavaScript" /><published>2025-12-28T00:00:00+00:00</published><updated>2025-12-28T00:00:00+00:00</updated><id>https://www.yegor256.com/2025/12/28/fall-of-javascript</id><content type="html" xml:base="https://www.yegor256.com/2025/12/28/fall-of-javascript.html"><![CDATA[<p>In 1995, <a href="https://github.com/BrendanEich">Brendan Eich</a> was hired by <a href="https://en.wikipedia.org/wiki/Netscape">Netscape</a> and asked to create a language for their HTML browser.
Rumors say, he designed Mocha in <a href="https://exploringjs.com/es5/ch04.html">10 days</a>, later renamed to <a href="https://stackoverflow.com/questions/2018731">LiveScript</a>, and then to <a href="https://en.wikipedia.org/wiki/JavaScript">JavaScript</a>.
It was <a href="https://brendaneich.com/2008/04/popularity/">planned</a> to make it similar to <a href="https://www.scheme.org/">Scheme</a>, a LISP-syntax language.
Instead, to <a href="https://brendaneich.com/2008/04/popularity/">please</a> the crowd of C++/Java coders, it was made syntactically similar to Java.
In 2008, Brendan made a tragic mistake: he <a href="https://www.theguardian.com/technology/2014/apr/02/controversial-mozilla-ceo-made-donations-right-wing-candidates-brendan-eich">donated</a> $1,000 in support of Californian anti-gay marriage <a href="https://en.wikipedia.org/wiki/2008_California_Proposition_8">law</a>.
In 2014, he joined <a href="https://www.mozilla.org/">Mozilla</a> as a CEO and the crowd <a href="https://www.cbc.ca/news/science/okcupid-protests-new-mozilla-ceo-s-anti-gay-marriage-donation-1.2593629">remembered</a> his anti-diversity gesture.
He had to <a href="https://blog.mozilla.org/en/mozilla/brendan-eich-steps-down-as-mozilla-ceo/">step down</a> and founded Brave Software, the developer of the <a href="https://brave.com/">Brave</a> browser.
Somewhere around that time they started to kill JavaScript.
Still doing it pretty good, thanks to recent <a href="https://en.wikipedia.org/wiki/ECMAScript">ECMAScript</a> updates and <a href="https://www.typescriptlang.org/">TypeScript</a>.</p>

<!--more-->

<figure class="jb_picture"><img itemprop="image" alt="Platoon (1986) by Oliver Stone" src="/images/2025/12/platoon.jpg" longdesc="#aeacd232" /><figcaption id="aeacd232">Platoon (1986) by Oliver Stone</figcaption></figure>

<p>In the JavaScript created 30 years ago, objects were primitive associative arrays of properties.
Either data, a function, or another object may be attached to a property of an object.
Let’s see what Brendan <a href="https://brendaneich.com/2008/04/popularity/">said</a> about JS in 2008:</p>

<blockquote>
  <p>I’m happy that I chose Scheme-ish first-class functions and Self-ish prototypes as the main ingredients.</p>
</blockquote>

<p>First-class functions mean that it’s possible to use a function as a value assignable to a variable.
And then he <a href="https://brendaneich.com/2008/04/popularity/">concluded</a> (pay attention, it’s C not C++):</p>

<blockquote>
  <p>Yet many curse it, including me. I still think of it as a quickie love-child of C and Self.</p>
</blockquote>

<p><a href="https://selflanguage.org/">Self</a>, which he refers to a few times, is a prototype-based object-oriented language
  designed by <a href="https://en.wikipedia.org/wiki/David_Ungar">David Ungar</a> and <a href="https://www.linkedin.com/in/randallsmith1/">Randall Smith</a> in <a href="https://en.wikipedia.org/wiki/PARC_(company)">Xerox PARC</a>, then <a href="https://www.stanford.edu/">Stanford University</a>, and then <a href="https://en.wikipedia.org/wiki/Sun_Microsystems">Sun Microsystems</a>.
Self doesn’t have classes, unlike Java or C++.
Instead, it only has objects.
To create a new object in Self we make a copy of an existing object, known as prototype, and then modify some of its slots (attributes).</p>

<p>In Self, objects don’t have types: all method calls are dispatched in runtime.
For example, we ask a book to rename itself:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>book rename: "Object Thinking".
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">rename</code> is the method of the <code class="language-plaintext highlighter-rouge">book</code> that we call with a single string argument.
The computer doesn’t know anything about the <code class="language-plaintext highlighter-rouge">book</code> until it’s time to call the <code class="language-plaintext highlighter-rouge">rename</code> method.
Obviously, such a <a href="https://en.wikipedia.org/wiki/Duck_typing">duck typing</a> has its performance drawback.
Every <code class="language-plaintext highlighter-rouge">rename</code> leads to a search in a <a href="https://en.wikipedia.org/wiki/Dispatch_table">virtual table</a> of <code class="language-plaintext highlighter-rouge">book</code>.
To the contrary, C++, where types are known in compile time, can dispatch <code class="language-plaintext highlighter-rouge">rename()</code> instantly:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Book b;
b.rename("Object Thinking");
</code></pre></div></div>

<p>Types (classes in C++ and interfaces in Java) and <a href="/2025/08/17/type-annotations.html">type annotations</a> are helpful—to the compiler.
To us humans they are a burden.
They require us to do the work of the compiler.
We have to pollute our code with messages like: “This object <code class="language-plaintext highlighter-rouge">b</code> is of type <code class="language-plaintext highlighter-rouge">Book</code>, please remember.”
The compiler must be smart enough to understand it without our hints.</p>

<p>This is a debatable topic though.
Some believe that type annotations help programmers better understand the code and make fewer mistakes.
I’m also in favor of fewer mistakes, but would rather expect the compiler to infer types automatically, without my annotations.
If I do <code class="language-plaintext highlighter-rouge">b.rename()</code> and <code class="language-plaintext highlighter-rouge">b</code> is known to be a car instead of a book, I would expect the compiler to figure this out on its own and refuse to compile.</p>

<p>Anyway, JavaScript was designed as a prototype-based dynamically typed language with a minimalistic syntax that resembles Java.
It worked perfectly fine until the industry decided to “fix” it.</p>

<aside class="quote">JavaScript worked perfectly fine until the industry decided to fix it
</aside>

<p>In 2008, <a href="https://www.mozilla.org/">Mozilla</a> and others <a href="https://auth0.com/blog/the-real-story-behind-es4/">proposed</a> ECMAScript 4, which included classes, modules, and other features.
<a href="https://www.microsoft.com/">Microsoft</a> took an <a href="https://www.theregister.com/2008/08/15/adobe_microsoft_ecma_javascript/">extreme position</a>, refusing to accept any part of ES4.
Chris Wilson, Microsoft’s Internet Explorer platform architect, <a href="https://www.theregister.com/2008/08/15/adobe_microsoft_ecma_javascript/">criticized</a> ES4 for trying to introduce too many changes.
Brendan Eich <a href="https://www.theregister.com/2008/08/15/adobe_microsoft_ecma_javascript/">accused</a> Wilson of spreading falsehoods and playing political games.
ES4 was <a href="https://auth0.com/blog/the-real-story-behind-es4/">abandoned</a>, and classes were dropped.</p>

<p>Then, in 2012, Microsoft created <a href="https://www.typescriptlang.org/">TypeScript</a>, a JavaScript with type annotations and classes.
Since classes weren’t in the standard, Microsoft made their own.</p>

<p>Finally, in 2015, <a href="https://262.ecma-international.org/6.0/">ECMAScript 6</a> added classes (among other features) to the JavaScript specification.
Many ES4 features, including classes, were <a href="https://auth0.com/blog/the-real-story-behind-es4/">revived</a> in a “maximally minimal” form.
The crowd of Java/C++ developers got what they wanted.</p>

<p>Let’s hear what <a href="https://www.crockford.com/pronto.html">Douglas Crockford</a>, the creator of <a href="https://en.wikipedia.org/wiki/JSON">JSON</a> and <a href="https://github.com/jslint-org/jslint">JSLint</a>, <a href="https://www.youtube.com/watch?v=PSGEjv3Tqo0&amp;t=360s">said</a> in 2014:</p>

<blockquote>
  <p>Class-free programming is JavaScript’s contribution to humanity.</p>
</blockquote>

<p>Unfortunately, not anymore.
It looks like the developers of recent versions of JS believe in something else.
Or maybe they don’t want to make a contribution to humanity anymore.
Maybe they just want to make the crowd happy.</p>

<p>Type annotations and classes don’t match with the concept of class-free object-based programming of JavaScript.
They came from Java or C++ but don’t fit in.
Some programmers may find them helpful, but only because they are used to seeing them in other languages.
JavaScript is not Java, even though the names look similar.</p>

<p>Java, with its
  <a href="/2016/09/20/oop-without-classes.html">classes</a>,
  <a href="/2016/09/13/inheritance-is-procedural.html">implementation inheritance</a>,
  and
  <a href="/2014/05/05/oop-alternative-to-utility-classes.html">static methods</a>,
  is OOP for dummies.
It’s object-oriented programming for those who, according to <a href="https://www.youtube.com/watch?v=PSGEjv3Tqo0&amp;t=360s">Douglas Crockford</a>, don’t know what
  <a href="/2016/08/15/what-is-wrong-object-oriented-programming.html">object-oriented programming</a> is.
JavaScript, on the other hand, is a member of conceptually solid OO languages, like <a href="https://en.wikipedia.org/wiki/Smalltalk">Smalltalk</a> and Self.
Blending Java flavors into JavaScript only ruins the flavor of the latter.</p>

<p>It’s sad to see how a once straight object-centric language paradigm turned into a diversity of unmatchable and suboptimal features.</p>

<p>P.S. JavaScript is still a great language if you ignore classes and type annotations.
When I write in JavaScript, I don’t use them.
Look at the code in the <a href="https://github.com/yegor256/jo">yegor256/jo</a> repository.
It illustrates the <a href="/junior-objects.html">Junior Objects</a> book of mine.
I’m proud of this code.</p>

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">“People using classes in JavaScript will go to their graves never knowing how miserable they were” - Douglas Crockford <a href="https://t.co/D2Hpegn0vY">https://t.co/D2Hpegn0vY</a></p>&mdash; Yegor Bugayenko (@yegor256) <a href="https://twitter.com/yegor256/status/2010297169899913568?ref_src=twsrc%5Etfw">January 11, 2026</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>]]></content><author><name>Yegor Bugayenko</name><email>yegor256@gmail.com</email></author><category term="oop" /><summary type="html"><![CDATA[JavaScript was an elegant prototype-based class-free language until TypeScript and ES6 classes ruined it.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.yegor256.com/images/2025/12/platoon.jpg" /><media:content medium="image" url="https://www.yegor256.com/images/2025/12/platoon.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">You Are the Low-Hanging Fruit</title><link href="https://www.yegor256.com/2025/11/30/internal-vs-external-obstacles.html" rel="alternate" type="text/html" title="You Are the Low-Hanging Fruit" /><published>2025-11-30T00:00:00+00:00</published><updated>2025-11-30T00:00:00+00:00</updated><id>https://www.yegor256.com/2025/11/30/internal-vs-external-obstacles</id><content type="html" xml:base="https://www.yegor256.com/2025/11/30/internal-vs-external-obstacles.html"><![CDATA[<p>Let’s say, you are a startup founder, like <a href="https://www.zerocracy.com">myself</a>.
Try to hire a sales guy.
Offer him a commission-only payment scheme.
Listen to his reaction: he will demand that you pay a fixed salary too, on top of commission.
Try to convince him that commission-only is a more reasonable and <a href="/2014/09/24/why-monetary-awards-dont-work.html">motivating</a> setup.
Goto 1.
After a number of iterations you realize that the mission is impossible.
Sales people are good at selling and the best thing they sell is the idea that their <em>time</em> must be compensated.
Even if they don’t sell the product to your customers.
If you don’t buy the idea, they go find another loser who will.
Something similar happens when you try to pay programmers by result.
They easily convince you to pay for <a href="/2015/07/21/hourly-pay-modern-slavery.html">their time</a>.
And you do.</p>

<!--more-->

<figure class="jb_picture"><img itemprop="image" alt="City of God (2002) by Kátia Lund" src="/images/2025/11/city-of-god.jpg" longdesc="#1e31b0ff" /><figcaption id="1e31b0ff">City of God (2002) by Kátia Lund</figcaption></figure>

<p>A sales rep doesn’t know how to write code.
Most of them don’t even know how computers work.
However, he <em>perfectly</em> knows how to bullshit people.
That’s exactly why we need him.
Because we don’t know how to bullshit people and we don’t want to learn it.</p>

<p>Now, two strategies lie in front of him.
He can use the skill against the prospects on the market and turn them into paying customers.
He can also use the same selling skill against you, the owner of the startup.
Instead of selling the product to the market he can sell <em>himself</em> to you.
He can sell the idea that even if he fails to sell the product to the customers he still deserves a decent weekly paycheck.</p>

<p>What do you think, which sale is easier to make?
What would you do in his shoes?
The answer is obvious.
The customers are far away and they have no mercy.
If they don’t like the offer, they simply hang up on him and that’s it.
You, on the other hand, sit next to him in the same office and can’t hang up.
You are the <em>low-hanging fruit</em>.
You are the <em>weakest</em> prey he can reach out to.</p>

<aside class="quote">In order to make him focus on external obstacles, you should make internal ones harder to overcome
</aside>

<p>A customer is an <em>external</em> obstacle that he must overcome in order to get paid, as a sales commission.
You are an <em>internal</em> obstacle, which he may also overcome to get a fixed weekly payment.
You need him to fight the external obstacle.
However, he is free to choose the <em>easiest</em> path.</p>

<p>In order to make him focus on external obstacles, you should make internal ones <em>harder</em> to overcome.
Joseph Stalin once <a href="https://www.goodreads.com/quotes/338750-in-the-soviet-army-it-takes-more-courage-to-retreat">said</a> that “in the Soviet army it takes more courage to retreat than advance.”
This war-time concept seems relevant to the sales guys you hire.
It must be harder for them to talk you into paying them a fixed salary than to convince a prospect to buy your product.</p>

<p>Emotionally, for you it may be rather challenging to constantly push him back.
Just like it’s often hard to say “No” to a vagrant begging for a dollar at the corner.
Beggars, unless they are physically disabled, also, just like sales people, have two possible life strategies.
Either find a job or beg at the corner.
The begging strategy, for the vagrant and for the sales rep, is <em>easier</em> to pursue.</p>

<p>Programmers are not much different.
They also have two strategies.
They can solve technical problems by merging qualified pull requests.
They can also persuade you that you must pay for their time, not their pull requests.
Which obstacle is going to be harder for them to overcome depends on <em>you</em>.</p>

<p>First, you set up a formula for measuring their contribution.
Second, you bind their paychecks to it: they get paid <a href="/2016/05/24/who-is-project-manager.html">not by you</a>,
  but by <em>merged pull requests</em>.
Finally, you taboo the very possibility of discussing time-based compensation.</p>

<aside class="quote">Taboo the very possibility of discussing time-based compensation
</aside>

<p>What you get is a technical team focused on resolving external problems.
The team will <em>advance</em> because it will be <a href="/2018/07/24/bugs-or-pull-requests.html">pointless</a> to <em>retreat</em>.
You simply <a href="/2015/07/21/hourly-pay-modern-slavery.html">won’t pay</a> them for their time.
No matter how many times they repeat “I was working hard the entire weekend.”</p>

<p>Incentives shape behavior.
If you reward excuses, you buy excuses.
If you reward results, you get results.
As a founder, your job is to eliminate the temptation for your team to <a href="/2019/07/10/inversive-management.html">sell you</a>
  anything other than tangible artifacts.</p>]]></content><author><name>Yegor Bugayenko</name><email>yegor256@gmail.com</email></author><category term="management" /><summary type="html"><![CDATA[Sales reps and programmers can either fight external obstacles to earn their pay, or convince you, the founder, to pay for their time regardless of results; make the internal path harder.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.yegor256.com/images/2025/11/city-of-god.jpg" /><media:content medium="image" url="https://www.yegor256.com/images/2025/11/city-of-god.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Small Repo, High Quality</title><link href="https://www.yegor256.com/2025/11/16/smaller-repository-higher-quality.html" rel="alternate" type="text/html" title="Small Repo, High Quality" /><published>2025-11-16T00:00:00+00:00</published><updated>2025-11-16T00:00:00+00:00</updated><id>https://www.yegor256.com/2025/11/16/smaller-repository-higher-quality</id><content type="html" xml:base="https://www.yegor256.com/2025/11/16/smaller-repository-higher-quality.html"><![CDATA[<p>I don’t like <a href="/2018/09/05/monolithic-repositories.html">monolithic repositories</a>.
They keep multiple projects together, often written in different languages, by different teams.
Unfortunately, <a href="https://dl.acm.org/doi/pdf/10.1145/2854146">Google</a>, <a href="https://engineering.fb.com/2025/10/16/developer-tools/branching-in-a-sapling-monorepo/">Facebook</a>, and <a href="https://shiftmag.dev/mono-repo-infrastructure-yandex-1011/">Yandex</a> favor them.
Primarily, according to them, <a href="https://monorepo.tools/">monorepos</a> reduce integration <a href="https://www.sonarsource.com/resources/library/monorepo/">overhead</a>.
They do, but at the cost of quality.
In smaller repositories we can develop better code.</p>

<!--more-->

<figure class="jb_picture"><img itemprop="image" alt="Морфий (2008) by Алексей Балабанов" src="/images/2025/11/morphine.jpg" longdesc="#04b3173e" /><figcaption id="04b3173e">Морфий (2008) by Алексей Балабанов</figcaption></figure>

<p>When a repository is smaller you can achieve higher quality, for a number of reasons:</p>

<ul>
  <li>
    <p><strong>You can be stricter on style.</strong>
It’s easier to keep a thousand lines consistently formatted than a million.
With a thousand lines, you can configure <a href="https://eslint.org/">ESLint</a> to its maximum, enabling as many rules as you can find.
Stricter <a href="/2014/08/13/strict-code-quality-control.html">control</a> over code stylistics leads to cleaner code.</p>
  </li>
  <li>
    <p><strong>You can write deeper tests.</strong>
Integration (or <a href="/2023/08/22/fast-vs-deep-testing.html">deep</a>) tests are inevitably slow.
In a smaller repository, a good integration test coverage doesn’t mean a slow build.
In a larger repository—it does.
A slow build is something a team tries to avoid, thus jeopardizing the coverage.</p>
  </li>
  <li>
    <p><strong>You can review more pedantically.</strong>
In a larger repository it may be harder to remember all the aspects of design.
A pull request that affects different seemingly unrelated code parts
may be a challenge to <a href="/2015/02/09/serious-code-reviewer.html">review</a>.
Even if you are the <a href="/2014/10/12/who-is-software-architect.html">architect</a>.</p>
  </li>
  <li>
    <p><strong>You can write a README.</strong>
Maybe you have noticed already: large open source projects have short and sketchy <a href="/2019/04/23/elegant-readme.html">README</a> files.
They can’t make them much longer without them becoming as large as a book.
All they can do is redirect the reader to the documentation website.
The inability to explain the entire scope in a single file leads to scope creep.
Contributors struggle to understand the borders of the project.
This leads, among other bad things, to code duplication.</p>
  </li>
  <li>
    <p><strong>You can release frequently.</strong>
In a larger repository, frequent reintegration may be expensive, in both time and money.
In a small repo, a <a href="/2025/04/12/four-builds.html">build</a> of a few seconds is not a dream of programmers, it’s their reality.
Not only CI is cheap, but also CD.
After every small change you can publish a new release, with its own <a href="https://semver.org/">version</a>.
In a monorepo, we tend to wait until a portion of changes accumulate.</p>
  </li>
  <li>
    <p><strong>You can use AI agents effectively.</strong>
It is no secret that modern LLMs have limited <a href="https://docs.claude.com/en/docs/build-with-claude/context-windows">context windows</a>.
A million lines of code can’t fit into even the largest of them.
Even ten thousand lines, let alone a million, is more than an LLM can digest.
By keeping a repository small we do a big favor to our little friends: AI agents.</p>
  </li>
  <li>
    <p><strong>You can on-board faster.</strong>
Larger codebases are usually older and more <a href="/2018/09/12/clear-code.html">chaotic</a>, full of legacy code.
It takes longer to start making meaningful contribution to such a repository.
Monorepos attract
<a href="/2015/12/29/turnover-is-good-for-maintainability.html">long-term</a>
<a href="/2017/05/02/remote-slaves.html">office-based</a>
contributors
who care about job security more than about code quality.</p>
  </li>
  <li>
    <p><strong>You can expect responsibility.</strong>
In larger codebases, the very idea of code ownership is hard to maintain.
Programmers can hardly feel responsible for the code written and modified by others.
Smaller repositories, on the other hand, emotionally attach people to code.</p>
  </li>
  <li>
    <p><strong>You can go open source.</strong>
No matter how much your boss <a href="/2020/05/05/open-source-arms-race.html">loves</a>
open source, you can’t put your entire enterprise monorepo on GitHub.
However, if you extract a small part of it, you can.
The code that is open, visible and criticized by many people,
is <a href="/2015/12/22/why-dont-you-contribute-to-open-source.html">allegedly</a> of a higher quality.</p>
  </li>
</ul>

<p>In summary, you should look for an opportunity to extract a piece of code as a standalone package.
Then, insist on making it <a href="/2017/05/30/why-contribute-to-open-source.html">open source</a>.
Then, promote it in the community.
Then, quit your office job and join <a href="https://www.zerocracy.com">Zerocracy</a>.</p>]]></content><author><name>Yegor Bugayenko</name><email>yegor256@gmail.com</email></author><category term="oss" /><summary type="html"><![CDATA[By breaking your software into small open-source packages, you make the entire product easier to maintain—and significantly higher in quality.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.yegor256.com/images/2025/11/morphine.jpg" /><media:content medium="image" url="https://www.yegor256.com/images/2025/11/morphine.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>