Empty subject in match and switch constructions

php.internals

Dmitry Derepko

1 year ago
Hi! I’m thinking about making match (true) and switch (true) be more lightweight by removing the subject “(true)” and making matching “true condition” by default. So $var = match (true) { … } can be used as $var = match { … }. It’s often used in Kotlin. Pretty convenient way to use combined conditions. It’s natively understandable because there should be a condition: $result = match { $x < $n => …, $x > $n => …, else => …, } The same explanation for switch construction, but in Kotlin it’s the same construction “when": val result = when { x < n -> … x > n -> … else -> … } var result = null when { x < n -> { result = … } x > n -> { result = … } else -> return } https://kotlinlang.org/docs/control-flow.html#when-expressions-and-statements Conditions and loops kotlinlang.org `when` construction is overwhelming, but some features are totally handy, such as checking for class of the subject: when (obj) { is Class1 -> … is Class2 -> … else -> ... } Which was implemented by Ilija Tovilo in: https://github.com/php/php-src/compare/master...iluuu1994:pattern-matching By the way, what do you think about allowing to drop the subject of match / switch as a first iteration? Maybe would be better to ask Ilija to recreate his PR? ---------- Best regards, Dmitrii Derepko. @xepozz

Ilija Tovilo

1 year ago
Hi Dmitrii On Sun, Feb 2, 2025 at 1:05 PM Dmitry Derepko <xepozzd@gmail.com> wrote:
> > I’m thinking about making match (true) and switch (true) be more lightweight by removing the subject “(true)” and making matching “true condition” by default. > So $var = match (true) { … } can be used as $var = match { … }.
There's an old RFC draft for this that never went anywhere. I believe the feedback was mixed, but there's no way to know how it would have turned out since it never went into voting. Given it's inactive, it should be ok for you to take over. https://wiki.php.net/rfc/short-match https://externals.io/message/112496
> `when` construction is overwhelming, but some features are totally handy, such as checking for class of the subject: > when (obj) { > is Class1 -> … > is Class2 -> … > else -> ... > } > > Which was implemented by Ilija Tovilo in: https://github.com/php/php-src/compare/master...iluuu1994:pattern-matching
This is a really old draft. The RFC itself is mostly up to date. The implementation is still WIP. https://wiki.php.net/rfc/pattern-matching Ilija

Larry Garfield

1 year ago
On Sun, Feb 2, 2025, at 7:40 AM, Ilija Tovilo wrote:
> Hi Dmitrii > > On Sun, Feb 2, 2025 at 1:05 PM Dmitry Derepko <xepozzd@gmail.com> wrote: >> >> I’m thinking about making match (true) and switch (true) be more lightweight by removing the subject “(true)” and making matching “true condition” by default. >> So $var = match (true) { … } can be used as $var = match { … }. > > There's an old RFC draft for this that never went anywhere. I believe > the feedback was mixed, but there's no way to know how it would have > turned out since it never went into voting. Given it's inactive, it > should be ok for you to take over. > > https://wiki.php.net/rfc/short-match > https://externals.io/message/112496
Hi, author of that RFC here. Although there seemed to be interest for it in the initial match() discussion, the stand-alone follow up was met with a giant "meh", which is why I didn't pursue it further. I would still be in favor of it, though, if it could get through internals. I'm happy to have someone pick it up and run with it, or collaborate on rebooting that RFC. (I'm pretty sure the patch for it actually worked, at least it did at the time.) --Larry Garfield

Dmitry Derepko

1 year ago
Hi, Larry!
> On Feb 3, 2025, at 10:01 AM, Larry Garfield <larry@garfieldtech.com> wrote: > > On Sun, Feb 2, 2025, at 7:40 AM, Ilija Tovilo wrote: >> Hi Dmitrii >> >> On Sun, Feb 2, 2025 at 1:05 PM Dmitry Derepko <xepozzd@gmail.com> wrote: >> >> https://wiki.php.net/rfc/short-match >> https://externals.io/message/112496 > > Hi, author of that RFC here. Although there seemed to be interest for it in the initial match() discussion, the stand-alone follow up was met with a giant "meh", which is why I didn't pursue it further. I would still be in favor of it, though, if it could get through internals. I'm happy to have someone pick it up and run with it, or collaborate on rebooting that RFC. (I'm pretty sure the patch for it actually worked, at least it did at the time.) > > --Larry Garfield
It looks funny that I’m following in your steps with the RFC’s didn’t go through 😃 By the way, I’ve implemented empty match subject in a bit different way: https://github.com/php/php-src/pull/17692 About the RFC. What’s the way to re-activate it? Will you re-activate it? Do I need to create a new one referencing to this one? Can you share rights to edit the RFC and we can push it further together? ---------- Best regards, Dmitrii Derepko. @xepozz

Claude Pache

1 year ago
> Le 4 févr. 2025 à 08:43, Dmitry Derepko <xepozzd@gmail.com> a écrit : > > Hi, Larry! > >> On Feb 3, 2025, at 10:01 AM, Larry Garfield <larry@garfieldtech.com> wrote: >> >> On Sun, Feb 2, 2025, at 7:40 AM, Ilija Tovilo wrote: >>> Hi Dmitrii >>> >>> On Sun, Feb 2, 2025 at 1:05 PM Dmitry Derepko <xepozzd@gmail.com> wrote: >>> >>> https://wiki.php.net/rfc/short-match >>> https://externals.io/message/112496 >> >> Hi, author of that RFC here. Although there seemed to be interest for it in the initial match() discussion, the stand-alone follow up was met with a giant "meh", which is why I didn't pursue it further. I would still be in favor of it, though, if it could get through internals. I'm happy to have someone pick it up and run with it, or collaborate on rebooting that RFC. (I'm pretty sure the patch for it actually worked, at least it did at the time.) >> >> --Larry Garfield > > > It looks funny that I’m following in your steps with the RFC’s didn’t go through 😃 > > By the way, I’ve implemented empty match subject in a bit different way: https://github.com/php/php-src/pull/17692 > > About the RFC. What’s the way to re-activate it? > Will you re-activate it? > Do I need to create a new one referencing to this one? > Can you share rights to edit the RFC and we can push it further together?
Hi, One issue to resolve is how to interpret: ```php $x = match { preg_match('/a/', 'a') => "will it be matched ..." , default => "... or not?" }; ``` knowing that preg_match(...) never returns `true`, but one of `0`, `1` or `false`. More generally, how to deal with truthy-but-not-true values. I see three options: (a) check for strict equality with `true` (i.e. make `match {}` equivalent to match(true) {}`). The `preg_match(...)` branch will never be taken; (b) check for truthy values. The `preg_match(...)` branch will be taken if the condition evaluates to 1; (c) mandate a boolean: The `preg_match(...)` branch will throw a runtime error if the condition evaluates to 0 or 1; Personnally, I am against option (a) as it is confusing and would be a source of bugs. —Claude

Dmitry Derepko

1 year ago
Hi, Claude!
> On Feb 4, 2025, at 11:44 AM, Claude Pache <claude.pache@gmail.com> wrote: > > Hi, > > One issue to resolve is how to interpret: > > ```php > $x = match { > preg_match('/a/', 'a') => "will it be matched ..." > , default => "... or not?" > }; > ``` > > —Claude
I wouldn’t discuss it there because the proposal is only about short syntax. So making “match” work in different way is not a goal for the change. It must work as full form “match(true)”: strict match, which is "===“. If you’re going to use non-strict comparison check “switch” operator: https://3v4l.org/tHkJu Anyway, as for me it should be another thread. Thanks! ---------- Best regards, Dmitrii Derepko. @xepozz

Claude Pache

1 year ago
> Le 4 févr. 2025 à 10:34, Dmitry Derepko <xepozzd@gmail.com> a écrit : > > Hi, Claude! > >> On Feb 4, 2025, at 11:44 AM, Claude Pache <claude.pache@gmail.com> wrote: >> >> Hi, >> >> One issue to resolve is how to interpret: >> >> ```php >> $x = match { >> preg_match('/a/', 'a') => "will it be matched ..." >> , default => "... or not?" >> }; >> ``` >> >> —Claude > > I wouldn’t discuss it there because the proposal is only about short syntax. > So making “match” work in different way is not a goal for the change. > > It must work as full form “match(true)”: strict match, which is "===“. > If you’re going to use non-strict comparison check “switch” operator: https://3v4l.org/tHkJu > Anyway, as for me it should be another thread. Thanks!
Hi Dmitry, The issue absolutely belong to a thread discussing making “match (true) {}” equivalent to “match {}”. It doesn’t matter what is logical or simple, you have also think about what is intuitive or, conversely, confusing. With `match (true) { $foo => ... }`, it is clear you are comparing $foo with the literal value `true`. With `match { $foo => ... }`, it is not intuitive at all that you are *not* just checking the condition $foo, but rather you are comparing $foo with some default literal value. The difference matters. Therefore, I think it is a bad idea to make `match (true) { }` equivalent to `match { }`. —Claude

Marc

1 year ago
Hi Claude, On 04.02.25 11:10, Claude Pache wrote:
> > >> Le 4 févr. 2025 à 10:34, Dmitry Derepko <xepozzd@gmail.com> a écrit : >> >> Hi, Claude! >> >>> On Feb 4, 2025, at 11:44 AM, Claude Pache <claude.pache@gmail.com> >>> wrote: >>> >>> Hi, >>> >>> One issue to resolve is how to interpret: >>> >>> ```php >>> $x = match { >>>   preg_match('/a/', 'a') => "will it be matched ..." >>>  , default => "... or not?" >>> }; >>> ``` >>> >>> —Claude >> >> I wouldn’t discuss it there because the proposal is only about short >> syntax. >> So making “match” work in different way is not a goal for the change. >> >> It must work as full form “match(true)”: strict match, which is "===“. >> If you’re going to use non-strict comparison check “switch” operator: >> https://3v4l.org/tHkJu >> Anyway, as for me it should be another thread. Thanks! > > Hi Dmitry, > > The issue absolutely belong to a thread discussing making “match > (true) {}” equivalent to “match {}”.
agree
> It doesn’t matter what is logical or simple, you have also think about > what is intuitive or, conversely, confusing.
Of course it matters what is logical as a logical rule is much better to remember and document as a rule with tons of exceptions.
> > With `match (true) { $foo => ... }`, it is clear you are comparing >  $foo with the literal value `true`. > > With `match { $foo => ... }`, it is not intuitive at all that you are > *not* just checking the condition $foo, but rather you are comparing > $foo with some default literal value. The difference matters. > > Therefore, I think it is a bad idea to make `match (true) { }` > equivalent to `match { }`.
No, for me this isn't logical and it's going to be an exception which is harder to follow. Given your example from above actually shows me that this would hide an error case (or better makes the error case look like the usual one in this case) Additionally, if you really what to compare empty vs. non empty you can use empty to make it explicit. Marc

Larry Garfield

1 year ago
On Tue, Feb 4, 2025, at 1:43 AM, Dmitry Derepko wrote:
> Hi, Larry! > >> On Feb 3, 2025, at 10:01 AM, Larry Garfield <larry@garfieldtech.com> wrote: >> >> On Sun, Feb 2, 2025, at 7:40 AM, Ilija Tovilo wrote: >>> Hi Dmitrii >>> >>> On Sun, Feb 2, 2025 at 1:05 PM Dmitry Derepko <xepozzd@gmail.com> wrote: >>> >>> https://wiki.php.net/rfc/short-match >>> https://externals.io/message/112496 >> >> Hi, author of that RFC here. Although there seemed to be interest for it in the initial match() discussion, the stand-alone follow up was met with a giant "meh", which is why I didn't pursue it further. I would still be in favor of it, though, if it could get through internals. I'm happy to have someone pick it up and run with it, or collaborate on rebooting that RFC. (I'm pretty sure the patch for it actually worked, at least it did at the time.) >> >> --Larry Garfield > > It looks funny that I’m following in your steps with the RFC’s didn’t > go through 😃 > > By the way, I’ve implemented empty match subject in a bit different > way: https://github.com/php/php-src/pull/17692
I have no particular preference here; whichever approach Ilija thinks is better is what we should go with. (Feel free to steal the AST printer parts from my PR if we end up going with your PR.)
> About the RFC. What’s the way to re-activate it? > Will you re-activate it? > Do I need to create a new one referencing to this one? > Can you share rights to edit the RFC and we can push it further together?
Procedurally, since it was never voted on, I believe we can just move it back to "in discussion" on the wiki, start a new official discussion thread, and go to town. I'm fine with doing that if everyone else is. And of course add your name to it as well (and anyone else that contributes). The main question is whether there's enough interest to justify taking it to a vote. Would anyone actually vote Yes for this? :-) Feature-wise, I have to say I'd keep it strict-always, as both our PRs implement it. Yes, that means preg_match() wouldn't be able to slot in transparently. I'm frankly OK with that; hopefully pattern matching can be extended to a better regex syntax anyway in the future. --Larry Garfield

Kamil Tekiela

1 year ago
It sounds like a nice QOL improvement. I'm ok with preg_match not working and I would even say it would be wrong if it did work like that. It would also prevent people from accidentally forgetting to provide the matching subject in as it would generate UnhandledMatchError with non-bool types. I don't know about switch though. I think switch should always have a subject because it's loose comparison. So if the vote is whether we should allow no subject in both then I would vote no.

Weedpacket

1 year ago
On 2025-02-05 09:49, Larry Garfield wrote:
> > Feature-wise, I have to say I'd keep it strict-always, as both our PRs implement it. Yes, that means preg_match() wouldn't be able to slot in transparently. I'm frankly OK with that; hopefully pattern matching can be extended to a better regex syntax anyway in the future. > >
Besides, the ugly need go no further than a (bool)preg_match(...) cast - which is just as strict and is more explicit about what is actually being compared.

Dmitry Derepko

258 days ago
> On Feb 2, 2025, at 4:04 PM, Dmitry Derepko <xepozzd@gmail.com> wrote: > > Hi! > > I’m thinking about making match (true) and switch (true) be more lightweight by removing the subject “(true)” and making matching “true condition” by default. > So $var = match (true) { … } can be used as $var = match { … }. > > It’s often used in Kotlin. Pretty convenient way to use combined conditions. It’s natively understandable because there should be a condition: > > $result = match { > $x < $n => …, > $x > $n => …, > else => …, > } > > The same explanation for switch construction, but in Kotlin it’s the same construction “when": > > > val result = when { > x < n -> … > x > n -> … > else -> … > } > > var result = null > when { > x < n -> { result = … } > x > n -> { result = … } > else -> return > } > > https://kotlinlang.org/docs/control-flow.html#when-expressions-and-statements`when` construction is overwhelming, but some features are totally handy, such as checking for class of the subject: > when (obj) { > is Class1 -> … > is Class2 -> … > else -> ... > } > > Which was implemented by Ilija Tovilo in: https://github.com/php/php-src/compare/master...iluuu1994:pattern-matching > > By the way, what do you think about allowing to drop the subject of match / switch as a first iteration? > Maybe would be better to ask Ilija to recreate his PR? > > > ---------- > > Best regards, > Dmitrii Derepko. > @xepozz
I would like to bring the discussion up and try to figure out all pros and cons of this ability. Moreover, coming Pattern Matching is a great addition to have this merged: $x = match { $a is “pattern” -> … $b is “pattern” -> … $c === null -> … $this->lastChance($d) -> … default -> ... } Again, it should work as it would have `(true)` context. So the following snippet: var_dump(match(true) { 1=>'one', 0=>'zero', default=>'default', }); will produce “default”, because “true” is not “1” and “0”. IDE may highlight such cases because they’ll never match so it would be detected as dead code. ---------- Best regards, Dmitrii Derepko. @xepozz