Why Swift guard Should Be Avoided

Alexey Kuznetsov
Dec 22, 2015 · 3 min read

A lot has been told about the guard statement since its appearance in Swift. Indeed, it simplifies code and makes it more readable. But is guard really a silver bullet?

Small Functions

The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that. — Robert C. Martin, Clean Code book

More specifically, Robert C. Martin recommends keeping functions not more than six lines long and definitely not more than ten lines.

Following this simple rule makes magic. The code suddenly becomes more understandable. What previously was a thirty-line function with several indentation levels and intermediate variables that had to be kept in the head is now ten functions, each having a self-documenting specific name.

Single Responsibility

Yet this is violated over and over again. The function size seems to play the major role here. So if a thirty-line function is refactored to be ten three-line functions, the following of the single responsibility principle on the function level is automatically improved.

One Level of Abstraction

What does it mean? In short, high-level code, like controlling the whole process, shouldn’t be mixed with small details, like variable increments or Boolean checks.

Example

Of course, the vend(itemNamed:) function is just an example of using the guard statement but one can often see similar functions in the production code. This function has all three problems described above.

  1. It is pretty long, sixteen lines, multiple parts separated by empty lines.
  2. It does several things. It gets an item by name, validates parameters, and it implements the logic of vending an item.
  3. It has several abstraction levels. The high-level vending process is hidden among the finer-level details like Boolean checks, usage of specific constants, math operations, etc.

How could the function look like after refactoring?

The total number of lines increased, but it should not be forgotten that the number of lines is not an end in itself. The refactored code provides a number of benefits compared to the old one.

  1. The main vending function is now short and contains only high-level steps of vending an item. If the reader is not interested in the details, she can understand the vending process by quickly looking at this high-level function.
  2. The functions have more respect for the single responsibility principle. Some of them could be broken down even further, but even in their current form, each one is more understandable and readable. They separate the old bigger chunk of code into smaller, self-documenting pieces.
  3. Each function operates on a single level of abstraction. The reader can easily move between these levels as needed. How does the vending process look like? The item is determined by name and validated, the deposit is reduced, the item is removed from the inventory, and dispensed. How the item is validated? The count and the price are checked. How exactly the count is checked? The count is compared to zero. If small details don’t interest the reader, they can always be skipped.

Conclusion

Related Articles

Swift Programming

The Swift Programming Language

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store