On Mon, Dec 1, 2025, at 3:36 PM, Larry Garfield wrote:
> Hi folks. Ilija and I would like to present our latest RFC endeavor,
> pattern matching:
>
> https://wiki.php.net/rfc/pattern-matching
>
> You may note the date on the RFC is from 2020. Yes, we really have had
> this one in-progress for 5 years. :-) (Though it was inactive for many
> of those years, in fairness.) Pattern matching was intended as the
> next follow up to Enums, as it's a stepping stone toward full ADT
> support. However, we also feel it has enormous benefit on its own for
> simplifying complex comparisons.
>
> This RFC has been through numerous iterations, including a full
> implementation rewrite just recently that made a number of features
> much easier. We have therefore included two patterns that were
> previously slated for later inclusion but turned out to be trivially
> easy in the new approach. (Variable pinning and numeric comparison.)
>
> Nonetheless, there are two outstanding questions on which we are
> looking for feedback.
>
> Naturally given the timing, we will not be calling a vote until at
> least late January, regardless of how the discussion goes. So, plenty
> of time to express your support. :-)
Happy New Year!
Tim brought up some interesting points around parsing edge cases, which we're
still discussing off list. Once we have a proposal (or multiple) to consider,
we'll get back to that part.
Meanwhile, there's a few outstanding issues that we do still want/need broader
feedback on. Even if you just want to state a bikeshed preference, please do
so. (Though an explanation of why is always helpful.)
1. match() statements. There's two ways we could do this: All-branches, or
individual branches. This is particularly important as, in practice, we expect
match() to be the most common use of patterns.
// All-branches:
$result = match ($somevar) is {
Foo => 'foo',
Bar => 'bar',
Baz|Beep => 'baz',
Qix, Nox => 'qix',
};
// Individual branches
$result = match ($somevar) {
is Foo => 'foo',
is Bar => 'bar',
is Baz|Beep => 'baz',
is Qix, Nox => 'qix',
};
The idea of the second being that, if you want just an identity match, you can
skip adding `is` on just that one arm. While it would be lovely to do that
automatically, we cannot differentiate between a class name and a constant so
that's not really feasible.
Of note, most language with this functionality have no "non-pattern" equivalent
of match(), so the issue doesn't come up. The only one that does, Ruby, uses a
different prefix keyword depending if it's pattern or equality based, BUT you
have to use the same keyword for all branches.
2. Positional array patterns. How picky should the pattern matching be for
list-esque arrays? There's 3 options listed in the RFC as possible ways
forward, so I won't repeat them here but just provide a link:
https://wiki.php.net/rfc/pattern-matching#positional_array_enforcement
3. Do we want to have a pattern for "match an object's properties without
specifying what type the object has to be?" If so, what syntax should it be?
Just omitting the class name (producing `$o is {x: 1}` ) is not possible. We
tried. :-) Options include:
`$o is _(x: 1)`
`$o is object(x: 1)`
// Your suggestion here.
4. The variable pinning syntax. There's been some concerns about it being
non-obvious, which is valid. The main argument for it is "it's what Ruby
does", which is not the most compelling argument, but it's not invalid.
Is there some other syntax that would work better? Ilija has pondered `{$x}`,
which would then potentially allow simple expressions inside the pattern within
the {}. I am a little scared of the scope creep potential. :-) But we're open
to having this discussion, so please discuss.
Please do weigh in and help us decide on a way forward for these.
--Larry Garfield