Readable Functions: Guard Clause

Guard Clauses are one of my favorite little tricks that allow simplifying code. A guard clause is an if statement with a return in it. Consider the following code:

Using a Guard Clause we can simplify it to:

The if statement in this simplified code is a Guard Clause. You can have multiple Guard Clauses in a function.

The simplification removes ALL the state in the function, including the nasty and completely not needed mutation in the first form of the code. You can read the new code sequentially, and the code after the Guard Clause is not polluted by extra complexity arising from the special case.

This post is part of the Readable Functions series which contains tricks like this one and two general principles: Minimize State and Do One Thing.

3 thoughts on “Readable Functions: Guard Clause”

  1. Actually, having multiple returns in a single function or method is bad practice.
    Furthermore, there is literally no gain from refactoring the code like this – at least in your example. You could simply omit the first line (var $thing = ‘default’; ) and instead add a null coalescing operator to the return statement (return $thing ?? ‘default’; ) and the result would be almost identical.

    But back to the actual problem: several return statements within a function/method are usually a clear indication that there is refactoring potential at that point.
    In practice, multiple return statements only occur in those functions/methods that have 30+ lines, which is definitely too much for one function. And then you quickly realise why this is a shitty idea: between all the statements and control structures, it’s easy to overlook a return; which makes the code harder to access for developers who are not familiar with it.

    But that doesn’t mean that guard clauses are bad per se; they are just often misunderstood. The idea behind guard clauses is not to get out of a function as early as possible, even if this seems reasonable in older PHP versions due to rather poor performance. Guard clauses are used to ensure the integrity of a function/method or an entire object instance.

    If a method expects a string as a parameter, but this string must be exactly 10 characters long, we cannot reflect this via the method signature. But with the help of a guard clause, we can check scalars for certain criteria and throw an exception immediately if these criteria are not met.

    That is why this concept is called “Guard Clause”, because it is supposed to GUARD the functions, attributes and objects against undesired states.

    1. Thanks for sharing your PoV.

      While there are a number of things in your reply I do not (fully) agree with, I suspect we would both write code the other things is OK.

      You are right that if you keep your functions small, you will typically not need multiple returns. And if your code contains a lot of functions with multiple returns, that might be a code smell. Personally this is not something I have consciously been looking at, but nevertheless still have been refactoring away by working on reduced state and complexity.

      As for Guard Clauses just guarding against invalid parameters: do you have some source for that? This is not how I have seen the term used. The off-site example linked in the post here (https://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html) also suggests otherwise.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.