Re: [PHP-DEV] [RFC] switch expression

This is only part of a thread. view whole thread
  109296
March 25, 2020 15:46 larry@garfieldtech.com ("Larry Garfield")
On Wed, Mar 25, 2020, at 10:29 AM, Ilija Tovilo wrote:
> Thanks for your feedback, Larry! > > > One possible improvement to either version is allowing an expression on the left side. That is, rather than doing an equality match, do a boolean match. > > This is how Rust does it: > > ```rust > let x = match ... { > Some(y) if y < 5 => ... > } > ``` > > In other words, you can add an additional guard to each case that > excepts any expression. We don't really benefit a lot from that since > we don't have pattern matching. I don't think this would add any > significant benefit over: > > ```php > $x = true switch { > $x !== null && $x < 5 => ... > } > ```
Good point, I'd forgotten about that potential trick. So as long as an expression is allowed on the left, rather than just a literal, which is then == compared against the provided value, that should be "good enough" for most use cases. The implementation should include some tests to make sure that works properly, but I'm happy with the resulting syntax. So then the net result is: $var = switch($val) { case expr1 => expr2; } Where $val gets compared against the result of each expr1, and if true then $var is set to expr2. Endorse. --Larry Garfield
  109297
March 25, 2020 16:06 php@dennis.birkholz.biz (Dennis Birkholz)
Hello together,

Am 25.03.20 um 16:46 schrieb Larry Garfield:
> On Wed, Mar 25, 2020, at 10:29 AM, Ilija Tovilo wrote: >> Thanks for your feedback, Larry! >> >>> One possible improvement to either version is allowing an expression on the left side. That is, rather than doing an equality match, do a boolean match. >> >> This is how Rust does it: >> >> ```rust >> let x = match ... { >> Some(y) if y < 5 => ... >> } >> ``` >> >> In other words, you can add an additional guard to each case that >> excepts any expression. We don't really benefit a lot from that since >> we don't have pattern matching. I don't think this would add any >> significant benefit over: >> >> ```php >> $x = true switch { >> $x !== null && $x < 5 => ... >> } >> ``` > > Good point, I'd forgotten about that potential trick. So as long as an expression is allowed on the left, rather than just a literal, which is then == compared against the provided value, that should be "good enough" for most use cases. > > The implementation should include some tests to make sure that works properly, but I'm happy with the resulting syntax. > > So then the net result is: > > $var = switch($val) { > case expr1 => expr2; > } > > Where $val gets compared against the result of each expr1, and if true then $var is set to expr2.
on the first glance this all looks nice but you actually created something more like an if-expression that uses switch as a keyword because you stripped switch of some of its major features: - you compare the given value to possible cases -> you compare expressions to true - you can fall through to other cases without break - what about the default case? What about the following if-expression-syntax: $var = if ($x > 0) { return 1; } elseif ($x < 0) { return -1; } else { return 0; } Maybe this is more in line of what you want to do with your switch expression? Greets Dennis
  109300
March 25, 2020 16:22 ilija.tovilo@me.com (Ilija Tovilo)
Hi Dennis

Thanks for your feedback!

> you can fall through to other cases without break
You could do the same using the || operator.
> what about the default case?
I haven't described the default case in my proposal but it is exactly what you'd expect it to be: ```php $var = true switch { $x > 0 => 1, $x < 0 => -1, default => 0, }; ```
> What about the following if-expression-syntax:
That would work (once again, Rust already does it) though not with the return keyword. We'd still need a block expression to pass the value from the block to the if expression. When I compare the two I definitely think the match expression is more readable. Regards
  109303
March 25, 2020 16:51 cmbecker69@gmx.de ("Christoph M. Becker")
On 25.03.2020 at 17:06, Dennis Birkholz wrote:
> Hello together, > > Am 25.03.20 um 16:46 schrieb Larry Garfield: >> On Wed, Mar 25, 2020, at 10:29 AM, Ilija Tovilo wrote: >>> Thanks for your feedback, Larry! >>> >>>> One possible improvement to either version is allowing an expression on the left side. That is, rather than doing an equality match, do a boolean match. >>> >>> This is how Rust does it: >>> >>> ```rust >>> let x = match ... { >>> Some(y) if y < 5 => ... >>> } >>> ``` >>> >>> In other words, you can add an additional guard to each case that >>> excepts any expression. We don't really benefit a lot from that since >>> we don't have pattern matching. I don't think this would add any >>> significant benefit over: >>> >>> ```php >>> $x = true switch { >>> $x !== null && $x < 5 => ... >>> } >>> ``` >> >> Good point, I'd forgotten about that potential trick. So as long as an expression is allowed on the left, rather than just a literal, which is then == compared against the provided value, that should be "good enough" for most use cases. >> >> The implementation should include some tests to make sure that works properly, but I'm happy with the resulting syntax. >> >> So then the net result is: >> >> $var = switch($val) { >> case expr1 => expr2; >> } >> >> Where $val gets compared against the result of each expr1, and if true then $var is set to expr2. > > on the first glance this all looks nice but you actually created > something more like an if-expression that uses switch as a keyword > because you stripped switch of some of its major features: > - you compare the given value to possible cases -> you compare > expressions to true > - you can fall through to other cases without break > - what about the default case? > > What about the following if-expression-syntax: > > $var = if ($x > 0) { return 1; } > elseif ($x < 0) { return -1; } > else { return 0; } > > Maybe this is more in line of what you want to do with your switch > expression?
Or maybe even $var = $x > 0 ? 1 :($x < 0 ? -1 : 0); Yes, the required parentheses are ugly, but in my opinion, this is still better than a new if or switch(true) expression construct. -- Christoph M. Becker