Hi Kosit,

There's some really interesting ideas in here, thanks for sharing them.


On 19/10/2019 17:40, Kosit Supanyo wrote:
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


This feels like an odd restriction to me, and one that as far as I'm aware PHP doesn't have anywhere else. For instance, it might be considered bad style, but it's possible to use a ternary operator as an abbreviated if statement:

isset($_GET['logout']) ? $session->logout() : $session->extend();

Was this restriction added to make the implementation easier, or because you thought it was a useful feature?


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;
}


This is an interesting idea, given that switch(true) is the documented way to do this right now. However, I've always felt switch(true) was rather limited in its advantage over if-elseif. I would prefer a syntax that reduced the boilerplate for:

* Different comparisons applied to the same variable/expression, e.g. match($user->getScore()) { case <0 => foo(), case >100 => bar(), default => baz() } * Different values compared against the same expression using the same operator, e.g. match( $exception instanceOf ) { case FooException => handleFoo(), case BarException => handleBar() }



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"),
};


This seems confusing to me, because it mixes statements and expressions in a rather unusual way. The "return" case in particular seems ambiguous - if $v is visible outside the function, will it have a value assigned to it by the "return" branch, and if so what would that value be? I can imagine more use cases for the "throw" version, and it's reasonably obvious how it would behave, so it might be reasonable to have that one special case.



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


This is a very interesting feature, although I think what would be even more useful would be syntax to check if something _can_ be cast, i.e. the same check you have here, but as an operator evaluating to boolean.

That way, you could write code like this:

if ( <int>$_GET['id'] ) {
   $user = getUser($_GET['id']):
}
else {
   echo "Invalid ID provided";
}

Which would be equivalent (given a type hint on getUser() and no strict_types declaration) to this, but without needing to use exceptions as flow control:

try {
   getUser($_GET['id']);
}
catch ( TypeError $e ) {
   echo "Invalid ID provided";
}


Regards,

--
Rowan Tommins (né Collins)
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to