The Pyramid Of Doom In Swift

If you are using a lot of nested indentations, your code becomes rapidly unclear – the pyramid of doom. You can avoid this by using the keyword guard.

The Pyramid Of Doom

Let’s start by looking at an example. We are creating a function that calculates the area of a circle:

enum CircleAreaCalculationError: ErrorType {
    case RadiusNotSpecified
    case RadiusUnvalid
    
}

func calculateCirlceArea(radius:Double?) throws -> Double {
    
    if let radius = radius {
        if  radius > 0 {
            return radius*radius*M_PI
        } else {
            throw CircleAreaCalculationError.RadiusUnvalid
        }
    } else {
        throw CircleAreaCalculationError.RadiusNotSpecified
    }
    
}

It is just a very simple example, but it is already very difficult to see what is happening. If the parameter is equal to nil, the CircleAreaCalculationError.RadiusUnvalid error will be thrown. Furthermore, if the radius is not bigger than 0, the CircleAreaCalculationError.RadiusNotSpecified will be thrown. You can easily imagine how much more difficult the code will be to read, if you are programming a more complex problem.

guard

guard was introduced in Swift 2.0 and it is very powerful. guard checks whether a certain condition holds true or not. If it doesn’t, you have to leave the current context. So let’s change our code:

enum CircleAreaCalculationError: ErrorType {
    case RadiusNotSpecified
    case RadiusUnvalid
}

func calculateCirleArea(radius:Double?) throws -> Double {
    
    guard let radius = radius else {
        throw CircleAreaCalculationError.RadiusNotSpecified
    }
    
    guard radius > 0 else {
        throw CircleAreaCalculationError.RadiusUnvalid
    }
    
    return radius*radius*M_PI
    
}

I my opinion this is much easier to read. Contrary to the example without guard, the errors are thrown immediately one line after the check and not after a very long if block. Moreover, the optional radius becomes a non optional after the nil check, which makes things a lot easier.

[thrive_text_block color=”blue” headline=”Conclusion”]On the first sight guard seems to be like a very small new feature in Swift 2.0, but it is in fact one of the most important new features in Swift 2.0. [/thrive_text_block]

References

Swift 2: guard
Wikipedia
Swift 2.0: Why Guard is Better than If
Image: @ Dudarev Mikhail / shutterstock.com

2 comments

  1. I get the idea why guard is a good option to avoid the pyramid of doom. But, the example… can be better. Why are you guarding an optional Double ? Ask for a Double so the compiler can check that for you.

    1. Well, I think it is possible that the method will be called in a context where it is possible that the radius is an optional. So it is better that the method itself handles that for you and not the caller of the method. And he has to catch errors anyway.

Comments are closed.