'switch-expression' and the 'type guard' unary operator demo

From: 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

« previous php.internals (#107580) next »