Code Craftsmanship: Never Nesting

Reviewing the practice: Never Nesting

This blog post will review a video about how to write cleaner code using a practice where you try to not nest your code. I will then give my thoughts on the video and comment on whether I think this is a good practice or not based on my personal opinions.

What is Nesting

In the video he talks about nesting your code, nesting refers to the practice of adding more code blocks within an existing code block, here's an example of a nester for loop in javascript:

for (let i = 1; i <= 3; i++) {
  for (let j = 1; j <= 3; j++) {
    console.log(`Outer loop: ${i}, Inner loop: ${j}`);
  }
}

We call this a nested for loop because there's a for-loop code block inside an existing for-loop code block. He mentions in the video that he'll refer to each indentation/nest in the code as depth, for each indentation the depth increases, one indentation is one deep, two indentations are two deep, and so on. I'll be referring to indentations similarly here.

How Never Nesting works

In the video he explains you can achieve never nesting using two methods, extraction and inversion. Here's an example to showcase both:

function example(param1, param2) {
  if (param1) {
    if (param2) {
      const convertedParam2 = (param1 + param2).toString(36)  
                    + "-" + Math.round(Math.random() * 9)

      for (let i = 0; i < convertedParam2.length; i++) {
        const letter = convertedParam[i]
        if (letter == "b") {
          return true
        }
      }

      return false
    } else {
       console.warn("Please Provide a param2")
    }
  } else {
    console.warn("Please provide a param1")
  }
}

To denest this function we can make use of the two methods mentioned earlier, first extraction, we'll take the for loop out of the function and put it into its own function.

// extracted function
function convertNumber(n) {
  const r = Math.round(Math.random() * 9)
  return param2.toString(36) + "-" + r
}

// extracted function
function containsLetter(word, letter) {
  for (let i = 0; i < convertedParam2.length; i++) {
    const letter = convertedParam[i]
    if (letter == "b") {
      return true
    }
  }

  return false
}

function example(param1, param2) {
  if (param1) {
    if (param2) {
      // extracted functions used to be here
      const convertedParam2 = convertNumber(param1 + param2)
      return containsLetter(convertedParam2, "b")
    } else {
       console.warn("Please Provide a param2")
    }
  } else {
    console.warn("Please provide a param1")
  }
}

Now we can make use of inversion, this is where we take conditions and invert them so that the rest of the code becomes the condition, removing the nesting required for the condition.

function convertNumber(n) {
  const r = Math.round(Math.random() * 9)
  return param2.toString(36) + "-" + r
}

function containsLetter(word, letter) {
  for (let i = 0; i < convertedParam2.length; i++) {
    const letter = convertedParam[i]
    if (letter == "b") return true // less nesting
  }

  return false
}

function example(param1, param2) {
  if (!param1) { // inversed condition
    console.warn("Please provide a param1")
    return
  }

  if (!param2) { // inversed condition
    console.warn("Please provide a param2")
    return
  }

   // there used to be a big nest of conditions here
   const convertedParam2 = convertNumber(param1 + param2)
   return containsLetter(convertedParam2, "b")
}

Mental Storage

He mentions that when over-nesting, he finds that he has to keep all these conditions in mind when going through the code, which becomes very hard to do the more you're nesting your code. When you denest your code, you can discard the conditions that were checked earlier in the code and you only have to focus on the core code. It makes less difficult to go through old code and understand it.

Conclusion

I completely agree with this coding methodology, and I took a lot away from this video, never nesting makes your code easier to understand and makes it more readable and promotes self-documentation by forcing you to split big functions into smaller functions. Since watching that video, I've adopted the "never-nesting" approach in my own programming, and it has significantly improved the way I write and understand code. It's a game-changer for sure!