rfc:switch-expression-and-statement-improvement

PHP RFC: Switch Expression & Switch Statement Improvement

Introduction

The current design of PHP's switch statement follows closely languages such as C/C++ and supports fall-through semantics by default. The traditional switch statement is unnecessarily verbose which often leads to missing break statements mean that accidentally fall-through occurs. The idea of this RFC is to extend switch statement so it can be used as either a statement or an expression which can use simplified control flow behaviour and scoping similar to arrow functions.

Proposal

The motivation behind this proposal is to provide a simplified control flow and direct return value allowed to be used as an expression.

Following example shows how a switch statement can be unnecessarily verbose and how visual noise could lead to accidental fall-through occurs.

<?php
 
switch (date("w")) {
  case 0:
    $say = "weekend!";
    break;
  case 1:
  case 2:
  case 3:
  case 4:
  case 5:
    $say = "weekday :(";
    break;
  case 6:
    $say = "weekend!"
}
echo "Today is {$say}";

Switch Statement Improvement

The proposal is to reduce noise added by repeating separate case labels by grouping them in the comma-separated list.

Above example show how to group set of labels which takes the same expression block as an action in response to any label statement match.

<?php
 
switch (date("w")) {
  case 0:
    $say = "weekend!";
    break;
  case 1, 2, 3, 4, 5:
    $say = "weekday :(";
    break;
  case 6:
    $say = "weekend!";
}
echo "Today is {$say}";

Switch Expression Introduction

The proposal is to introduce a new form of switch label, written “case C ⇒” to signify that only the code to the right of the label is to be executed if the label is matched and in consequence value of that code should be the return value of switch expression.

Following example demonstrates noise and verbosity reduce.

<?php
 
$say = switch (date("w")) {
  case 0 => "weekend!";
  case 1, 2, 3, 4, 5 => "weekday :(";
  case 6 => "weekend!";
};
echo "Today is {$say}";
Note! Switch expression allows evaluating single expression just like the arrow function. This restriction can be relaxed in the future.

Return type

The switch expression errors with RuntimeException if return type given and there is a type mismatch.

<?php
 
$say = switch (date("w")): string {
  case 0 => "weekend!";
  case 1, 2, 3, 4, 5 => "weekday :(";
  case 6 => true; // This throws TypeError when resulting expression evaluates with different type
};
echo "Today is {$say}";

Non-completeness

The witch statement returning errors with RuntimeException if none of the labels evaluated on a match.

<?php
 
$kind = "baz";
$foo = switch ($kind): string {
  case "foo" => "matched 'foo'!";
  case "bar" => "matched 'bar'";
}; // This trows RuntimeException cause there is no default clause and whole expression is not complete

Backward Incompatible Changes

None.

Proposed PHP Version(s)

Targets next PHP 8.x.

RFC Impact

To SAPIs

None.

To Existing Extensions

None.

To Opcache

Would require opcache changes.

Future Scope

Splat operator

Grouping labels into a comma-separated list could benefit from splat operator replacing a bunch of labels.

<?php
 
$labels = ["foo", "bar"];
$kind = "bar";
 
switch ($kind) {
    case ...$labels:
        echo "matched 'foo' or 'bar', requires further manual verification";
        break;
}
 
echo switch ($kind) {
    case ...$labels => "matched 'foo' or 'bar', requires further manual verification";
};

Proposed Voting Choices

As this is a language change, a 2/3 majority is required.

The vote is a straight Yes/No vote for accepting the RFC and merging the patch.

Patches and Tests

Not implemented.

A volunteer to help with implementation would be desirable.

Implementation

References

rfc/switch-expression-and-statement-improvement.txt · Last modified: 2019/09/26 14:17 by brzuchal