Thursday, July 14, 2022

The Quickest Way to Become a Better Developer

 The Quickest Way to Become a Better Developer

What if I tell you that stopping using the else statement will make you a better developer and increase the quality of your code?



Let’s be honest… even though we are always trying to follow standards and best practices, we are only humans (after all)!

We all have different preferences, backgrounds, and experiences that make our code look slightly different from the one of our colleagues, in some way we can say that we all have our style of coding.

Most of the time this “style” consists of little things, like using a ternary operator instead of an if statement for a simple check, or using explicit function declaration instead of arrow functions; Some other times these things are close to being guilty pleasures.

Like everyone, I also have some preferences when I code, and as you could guess by the subtitle of this article, there is one in particular that I’d like to talk about: I never use the else statement!

❓ What is the problem with the else statement?

The answer is pretty simple: I write better code without it!

I know I’m not alone in this “battle”, but for those that are asking why I’m not using a fundamental piece of every programming language, here is an explanation:

We can detect 3 code smells that are often related to the else statement:

if (condition()) {

  // Then Block

} else {

  // Else Block

}

The first smell is related to the condition itself, in fact, if the condition is complicated, the else is twice as complicated because the reader has to invert the condition:

if(something > somethingElse || (!anotherVariable && something === 0)) {

  // then block

} else {

  // else block

  // If this is executed it means that the previous condition was false

  // which means that one of the following conditions was false:

  // - something > somethingElse

  // - !anotherVariable && something === 0

  // Possible scenarios:

  // ---> "something" equals to "somethingElse"

  // ---> "something" greater than "somethingElse"

  // ---> "anotherVariable" true and "something" === 0?

  // ---> "anotherVariable" false and "something" !== 0?

  // ---> "anotherVariable" true and "something" !== 0?

}

The second smell, instead, is somehow related to the visibility of the condition itself: If the “Then Block” contains more than a reasonable amount of lines it’s easy to forget what the condition was.

Last but not least, The third smell is when we have nested if-else blocks because they easily become really — really — hard to read:

if (conditionOne) {

  // then block condition one

  // conditionOne is truthy

  if (conditionTwo) {

    // then block condition two

    // conditionOne is truthy and conditionTwo is truthy

  } else if (conditionThree) {

    // else block condition two

    // but also then block of condition three

    // conditionOne is truthy and conditionTwo is falsy and 

    // conditionThree is truthy... I guess

  } else {

    // Is becoming hard to understand how I got here

    if (conditionFour) {

      // then block condition four

      // I hope no one will enter this block because I don't

      // know how to go back!

    }

  }

}

In all the previous examples, refactoring the code to avoid the usage of the else branch will result in a better and more readable code. This led me to a thought — What if the else branch was never invented?

 Would it be a better world without it?

What if the else branch was never invented?

Would it be a better world without the else statement?

Short answer: Yes.

Long answer:

The problem is not the else statement, the problem is you .

If we analyze again those 3 big “smells”, we can see that the real problem is not the else statement, the real problem is the whole if-else block that, if used in the wrong way, can quickly become a mess.

Forcing yourself not to use the else statement is just an easy trick to better structure your code because you’re forced to extract that piece of code into a separate function — which is always a good idea, whether you’re using the else branch or not.

So… What if there was no “else”?

Let’s start from a fact: the else statement is unnecessary! A world without else is possible!

Even though we wrote millions of conditions in our code, there are 2 possible scenarios for an if-else statement: when there is code after the if-else statement and when there is not:

First scenario: There isn’t any code to be executed after the condition:

function mainFunction() {

  if (condition())  {

    executeIfTheConditionIsTruthy();

  } else {

    executeIfTheConditionIsFalsy();

  }

}

Second scenario: when some code will be executed in any case, no matter the result of the condition.

function mainFunction() {

  if (condition()) {

    executeIfTheConditionIsTruthy();

  } else {

    executeIfTheConditionIsFalsy();

  }

  executeAnyway();

}

In this scenario, extracting the if-else block into a separate function is the way. There is also a name for this pattern: Extract Method.

You can always iterate the process for nested if-else and apply the Return early and Extract method together.

Let me also give you a real-world example, so everything will be much easier to understand:

function isEven(number: number) {

  if (number % 2 !== 0) {

    return false;

  } else {

   return true; 

  }

}

Here we don’t even need the if statement at all, because returning directly "number % 2 === 0 “ is enough, but this is not the point.

We don’t need any explicit else branch — if the code below the if statement is executed, it means that the condition is false.

And so, the rest of the function is an implicit else branch!

The resulting code is more clear and more concise.

Second scenario

function sendNotification(numberOfPeople: number) {

  let message = '';

  if (numberOfPeople === 0) {

    message = "No one will attend your talk 🥲";

  } else {

    message = `${numberOfPeople} people will attend your talk!`;

  }

  NotificationService.send(message);

}

Also in this case not using the else branch ended up in an improvement of the code quality, in fact, the function before was doing 2 things:

- creating the content of the message;

- calling the API to send the notification;

Now instead, the creation of the message is delegated to a dedicated function and the resulting code is easier to read and better structured.

In conclusion

By the way, I don’t have anything against the else statement and I’m not suggesting to always avoid it, all I wanted to point out is:

If you feel lost in a condition, try to refactor the code to avoid the else branches — you’ll have a better code as a result just because you’ll be forced to follow best practices and split the complexity into different functions— but if you don’t feel the smell, everything is fine 😉.


No comments: