RSS

Tag Archives: code review

Small Changes and the Art of Non-Destructive Review

Two landscapers discussing a planting plan in a garden, one holding a blueprint and pointing to a marked spot on the grass, while the other holds a shovel and gives a thumbs up next to a potted plant.

I think we’ve all experienced a system failure that occurs when we are sure nothing changed. But aside from that, it feels true that the smaller the change you make, the better are the chances that it will have no negative repercussions. Having someone review your proposed change improves its chances of success. And small changes are easier to review with confidence than big ones.

When doing file maintenance on a Linux system, I often end up needing to remove some files:

rm <some_pattern>

How sure am I that will do what I intend? Fortunately, listing and removing files in Linux are very close in syntax. I almost invariably precede an rm with a pattern by ls with the same pattern:

ls <some_pattern>

I review the output, convince myself only the intended files are affected, then use the up arrow key to recall the ls, change ls to rm, and press return to execute. I do not retype the pattern!

I can then press up twice and re-execute the ls to verify the files are gone.

Happily, SQL SELECT and DELETE have a similar relationship: the first finds and the second destroys. If I think I want to do:

DELETE FROM my_table WHERE <some_clause>

I generally first do:

SELECT * FROM my_table WHERE <some_clause>

Then, when I’m confident it selects the right rows, I edit the command changing only SELECT * to DELETE and nothing else and then execute it.

It’s less helpful that SQL SELECT and UPDATE have somewhat different forms so if I want to change data, I can’t just write a query and make a simple edit to update the same rows. At least not in an obvious way.

Recently, someone asked me to review their plan to update some data. They offered a fairly complex SELECT that identified the relevant rows and showed the data that needed to be changed. But then they offered a different query to find rows to update. I spent a few minutes looking at the two queries and decided I could not be confident they found and changed the same rows. A common table expression turned out to be the solution.

The query to find the relevant rows ended up something like:

WITH Changes AS (
-- a complex query
)
SELECT t.OldValue, c.NewValue
FROM table AS t
JOIN Changes AS c
ON c.ID = t.ID;

Of course, we could have listed more values from t if they were helpful but this was enough to

  1. Give the developer something safe to iterate on while developing the query logic
  2. Give me a harmless query to review carefully and run as needed to raise my confidence

Once we both felt that the complex logic in the CTE was correct, they had only to change:

SELECT t.OldValue, c.NewValue

to

UPDATE t SET OldValue = cNewValue

That is an almost trivial change that is easy to review. The complex query could have been tens of lines but it didn’t need to be reviewed again because it didn’t change.

They changed it, I reviewed it, they ran it. It did exactly what we wanted.

We often think of database safety in terms of transactions, permissions, or backups. But human-centric safety is just as critical. Good software engineering requires writing code that is easy for a person to read, review, and trust.

If a peer review requires holding two separate queries in your head to verify they target the exact same rows, the process itself invites error. Wrapping the selection logic in a CTE bridges the gap between shell simplicity and SQL structure: it lets you preview the precise impact before swapping out the verb, giving both author and reviewer total confidence.

Small, atomic changes make code easier to write, safer to review, and far less stressful to execute.

 
Leave a comment

Posted by on September 15, 2026 in Software techniques

 

Tags: , ,

Good Reviews Are Conversations

   Q: How do you know if a programmer is an extrovert?

   A: They look at your shoes when they talk to you.

I can say that, I’m a programmer. And an introvert. 😉 But that’s not the type of conversation I want to write about.

A code review is a conversation: someone asks a question or makes an observation and someone else responds. But it turns out the mechanics of a code review also apply to other types of written feedback. In the past few weeks, I’ve participated in reviewing code, design documents, and contracts. Along the way, I’ve recognized that a few guiding principles can help you get the most benefit out of the review process.

Be Specific

I mean this both in the sense of not being vague (“This seems wrong”) but also not being general. It’s rare that code or prose is so weak it needs to be rewritten from scratch. You almost always have a solid outline and one or more things could stand improvement.

  • In modern source control platforms, you can likely comment on a specific line of code.
  • In Google Docs, Microsoft Word, and such, you generally highlight the text you want to comment on.

Once you’ve picked the code or text to comment on, give specific feedback.

  • “This variable name is inconsistent with our usual style”
  • “I find this hard to read; parentheses would make this calculation clearer”
  • “This sentence lacks the serial comma that is recommended in our style guidelines”
  • “This seems to contradict section 2.3 earlier in the document”

Critique the Work, Not the Author

Good review comments focus on the artifact, not the person.

Weak: “You clearly didn’t think about edge cases here.”

Better: “It’s not clear to me what happens if the input list is empty.”

The distinction matters. The first version invites defensiveness; the second invites collaboration. Remember, the goal is to improve the work, not win the argument.

Help the Author

If there is an external authority (a style guide or RFC or Wikipedia entry) that supports your argument and gives the author resources, link to it. (If no such reference exists, consider if your comment is going to improve the code or text, or just satisfy your own style bias.)

Be Responsive

Distributed teams thrive on the asynchronous nature of cloud-based feedback loops. But the feedback needs to be timely. I’ve come back to a conversation that has languished and wondered, “What was I trying to say here?” Your team may be in different time zones or on different schedules so feedback in minutes or even hours may not be practical. But if your feedback cycle is measured in weeks, you’re probably spending too much time getting back up to speed as you dig in again.

Only the OP Can Resolve a Conversation

Only the original poster knows with confidence that their concern has been addressed. If the reviewer is confused, the author can’t just rewrite it and assume it is now clear! Waiting for the reviewer to acknowledge that their concern has been addressed may be the most important contribution to the success of the review.

Weak

  • Author: Would you look at this?
  • Reviewer: This paragraph is hard for me to follow.
  • Author: I rewrote it. (And resolves the conversation.)

The author has no way to tell if the new text is clear to the reviewer.

Better

  • Author: Would you look at this?
  • Reviewer: This paragraph is hard for me to follow.
  • Author: How’s this?
  • Reviewer: Yes, I understand. Thanks. (And resolves the conversation.)

Challenge: Do you see the bug in the Python code in the image at the top of this post?

 
Leave a comment

Posted by on May 27, 2026 in Uncategorized

 

Tags: ,

Code Review in Three Words

I was recently at a networking event chatting with a non-technical acquaintance.  I mentioned that I was mentoring a new member of my team who was going to start reviewing some of my code soon.  I analogized that no one would consider publishing a book without an editor, and code needed a second set of eyes as much or more than prose did.  It got me thinking about how publishers have style guides that can be used as references when editing and I needed some way to explain to this young developer what to look for as he began to review my work.  Some teams have rigorous style guides and certain languages have favored idioms, but I was looking for something more generic and ended with these three broad guidelines.

Is it Correct?

If an article about Abraham Lincoln mentioned “the president’s wife, Martha” an editor might recognize the wrong president’s wife was named and easily make the correction.  Unless the article was about Presidents’ Day or some other topic that discussed the first and sixteenth presidents, then the editor might have to go back to the author and ask for a clarification.  Similarly, some code is clearly wrong on its face and some less obviously so, but in both cases careful reading by a fresh set of eyes can reveal many — but likely not all — the places that the code is incorrect.

Is it Consistent?

Sports writers have a special talent for finding hundreds of different ways to say “won” or “beat.”  Writing software isn’t — shouldn’t be — nearly as creative an endeavor.  If you create one object you don’t add another, unless that difference in term indicates a difference in use.  If “close” is the opposite of “open,” it is always the opposite of open, never “shut” or “seal” or “drop.”

Is it Complete?

When the anchor of the nightly news tells you that a stock market index is up 200 points today, what do you make of it?  Nothing, really; you have no information to go on.  Numbers with units — points in this case — are meaningless.  A 200-point swing in the Dow is very different than the same change in the NASDAQ.  Without a basis for comparison — like the value of the index — the story is incomplete.  If you were told it was up or down 5% or 15% then you have reason to cheer or worry.

What if your favorite sports team’s rival played yesterday and you wonder how the game turned out.  The sports section may be full of scores and commentary, but if the game you are interested it isn’t covered, the section is incomplete.

Putting it All Together

Software can be complex and subtle and reviewing it is not trivial and must be done on several levels.  As an analogy, consider the recent sales listed in the real estate section of my Sunday paper.  There is one item after another like:

Alice and Bob Smith bought property at 704 Main Street from Ted and Carol Jones for $195,800.

There are hundreds of these items county by county (in alphabetical order) and town by town within county (also alphabetical).  The items themselves seem to be unordered, perhaps they are by transaction date.

Is it correct?

The names of the parties, the address, and the price in each item are verifiable.  There is a record of sale somewhere that can be consulted to be sure that the facts are correct.  If a few letters in the middle of the listing were in italic or bold or a different typeface, you could reasonably argue that is incorrect, too, though at a different level.

For software, the source of truth about the software’s intent is the design, sometimes reflected in a test it is expected to pass.  When revising software to address a bug, you must reference the ticket where the bug is described to know what the wrong and expected behaviors are in order to assess the correctness of the code.

Is it Consistent?

Occasionally the real estate sales include an item like

Betty and Barney Rubble bought property at 1 Gravel Lane from Acme Relocation Services for $1,234,567.

This is noteworthy because the seller is a company.  More subtly, you might also have noticed in the first example that one couple is listed woman first and the other man first.  Is that intentional?  Perhaps the listing just echoes the names as they appear on the deed.  Or perhaps they are intended to always be in alphabetical order (in which case the Ted and Carol are in the wrong order).  Once you are accustomed to the standard format, exceptions stick out.

This happens with software, too.  If two pieces of code do very similar things, they should differ only in the ways that are necessary.  Unexplained or unnecessary differences should cause the reviewer to pause and wonder if they are also unjustified.

Is it Complete?

On a rare weekend, the listing of sales omits my town.  It is hard for me as a reader to tell if single transactions are missed with more regularity.  If I were tasked with editing or reviewing that section I would need a checklist of all the communities covered and their counties.  That list could be used week after week.  I’d also need at least a count of transactions per town and overall as a first check of completeness.  And if accuracy was paramount, I’d want some form of the sales records to reconcile the listings with.

Even a simple software system may be built around several different classes.  For classes that may be stored as records in a database, each needs code to create, read, update, and delete instances.  Your classes have to cover all those operations for all the classes (or your comments need to explain why, say, one object is immutable after creation).

That system should have a test suite that covers creating an instance of each class in each way that is meaningful (using default values, using overridden values, using invalid values, etc.).  It should test retrieving or reading each class, including trying to get one that doesn’t exist.  It should test updating an instance of the class with no changes, with valid changes, with incompatible changes to values, etc.  It should read and attempt to update one that is deleted between the operations.  It should test deleting objects, including trying to remove one that doesn’t exist.

The combinatorics add up quickly — like the sales in towns and the towns in counties — and reviewing the code of the implementation and the tests that verify can be painstakingly detailed work.  But if the system is important enough, it is necessary.

That’s my 1,000-word take on three watch words for code review.  Are they enough?  Probably not.  But I hope they provide a starting place for novice reviewers as they develop their reviewing skills.

 
Leave a comment

Posted by on November 1, 2017 in Uncategorized

 

Tags: ,