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
Hi Dmitrii
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
Hi Dmitrii
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
Hi, Larry!
Hi Dmitrii
https://wiki.php.net/rfc/short-match
https://externals.io/message/112496Hi, 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
Le 4 févr. 2025 à 08:43, Dmitry Derepko xepozzd@gmail.com a écrit :
Hi, Larry!
Hi Dmitrii
https://wiki.php.net/rfc/short-match
https://externals.io/message/112496Hi, 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:
$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
Hi, Claude!
Hi,
One issue to resolve is how to interpret:
$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
Le 4 févr. 2025 à 10:34, Dmitry Derepko xepozzd@gmail.com a écrit :
Hi, Claude!
Hi,
One issue to resolve is how to interpret:
$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
Hi Claude,
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:
$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 valuetrue
.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 tomatch { }
.
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
Hi, Larry!
Hi Dmitrii
https://wiki.php.net/rfc/short-match
https://externals.io/message/112496Hi, 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
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.
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.