rfc:guard_statement

Guard statement

Introduction

Defensive programming is set of practices that widely used in software-engineering and also in PHP community. One of the techniques from it, guarded code or precondition, is mature and proven to be effective in structuring programs. This RFC introduces new statement that improves writing guarded code.

More about the topic:

Proposal

Guard statement is control-flow type statement that executes code in a body only if expression equals false. Body of statement must contain code that changes control flow: return, throw, goto. Also, in a loop context, you can use break or continue.

guard (condition) else {
    //this code executed only if condition equals false
    return|throw|goto;
    //or
    continue | break(in loop context only);
}
 
// in loop context - valid code
while (condition){
   guard (condition) else {
       break; //valid
   }
}

If compiler doesn't find any of those statements, it will search selection type statements(if with else|try/catch/finally|switch) and ensures that every element of these statements contains return, throw, goto.

//correct
guard (condition) else {
    if(another condition) {
        return;
    } else {
        throw new \LogicException();
    }
}
 
//incorrect
guard(condition) else {
   if(another condition) {
       return;
   }
}
 
//correct
guard (condition) else {
    try {
        //some code
        return;
    } catch(\Throwable $e) {
        throw new \LogicException();
    }
}
 
//correct 
guard (condition) else {
    try {
        //some code
    } catch(\Throwable $e) {
        throw new \LogicException();
    }
    return;
}

Otherwise, it will cause compile error. Syntax guarantees that statement will change scope of execution.

Syntax and other languages

Syntax almost the same as from Swift https://docs.swift.org/swift-book/ReferenceManual/Statements.html#grammar_if-statement

    guard condition else {
        statements
    }

Else keyword after expression helps to point that code will execute only if condition equals false. Similar statements:

Benefits

  • Improving readability. It will become easier to distinguish precondition blocks from generic if blocks.
  • Error pruning. Currently, to write preconditions, it often needed to negate expression to make early return. It is easy to forget insert ! before. And this kind of mistakes you cannot catch with static analyses tools. With guard statement it will become more natural and simpler to write this kind of code and make less mistakes.
  • Encourages Defensive programming design

Backward Incompatible Changes

Guard become reserved keyword, so it cannot be used in function/class/etc name. It will break userland code such as Laravel However, I think it is ok to make BC break for several reasons:

rfc/guard_statement.txt · Last modified: 2020/05/17 13:47 by alherd