'switch-expression' and the 'type guard' unary operator demo
| From: | Kosit Supanyo | Date: | Sat, 19 Oct 2019 16:40:56 +0000 |
| Subject: | 'switch-expression' and the 'type guard' unary operator demo | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-107580@lists.php.net to get a copy of this message | ||
Hi Internals
I've just finished an implementation of 'switch-expression' that have been
discussed recently. So I would like to present my ideas here.
The basic syntax of switch-expression in this implementation is:
$result = switch ($expr) {
case $cond1 => $result1,
case $cond2 => $result2,
case $cond3 => $result3,
default => $default_result,
};
Like function declaration and function expression in JavaScript, if
switch appears as first token at statement level it will be recognized as
statement but if switch is in expression context it will be
switch-expression.
switch ($expr) {
case $cond1 => $result1,
case $cond2 => $result2,
case $cond3 => $result3,
default => $default_result,
};
// Parse error: syntax error, unexpected '=>' (T_DOUBLE_ARROW)
But this is OK.
!switch ($expr) {
case $cond1 => $result1,
case $cond2 => $result2,
case $cond3 => $result3,
default => $default_result,
}; // semicolon is still required because it is an expression
You can also use comma to associate multiple conditions with single result
expression.
$result = switch ($expr) {
case $cond1 => $result1,
case $cond2 => $result2,
case $cond3, $cond4, $cond5 => $result3,
default => $default_result,
};
Which is equivalent to:
$result = switch ($expr) {
case $cond1 => $result1,
case $cond2 => $result2,
case $cond3 => $result3,
case $cond4 => $result3,
case $cond5 => $result3,
default => $default_result,
};
If there's no default value or switch-expression will just give NULL.
$x = 'c';
$v = switch ($x) {
case 'a' => 1,
case 'b' => 2,
};
var_dump($v); // NULL
Empty switch-expression is also allowed.
$v = switch ($x) {
};
var_dump($v); // NULL
You can omit parenthesized expression which is shortcut to switch (true).
This change applies to switch statement as well.
$v = switch {
case $x >= 0 && $x <= 100 => 1,
case $x >= 100 && $x <= 200 => 2,
default => 3,
};
switch {
case $x >= 0 && $x <= 100:
doSomething1();
break;
case $x >= 100 && $x <= 200:
doSomething2();
break;
default:
doNothing();
break;
}
You can also use return and throw in result expression. I recalled some
languages have this feature (but I've forgotten what language). This
feature can be very handy and useful in many use cases.
$x = 'd';
$v = switch ($x) {
case 'a' => 1,
case 'b' => 2,
case 'c' => return true,
default => throw new Exception("'$x' is not supported"),
};
Additional feature in the demo patch is the 'type guard' unary operator
which is an operator that will perform type check on given value and throw
TypeError when type mismatch occurred, otherwise return the value as is.
It has the same precedence as new.
$a = 'This is a string';
$v = <int>$a; // TypeError: Value is expected to be int, string given
Just like type hints, can accept nullable types.
$v = <?int>switch ($x) {
case 'a' => $result1,
case 'b' => $result2,
};
Also works with variable references.
$x = &<int>$a;
$y = &<callable>$functions[$name];
$arr = [&<Countable>$obj];
This operator can also be used to simulate typed variables.
The demo is here:
https://github.com/webdevxp/php-src
P.S. This is just a bunch of ideas with concrete demo, not intended to be
pull request nor proposal because I think I'm still new here and
inexperienced in many other ways.
Cheers