loading...
Cover image for The Life-Changing Magic of Flat Code

The Life-Changing Magic of Flat Code

recursivefaults profile image Ryan Latta ・2 min read

Here’s the situation, you come across some code and you have to start making sense of it. As you read the code you begin to build a mental model of how the pieces work, and then slowly but surely you get enough of it in your head that you see potential bugs or areas to improve.

The problem is that doing this is arduous work, and we can only accurately keep very little code in our head before we begin to over-generalize or lose detail.

When I’m working with teams of developers, I often will teach them to flatten their code. The idea is simple enough to demonstrate, but in this article I’m going to focus only one way to flatten code: If statements

Let’s take a look at a common block of code:

function doAwesomeWork(isNotUnset) {

  result = null

  if(isNotUnset) {
    for(int i = 0; i < 20; i++) {
          result = ...
    }   
  }
  else {
   return result
  }
}

Ok, so this isn’t the most complicated thing I can produce, but it does force the mind to work. We have to remember what the result variable is doing, what we are checking in the first if, the purpose of the for, and within that what the result is being set to. Then we have to remember that if isNotUnset is false, then we send back a null result.

Also, I named isNotUnset that way to be mean. Though I bet you can find an example of that easily in every codebase you’ve seen.

Here’s the way I’d flatten the if:

function doAwesomeWork(isNotUnset) {
  if(!isNotUnset) {
    return null
  }

  result = null
  for(int i = 0; i < 20; i++) {
    result = ...
  }
  return result
}

Reading this is a little different. We check the first if, and we might be done there. Mentally we can treat this as a self-contained section and not have to remember it once it is understood.

Now we move to the meat of what this does. When I see the function, I can see very quickly that this function is about the loop. I can focus on that behavior instead of remembering the conditions that get me to it.

That is what this technique is about. So the goal when flattening if statements are:

  • Get the business logic as close to the left margin as possible
  • Use conditionals for errors and exceptions
  • Remove else statements where possible

In this case, the business logic is the for loop, so I want that to the left. The way I break the if that contains it is to use it as an error check. I inverted the logic and turned it into an early return. That left me with the business logic as the only thing the function does if the pre-conditions are correct.

When you’re coding, give this technique a whirl. You’ll find that the code is way easier to understand, refactor, and test.


Hey devs I've launched a newsletter for developers who want to make the most of their career. Come check it out!

image credit unsplash

Posted on by:

recursivefaults profile

Ryan Latta

@recursivefaults

I've been in software since 2009. I help software companies get the results they want and developers get the career of their dreams.

Discussion

markdown guide
 

This if statement

  if(!isNotUnset) {
    return null
  }

is called a guard clause like you mentioned it's a way to reduce if else blocks. In the end, it makes your code cleaner and easier to read.

 

Yep, you can also vary into assertion based programming as well.

 

This is a good, succinct description of a useful technique. I would however think about adding some detail of what's happening in that loop. The final code looks like you're just going to return the value from the last iteration; which I'm sure isn't what's intended ;)
Depending on what it does you could even extend the example to directly return the output from an array function (e.g. reduce, map etc.)

 

Haha, you're in my head. As I was writing the example I was deciding how far I wanted to carry it for correctness. I opted for keeping the code near the if's at a more abstract level. Partially hoping people wouldn't fixate on it ;)

 

The expression !isNotUnset already causes me to wonder what the condition of isSet() and UnSet is. I almost thought you did it as a way to demonstrate good negative logical tautology to be smart :D

 

This technique is also known by other labels: early returns or return early pattern.

And I'm a big fan.

However, it's worth pointing out that not everyone is on board -- I've even seen it explicitly discouraged in company coding guidelines. Not quite spaces vs tabs battleground but up there :D

 

Oh, there are tons of strange things in coding guidelines that companies create. I think that's a whole separate topic :)

My personal favorite from a coding guide: Always use pre-increment in for loops.

 

I spent a few months writing Go at work last fall, and absolutely fell in love with this style! Kudos for sharing!