Flattening the “Pyramid of Doom” in Swift with Custom Operators

Update: The solution in this post is effectively obsoleted by the guard statement available since Swift 2.

Swift 1.2 introduces a feature that allows us to condense nested if statements into a single one, eliminating the so-called “pyramid of doom”. However, there are still a few edge cases not covered by such an improvement, one of which appears in the Tiny Networking library by Chris Eidhof:

What prevents us from using a single if statement is the fact that there is a corresponding else after each if. In fact, this is a very common pattern in data serialisation and error handling, so we need a more elegant way to represent it.

Solution

We start out by defining an operator:

The rhs parameter of this operator is a closure that acts exactly like an else block—it will only be executed if lhs is nil. Here is an example:

The operator we defined, having higher precedence than the assignment operator, will be evaluated before assignment takes place. The implementation first checks lhs to decide whether the closure should be called or not. In the above example, the first string is unwrapped successfully, so its corresponding closure is not called. However, the second string is nil, which triggers the execution of its accompanying closure and causes the entire condition to fail.

Similarly, we can overload this operator to handle Boolean values:

We can even add the @autoclosure attribute to the rhs parameter so that you can pass in an expression without explicit curly braces around it:

Equipped with the new operator, we can now rewrite the code at the beginning of this article as follows. Note that you can chain expressions together with the operator to avoid using any curly braces, as shown in the where clause below:

As you can see, by defining a simple operator, we can completely flatten the “pyramid of doom” and make our code much more readable.

All code above is available in this gist.