Don’t use ‘else {}’

Georges Jamous
5 min readAug 15, 2019

--

let’s use something else instead

if-else has been around since humanity first started coding. It is the core of our systems and conditional statements are crucial for program flow control.

wikipedia — ….conditional statements, conditional expressions and conditional constructs are features of a programming language, which perform different computations or actions depending on whether a programmer-specified boolean condition evaluates to true or false….selectively altering the control flow based on some condition.

Just one second, think about a simple if-else condition.
Just like when you want to explain it to someone new to coding.
Have something in mind? Sweet! let’s go

Your mind probably went to something like this (or at least a variation of it)

if true {
.. do stuff when true
} else {
.. do stuff when false
}

I mean why wouldn’t you? It’s an if-else statement, it does its job and you can nest them as much as you want to control the flow! heck, we can even throw in functions, check this out!

if true {
if true {
doSomething()
} else {
doSomethingElse()
}
} else if {
} else {
}

Let us solve a simple hypothetical problem using what we know

We want to create a program to simulate a bartender handing beers.
The customer enters his name and age, the bartender only serves the request if the age is over 18.

Keep it simple, one or two functions max. I am gonna use Swift.

func giveMeABeer(name: String, with age: Int) {
print("Hello!")
if age >= 18 {
print("sure thing \(name)\n")
print("here you go 🍺. Cheers!")
} else {
print("sorry you are not old enough to drink \(name)")
}
}
// or if you are a function freak like me
// you might have gone with something like this
func giveMeABeer(name: String, with age: Int) {
print("Hello!")
if canDrink(age) {
okGiveBeer(to: name)
} else {
underAgeAlert(to: name)
}
}

we’ll get back to this example in a sec

Ok, so let’s ditch the ‘else’ and think about conditional flow the following way:

if !true { 
break the pattern and exit
}
...continue normally
// instead of if true {
.. do stuff when true
} else {
.. do stuff when false
}

Now hold on! bear with me.

What is the bonus?

Generally, when solving a problem, our mind finds the best possible solution using the tools at our disposal to solve it. In other words, the tools we have forges the solution and more importantly draws the path to reach the solution. makes sense yet?

ok let me speak in a language we both understand:

In coding terms, the tools at our disposal are Variables (Int, Bool, Float, Array..), Functions, Conditions (If-Else, Switches), Enums, try-catch…etc
The way we think about these tools, how we can use them is what steer us to write the solution the way we do.

So, reversing our understanding of the if-else flow forces our brain to think about the logic differently, I mean we now have one additional tool people!!

Ok so let’s apply the new tool to the previous exercise

func giveMeABeer(name: String, with age: Int) {
print("Hello!")
if age < 18 {
print("sorry you are not old enough to drink \(name)")
return
}
print("sure thing \(name)\n")
print("here you go 🍺. Cheers!")
}
/// now i have to include this version too dont i?
func giveMeABeer(name: String, with age: Int) {
print("Hello!")
if !canDrink(age) {
underAgeAlert(to: name)
return
}
okGiveBeer(to: name)
}

Without even thinking:

  • our code is much cleaner now (you will notice this in large projects)
  • the normal flow is kept at indention-zero.
    Reduced the ugly horizontal indentions that ‘else {}’ stick us with
  • we exited early (hah a bonus!)
  • code is more pleasant to read

Not convinced yet are you? Keep on reading

In 2014 Apple introduced Swift 1.0 which stands for clean, fast and efficient.
It had a particularly interesting mechanism called ‘guard’. The guard is simply a condition assertion check.
In plain English goes like this: ‘make sure the condition is valid otherwise return’

guard CONDITION_TO_MEET else { return }
...continue normally

which translates to in legacy if-else


if
!CONDITION_TO_MEET {
return
}
...continue normally

and if you are one of the people who think that swift rebranded if-else just because it can, then you try to interchange it without the return statement at the end, the compiler complains. “guard body must not fall through!”

Swift is slowly steering us away from the if-else conditions, so we use guard and early-exit instead. I gotta say, pretty sneaky of Apple. They are helping us write better code without even noticing.

This is another example of guard statement in Rust language

guard!(CONDITION 
else { return });
...continue normally

Summary

“else {}” served us so well along the years, but as humanity evolves problems have become more complex and our projects so huge that we have to find more adequate tools to solve them.

Reversing how we think about the if-else logic will help us get rid of else{} and show us that in most cases we don't need it after all.

Cheers 🍻

The below was added on August 28 2019

It was pointed out to me that it seemed like I was completely outcasting
‘else {}’ and that the Don’t use ‘else {}’ is kind of a harsh title.
It may be, but I wasn’t, at least not for every condition.

Yes the example provided may be considered too simple but it triggers a contrast difference and that’s all I need to pass along the argument.

Conditions are the core of programing language, and ‘if-else’ is obviously at its center. It goes the same for tertiaries or quaternary like ‘if elseif elseif else {}’ while matching more conditions. Sometimes you need them; that’s perfectly all right. All I am saying is that we should try to prioritize the use of ‘if-not-deviate’ over the legacy ‘if-else’ when it is possible because it promotes some great coding patterns.

One more thing, some of us don’t like exiting early, (I may dedicate an article for it but for now just a few thoughts) because it may promotes bugs, deminishes the one-entry-exit point pattern and you may end up with unpredictable code. Which is true for long functions and very complex algorithms, I mean you have to follow the flow right?
But when you; when possible, try to move away from long functions towards shorter ones that are single purpose-oriented, you will find yourself exiting early often because simply it makes more sense.

🍻

--

--