- Published on
Pyramid of Doom
- Authors
- Name
- Misiel Rodriguez
- @misiel
What is the Pyramid Of Doom?
func pyramidOfDoom() {
if (user != null) {
// do something
if (user.name != null) {
// do something
if (user.status != null) {
// if...
//if...
//if...
//if... you get the gist
}
}
}
}
Wikipedia defines it as: a common problem that arises when a program uses many levels of nested indentation to control access to a function.
I ran into this problem recently at work when I was creating a helper function for a larger function, and saw that the code within the function created this nested visual pattern. I thought nothing of it since the code worked (junior dev mistake), but something just felt off. Why was the objective of my function nested within 3+ if statements?
A senior dev helped me realize the error of my ways when he pointed out the "Pyramid of Doom" concept to me. Through some simple guard clauses, I was able to declutter the visual mess and make my code look cleaner and more visually appealing, also just logically easier to read since a future reader wouldn't have to parse X amount of if-statements to see what the objective of the function is.
So what's the solution to this?
Well it's dependent on the language you're using. Being a previous Android dev using Kotlin, I would take the above code example and rewrite it like this:
fun pyramidOfDoom() {
if (user == null) return
// do stuff
}
This if (user == null) return
line is known as a guard clause. Instead of nesting logic within a block of code that begins with checking if the user is NOT null, we could just end our code early if the user IS null.
(This is a simple example without going too deep into Kotlin's "?." operator and other ways of null safety.)
But Swift also has it's own ways of null checking...
'If let'
func pyramidOfDoom(){
if let userName = user.name {
print("The user's name is \(userName)")
}
}
Through the usage of if let
, we're able to check if user.name
has a value and assign that value to a variable. Within the scope of the if let block, we know the value is not null and able to use it however way we want.
'Guard'
func pyramidOfDoom(){
guard let userName = user.name else { return }
print("The user's name is \(userName)")
}
guard
is another way of null safety in Swift and allows us to combat the "Pyramid of Doom". The difference between this and if let
is we now have a greater scope to use our non-null value. With if let
, the value is only non-null within the scope of the block. With guard, if the value is not null then we can use it throughout the whole function scope.
Thanks for reading!