Why so negative?

Published by Michael Carrano on August 20, 2021



As an engineering manager, one thing I spend a lot of time doing is reviewing code that my team ships. According to Pull Panda I am often a top reviewer for the team.

There are many things I look for when reviewing the code such as does this architecture make sense? Is it flexible for future changes or will we have to redo a lot of it? Does it do what you think it does? Are we already doing something similar elsewhere and we just re-invented the wheel? And much more.

Then there are the smaller things I look for such as naming (one of the hardest problems) and cognitive load when reading and understanding the code.

The most common feedback I give is related to using negation ! in the code. Is it really needed? We can all be more positive.

Here are just some basic examples of what I come across and how they can be improved.

// Common example with negation. 
// Reading this code would be something like: 
// "If colors is NOT empty then doSomething1() else doSomething2()".

val colors = listOf("red", "blue", "green")
if(!colors.isEmpty()) {
    doSomething1()
} else {
    doSomething2()
}

// Lets see how a small change can improve the cognitive load.
// This will now read as 
// "If colors is empty, doSomething2() else doSomething1()". 
// We have the same exact outcome as the above without having to think about negation.

val colors = listOf("red", "blue", "green")
if(colors.isEmpty()) {
    doSomething2()
} else {
    doSomething1()
}

Here is another example which involves some not so great variable names:

// Pared down example from our actual codebase before refactoring it
// Try reading this... "If NOT don't show again, then doSomething1() else doSomething2()"
// Double negatives can hurt your brain

val dontShowAgain = false;
if (!dontShowAgain) {
    doSomething1()
} else {
    doSomething2()
}

// Lets see how renaming the variable and removing the negation can clean this code up.
// Now this is much easier to read as "If showAgain, doSomething1() else doSomething2()".
val showAgain = true;
if(showAgain) {
    doSomething1()
} else {
    doSomething2()
}

// I had to triple check my logic above to make sure I was still right.

The last example is real. I worked with our intern this summer to refactor this area of code and we were often on Zoom confusing ourselves because of the double negatives when trying to comprehend the code. Ultimately decided that we should first add tests to this part of the code since we lacked coverage before refactoring to make sure we did not break our logic.

So try to be more positive with your code, it really helps.