[RFC][POLL] Switch expression

php.internals

Ilija Tovilo

6 years ago
Hi internals A few days ago I opened the discussion on the switch expression RFC: https://wiki.php.net/rfc/switch_expression There's been a fundamental disagreement on what the switch expression should actually be. Due to the conflicting feedback I no longer know how to proceed. This is why I've created a poll to get a general feeling of what approach is preferred. If you can vote, **please**, vote. https://wiki.php.net/rfc/poll_switch_expression Ilija

David Rodrigues

6 years ago
In relation to "Some people have asked why we don't reuse the syntax of the switch statement". I do not think that it could cause a conflict with an array. The same is valid for anonymous functions or classes: you need use terminator (";"). I still prefer it than create another format to switch. And maybe you should just use "return" here to specify the return value. $x = switch ($y) { case 1: return $y + 1; case 2: return $y - 1; // default: return null; }; Atenciosamente, David Rodrigues Em ter., 31 de mar. de 2020 às 15:51, Ilija Tovilo <tovilo.ilija@gmail.com> escreveu:

Unnamed Person

6 years ago
On Tue, Mar 31, 2020 at 12:51 PM Ilija Tovilo <tovilo.ilija@gmail.com> wrote:
> > Hi internals > > A few days ago I opened the discussion on the switch expression RFC: > https://wiki.php.net/rfc/switch_expression > > There's been a fundamental disagreement on what the switch expression > should actually be. Due to the conflicting feedback I no longer know > how to proceed. This is why I've created a poll to get a general > feeling of what approach is preferred. If you can vote, **please**, > vote. > > https://wiki.php.net/rfc/poll_switch_expression > > Ilija > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >
To be clear, you actually could reuse the switch keyword for an expression: $x = switch ($y) {/* ... */ }; It's a bit tedious to do but it's not ambiguous. I did a similar thing in the past when working on short closures. I tried using `{$x => $x *2}` for the syntax and had to disambiguate with an empty block (which serves no purpose in PHP). I can't find the branch/patch anymore, which is unfortunate, but it is doable if you are determined.

Ilija Tovilo

6 years ago
Hi internals After Levis email yesterday we discussed his suggestions in private. I did some investigation and did find a way to reuse the current switch syntax. The main problem of the ambiguity was the empty switch statement vs expression: ``` // Could be a switch expression or a switch statement with an empty statement (;) switch ($x) {}; ``` Disallowing the switch expression to be empty solves the ambiguity. ``` // This code throws a parser error $x = switch ($y) {}; ``` It's not optimal but everything else will require significant changes in the grammar and have other downsides. I updated the RFC accordingly. Ilija

Rowan Collins

6 years ago
On 31 March 2020 19:50:59 BST, Ilija Tovilo <tovilo.ilija@gmail.com> wrote:
>There's been a fundamental disagreement on what the switch expression >should actually be. Due to the conflicting feedback I no longer know >how to proceed.
I think this confusion is there in your proposal, not just in people's responses to it. In the new poll, you say this:
> The question seems to be if this new construct > should be a variation of the switch to make it > usable as an expression (like the RFC currently > suggests)
But the introduction of the actual RFC doesn't even mention the expression part, only that you want to solve some of the problems of the current statement:
> The switch statement has some long-standing > issues that we're going to look at in this RFC.
You then go onto describe 4 problems, and propose a new syntax that solves 3 of them, with only the type coercion part retaining the switch statement's behaviour. I don't think people are saying they *want* the proposal to be more of "an alternative to the switch statement that fixes all the issues mentioned in the RFC", they're saying that what you've currently proposed *is* that replacement. If that's the intention, using a new keyword would make sense. If the intention is to make this feel like an expression version of the switch statement, then making it look more similar would make sense. I think it's ultimately up to you which direction you want to take the proposal, but you should pick one and follow it through. Personally, I think changing the keyword to "match", and possibly using strict comparison, would make a compelling feature. I don't think this part would be needed or desirable:
> Each case can contain a single expression, or a > block with a statement list if the expression > result is discarded
I think it's perfectly fine to have a match expression that's built only from expressions. If someone wants flow control, they can use other features, the new syntax doesn't need to do everything. Regards, Hi Ilija,
-- Rowan Tommins [IMSoP]

Rowan Collins

6 years ago
On 01/04/2020 09:56, Rowan Tommins wrote:
> If the intention is to make this feel like an expression version of the switch statement, then making it look more similar would make sense.
To expand on this a bit, if the aim is "a switch statement, but usable as an expression", then it would make sense to start with an identical syntax, and make only those changes needed to meet that aim. So, given the following example from the RFC: switch ($x) {     case 0:         $y = 'Foo';         break;     case 1:         $y = 'Bar';         break;     case 2:         $y = 'Baz';         break; } The starting point would be to move the assignments and nothing else: $y = switch ($x) {     case 0:         'Foo';         break;     case 1:         'Bar';         break;     case 2:         'Baz';         break; } That looks a little odd, because the result expressions are formatted as statements, so we could maybe combine them with the break keyword: $y = switch ($x) {     case 0:         break 'Foo';     case 1:         break 'Bar';     case 2:         break 'Baz'; } We could then bikeshed whether to swap out "break" for "return" or "yield", but the result would look and act like an expression version of the switch statement. It could even have other statements between the "case" and "break" lines, and all the normal fallthrough behaviour. The other issues discussed in your RFC - fallthrough, inexhaustiveness, type coercion - are valuable things to discuss, but each one takes this further away from being a "switch expression", and into being "a new value-matching expression". As I said in my last e-mail, I don't think that's a bad thing; I really like the proposed syntax, as a new construct for picking one of a set of expressions, and would be happy to see the RFC re-focussed in that direction. Regards,
-- Rowan Tommins (né Collins) [IMSoP]

Ilija Tovilo

6 years ago
Hi Rowan I agree that the structure of the RFC is sub optimal. Honestly, I've rewritten and moved things at least 5 times and it's still not good. I'll see how I can improve it.
> so we could maybe combine them with the break keyword: > > $y = switch ($x) { > case 0: > break 'Foo'; > case 1: > break 'Bar'; > case 2: > break 'Baz'; > }
We can't really do that since break already accepts an integer telling it how many enclosing structures it should jump out of.
> The other issues discussed in your RFC - fallthrough, inexhaustiveness, > type coercion - are valuable things to discuss, but each one takes this > further away from being a "switch expression", and into being "a new > value-matching expression". As I said in my last e-mail, I don't think > that's a bad thing; I really like the proposed syntax, as a new > construct for picking one of a set of expressions, and would be happy to > see the RFC re-focussed in that direction.
Yes, I can absolutely see your point. The point of the poll is to see what direction we should take. After that I'll try to clean up the RFC. Thanks! Ilija

Rowan Collins

6 years ago
On 01/04/2020 12:19, Ilija Tovilo wrote:
> We can't really do that since break already accepts an integer telling > it how many enclosing structures it should jump out of.
Sure, but we could use "return", or some other keyword. My point was that the syntax could look a lot closer to a switch statement if that was the aim. I think I like your existing syntax proposal better on its own merit, it just doesn't look anything like a switch statement, so I'd pick a new keyword like "match" or "select".
> Yes, I can absolutely see your point. The point of the poll is to see > what direction we should take. After that I'll try to clean up the > RFC.
I don't have karma to vote, but if I did, my answer to your poll would be "something else". I don't see "match" (or whatever we decide to call it) as a replacement for switch, or as a version of it. It would replace some uses of switch, just as switch replaces some uses of elseif, but in some ways it would be more related to the ternary operator - an expression with branches for different conditions, not a form of flow control. Regards,
-- Rowan Tommins (né Collins) [IMSoP]