rfc:conditional_break_continue_return

This is an old revision of the document!


PHP RFC: Your Title Here

This is a suggested template for PHP Request for Comments (RFCs). Change this template to suit your RFC. Not all RFCs need to be tightly specified. Not all RFCs need all the sections below. Read https://wiki.php.net/rfc/howto carefully!

Quoting Rasmus:

PHP is and should remain:
1) a pragmatic web-focused language
2) a loosely typed language
3) a language which caters to the skill-levels and platforms of a wide range of users

Your RFC should move PHP forward following his vision. As said by Zeev Suraski “Consider only features which have significant traction to a large chunk of our userbase, and not something that could be useful in some extremely specialized edge cases [...] Make sure you think about the full context, the huge audience out there, the consequences of making the learning curve steeper with every new feature, and the scope of the goodness that those new features bring.”

Introduction

This proposal is a syntatical addition that allows `break`, `continue` and `return` to be conditionally qualified. Two variations are possible (depending on which, if either are desirable to have.)

Option #1 with optional return value at end of statement:

<code php>

  function divide($dividend, $divisor = null) {
      return if ($divisor === null || $divisor === 0);
      // or
      return if ($divisor === null || $divisor === 0): 0;
      return $dividend / $divisor;
  } 

</code php>

Option #2 with optional return after return keyword:

<code php>

  function divide($dividend, $divisor = null) {
      return if ($divisor === null || $divisor === 0);
      // or
      return 0 if ($divisor === null || $divisor === 0);
      return $dividend / $divisor;
  } 

</code php>

Proposal

The general concept comes from the idea of a guard clause. (Also sometimes called “short circuiting”, or even simply “returning early”.)

In short [I perceive], a benefit of using guard clauses is to avoid deeply nested conditionals and to avoid increasing cognitive complexity in a function or method. Utilizing this technique in code results in code that is more easily code reviewable and easier to determine possible code paths that exists from the top to the bottom of a function or method.

Over the past few years, I've seen a growing number of blog posts, conference talks, and even tooling (for example code complexity scoring), that suggest writing guard clauses is a good practice to utilize. I've also seen it more prevalent in code, and even attempts at achieving this with Exceptions (in an HTTP context) in a framework like Laravel.

see abort_if/throw_if: https://laravel.com/docs/7.x/helpers#method-abort-if

It is also worth mentioning that Ruby has similar features (called a modifier), and I believe they are heavily utilized:

see: https://github.com/rubocop-hq/ruby-style-guide#no-nested-conditionals

Variation #1

My personal favorite is this variation (in it's full statement form):

<code php> return if ($condition): $returnValue; </code php>

Pros: 1. `return if` acts as a compound keyword, put another way since `if` must follow `return`, their proximity acts just like a new singular keyword would. It would effectively be a singular visual cue (much like, for example `return_if` if it were proposed). 2. In the most common coding standards, `return if` will be aligned to the left most side of a line of code, making it easier for (humans) to scan for and quickly identify. 3. (Building on the #2 Pro...) It keeps the precedence of information about the statement in a prioritized order. Put another way, since the first 2 lexical tokens are constant, and a meaning for the full statement can be derived from those, the following information (the actual condition and the actual optional return value - which I argue have less precedence) can be found later in the statement. 4. the optional return value syntax mimics that of the function/method return type hint syntax, as in at the end of a method signature in the `: <return>` format.

Cons: 1. Does not read like an “English-like” statement: “Return X if Y”

Variation #2

I am also fond of this variation which is commonly asked for (to be fair I like it to a slightly lesser degree than #1):

<code php> return $returnValue if ($condition); </code php>

Pros: 1. Reads well “Return subject if condition” 2. Follows a similar pattern as found in other languages, like Ruby

Con: 1. Large optional return values will create more space between the `return` and `if` keywords, potentially making it harder for (humans) to scan for the conditional qualifier.

Backward Incompatible Changes

No BC issues.

Proposed PHP Version(s)

PHP 8

RFC Impact

To Opcache

Unknown, under discussion.

Proposed Voting Choices

Include these so readers know where you are heading and can discuss the proposed voting options.

Patches, Tests, Implementation

References

The recently contributed Guard RFC

rfc/conditional_break_continue_return.1589656348.txt.gz · Last modified: 2020/05/16 19:12 by ralphschindler