Eliminating Code Complexity by Finding Double Negatives
Jeff Morhous // September 04, 2022
I have been reading "A Philosophy of Software Design," and almost the entire book is spent either explaining the dangers of complexity in a codebase, or eliminating complexity.
Code, especially Ruby code, should make its intent loud and clear to the reader. Clear code is the opposite of complex code. It's easy to understand its purpose, so it's easier and less risky to modify, extend, or remove.
One thing that I haven't seen explicitly discussed in this book is double negatives.
Whether it's spoken or written, double negatives make sentences less clear. Something like "There are not no eggs left at the store" is obviously poor grammar, but it also makes the sentence harder to understand.
When our code reads like a sentence (well written Ruby should), double negatives
increase complexity. Things like
unless !some_condition can be more clearly written
Most programmers will find writing in-line conditionals like this to be straightforward, but it gets less intuitive when extracting this logic into methods.
A bit ago, I was writing some ruby code with a friend. We wanted to take an action if something was false, and like the good ruby programmers we are, we extracted that complex conditional into its own short method.
We found ourselves going around and around trying to make this as clean as possible. One of our first iterations contained a programming double negative - see if you can find it:
# Method call return  unless items_found(users) # Method implementation def items_found(users) no_items_found = false users.each do |volunteer| if volunteer.items.present? no_items_found = true end end no_items_found end
Contrast this to what we ended up with
# Method call return  if no_items_found_for(users) # Method implementation def no_items_found_for(users) no_items_found = true users.each do |volunteer| if volunteer.items.present? no_items_found = false end end no_items_found end
It's a pretty small change, but I think it highlights what the code actually does much better than the first time around. I'm trying to be more intentional about writing my code with these things in mind.
If you enjoyed this, consider signing up to my newsletter to get occasional updates about new things I make or write.