Code That Doesn't Exist Is The Code You Don't Need To Debug

fagnerbrack.com ~3 min read
View original
Crawl details
  • best
Summary (TL;DR)
Writing only the code you need keeps complexity down. When testing a function that calls a network request, you can stub just the few response properties the function uses instead of copying the whole dataset. That cuts unused test data, makes the test smaller and easier to reason about, and forces you to add more only when the code demands it. Running tests first does the same thing by pushing you toward the minimum code that satisfies a use case. Deleting code lowers what the author calls software entropy. Teams tend to reward adding features but ignore removals, so the author argues developers should be rewarded for deleting useless code just as much. Dead code still costs testing, maintenance, and support work.

As a developer, you’re in the business of managing complexity. And code is inherently complex.

By writing as little code as necessary to solve the task at hand, you’ll have fewer concerns down the road.

Less code, less complexity.

There are many examples that can illustrate this principle. For the purpose of this post, let’s say you want to test an existing function. It’s an untested legacy function that executes a network request and does something with its response. The important aspect is that the response contains more data than what the code actually uses.

The code showing a function that only requires the “street”, “number” and “suburb” properties from the “accountDetails”. See the line 27.

When testing that function, you want to stub the network request and provide a fixed dataset that simulates the original one. This way you can verify whether the function works as expected.

The code stubbing the network request with the same dataset. See lines 37 to 47.

But the original dataset is huge and you don't really care about the rest of it. You can just provide the minimum response necessary to satisfy the requirements of the function you’re testing.

The code, stubbing just the minimum amount of properties from the dataset. See lines 37 to 41.

There are a few benefits with the last example:

  1. There’s no unused response in the test
  2. The dataset won’t be huge, so it’s easier to reason about it (and that also makes the test smaller)
  3. If the code starts requiring more data from the response because of another test on the same function, the test will fail and you can start adding the rest of the response on an ad-hoc basis
  4. If you always change code by changing the tests first, when the code starts requiring less data, you’ll always be removing it from the tests first in order to keep the minimum amount of code necessary to test it

Test Driven Development (TDD) forces you to write the minimum amount of code that satisfies a use case. In the last example, if you had used TDD, it would have forced you to write the minimum amount of code in the dataset until you needed more data (See number 3 above).

In a great article called You Are Not Paid to Write Code, Tyler Treat says:

Every time you write code […] you are introducing the possibility of failure into your system.

A software system has a tendency to become more complex over time, increasing Software Entropy. The act of deleting code helps drive the system to a state where there’s only code that is necessary — a state where there's less Software Entropy. But project teams tend to ignore this principle and focus mostly on adding new things.

To avoid that, I believe developers should be rewarded when they remove code. Perhaps the same way (or more) than when they add new features.

Removing useless code should be rewardable.

Besides complexity, useless code can also represent part of a functionality that doesn't provide any value. For every feature or change related to that functionality, you have more stuff to test, maintain, and support. That’s an unnecessary cost to the project, and a cost that doesn't go away unless explicitly removed.

Evolution has shaped our minds to think of short term benefits. Adding features or fixing bugs to satisfy the project goal leads to short term benefit in the context of Software Entropy. This is essential, but shouldn’t come at the expense of adding or leaving code that is not necessary.

The characteristic that makes us humans is our ability to think ahead. Our ability to think about what really matters for a project. What we need is to reinforce the culture of removing code.

The code that doesn’t exist is the code you don’t need to worry about.

After all, why having to worry about something you don’t need to?