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