2

Sometimes it is a good idea to have a guard block:

Guard block guards against special cases.

GetFiletype(Ext)
{
    ; Guard block
    If (!Ext || Ext != "txt" && Ext != "md")
        Return "Not supported file type"

    ; Processing block
    If (Ext = "txt")
        Return "Plain text"
    Else
        Return "Markdown"
}

However, this code could be written in another way:

GetFiletype(Ext)
{
    ; Processing block
    If (Ext = "txt")
        Return "Plain text"
    Else If (Ext = "md")
        Return "Markdown"

    ; Does this part have a name?
    Else
        Return "Not supported file type"
}

As you see, the guard block was moved to the bottom, and therefore, it will be silly and incorrect to call it "guard" now.

Does this part have a name, something like "antiguard" or "fire exit"?

7
  • 1
    You've both reversed the senses of the conditionals (and the order of the code) as well as introducing another else clause. So, there's at least two more ways to write this! ... +1 for fire exit!
    – Erik Eidt
    Commented Sep 12, 2019 at 19:44
  • 4
    I'd call it a "default case". Your second example is just a sequential case statement with the default case at the bottom. Commented Sep 12, 2019 at 21:02
  • @ErikEidt Could you show the two ways you have mentioned? For example, post it on Pastebin?
    – john c. j.
    Commented Sep 12, 2019 at 21:39
  • 2
    The second version is not equivalent, it no longer handles !Ext (or else the first version is needlessly verbose)
    – Ben Voigt
    Commented Sep 12, 2019 at 21:45
  • 2
    For one, take 2nd code change Else If to just If, and remove the remaining Else (and dedent its block). (an else is unnecessary when then-part of if-statement ends with return (or break or continue or goto)) For another, take the first one and introduce Else for the If that doesn't have one!
    – Erik Eidt
    Commented Sep 12, 2019 at 21:55

1 Answer 1

2

As per [Wikipedia], "...a guard is a boolean expression that must evaluate to true if the program execution is to continue in the branch in question...".

So in your first example code, you have a default value that the function will return, "Markdown". And you have two guards, that will return "Not supported file type" or "Plain text" if those guards are met.

In your second example, you have switched those default and guard values around. You still have guards, but they now handle "happy path" results rather than the error state.

But as that same article mentions, the terms "guard code"/"guard clause"/"guard block" are commonly used to describe a guard that protects against errors, such as an unsupported file type in your example. So by moving the "Not supported file type" code out of a guard and to the default path, you no longer have a guard clause as you correctly say.

As to what to therefore call it, guard clauses are preconditions, so I'd refer to putting a default value to protect against errors at the end of the function as a postcondition. No guard is needed for that postcondition; it simply mops up a failure at the end.

As an addendum to this, there's two further points about your code examples that others touch on in comments that are worth mentioning here for completion.

Firstly, be aware that your two code examples aren't equivalent as the second version doesn't explicitly handle !Ext as your first example does. You avoid duplicating tests of Ext in the second example, but you lose that !Ext check. Depending on the language, this might affect the behaviour of the code.

Secondly, the Else's are redundant in your code: you are creating unnecessary branches. So your two examples can be expressed as:

GetFiletype(Ext)
{
    if (!Ext || Ext != "txt" && Ext != "md")
        Return "Not supported file type"

    If (Ext = "txt")
        Return "Plain text"

    Return "Markdown"
}

GetFiletype(Ext)
{
    If (Ext = "txt")
        Return "Plain text"

    If (Ext = "md")
        Return "Markdown"

    Return "Not supported file type"
}

It then becomes clearer that the code is just a succession of guards with a default result at the end in each case.

Not the answer you're looking for? Browse other questions tagged or ask your own question.