On Fri, Jun 21, 2024, at 3:35 PM, Brandon Jackson wrote:
Ilija and I have been working on and off on an RFC for pattern matching since the early work on Enumerations. A number of people have noticed and said they're looking forward to it.
Hi Larry, I have definitely been looking forward to this. Perhaps more
so than property hooks and avis.
By "very high level," I mean, please, do not sweat specific syntax details right now. That's a distraction. What we're asking right now is "which of these patterns should we spend time sweating specific syntax details on in the coming weeks/months?" There will be ample time for detail bikeshedding later, and we've identified a couple of areas where we know for certain further syntax development will be needed because we both hate the current syntax. 
I think that a lot of this would be best broken up. Although much of
it is aimed towards the same general idea, a lot of the pieces have
specific use cases and special syntax additions. Overall I think this
rfc should be simplified to just pattern matching with the `is`
keyword with the patterns limited to what can be declared as property
types (DNF types) and future scoping everything else. Maybe possibly
with the addition of 1 or 2 of the top requested `is` pattern matching
capabilities as secondary votes.
To give more context, as noted, this is a stepping stone toward ADTs. Anything that is on the "hot path" for ADT support I would consider mandatory, so trying to split it up will just take more time and effort. That includes the object pattern and match support, and the object pattern realistically necessitates literals. Variable binding would also be almost mandatory for ADTs. I'm very reluctant to push off anything in that hot path, as every RFC has additional overhead, and I'm all volunteer time. 
1. `as`
`is` and `as` have different responsibilities. I'm guessing the idea
is to keep them in sync. But I would still like to see this as a
future scope with a separate rfc. I do like the idea, and believe it's
much needed. But I think the pattern matching portion `is` overshadows
the `as` portion causing it not to get as much attention as far as
discussion and analysis goes. Especially if the idea is to sync them,
then that makes `as` just as big of an addition as `is`
For example, what if instead, a generally prefered solution/syntax
were variable types, something like:
`var Foo&Bar $my_var = $alpha->bravo;`
Although casting and declaring are 2 separate things. This seems like
it would accomplish the same thing without the extra keyword, with the
exception of casting being inline. How much would it get used if both
were added? Would one then become an "anti-pattern"?
As proposed, `as` is basically:
$foo as Bar|Baz
// Becomes
if (! $foo is Bar|Baz) {
throw \Exception();
}
So it would be pretty easy to do, I believe. Whether that's what we *want* `as` to be, that's a fair question.
2. Literal patterns
Again a really nice addition. Love it and likely will be loved by
many. Although, it definitely deserves its own separate discussion.
Looking at typescript which has both enums and literal types (although
vastly different in php) caused what was once considered a nice
feature to be black listed by many. Also note how typescript separates
type land and value land. Maybe worth considering.
As noted above, I don't think it's feasible to postpone this one. It's also pretty simple, and wouldn't have any conflict with enums unless we went all in on the guards options, which we most likely will not in the initial version.
3. Wild card
Has already been marked as not necessary it looks like and replaced by mixed.
Some people still want it, even though it's redundant, so it may end up as a secondary vote. I don't much care myself either way.
4. Object matching
Absolutely a separate rfc please. Definitely needs discussion. Could
intersect another potentially preferred solution like type aliases.
Sending one or the other into anti-pattern world.
Maybe a solution similar to this would be preferred:
type MyType = Foo&Bar
$foo = $bar as MyType|string
As noted, this is on the ADT hot path so postponing it is problematic. Especially holding it on type aliases, which have been discussed for longer than this RFC has been around (nearly 4 years) and yet no actual proposal has ever been put forward. It's unwise to wait for such a feature, especially when most likely implementations would dovetail well with patterns anyway.
5. Array sequence patterns
More in depth discussion needed. Not sure how often this comes up as a
structure people want to check against, but it can definitely be done
in user land with array slices. Even though it might be nice for
completion's sake, it may not be worth it if there's not high demand
for it. If at all could be grouped with associative array patterns.
6. Associative array patterns
Love to have this one, but it also seems like a small extension or
conflicting with array shapes. Also potentially conflicts with
generics (which may or may not ever be a thing) but still let's give
it the attention it needs. Maybe group with array shapes as well.
7. Array shapes
Same as above
To clarify here, these all come as a set. Array shapes aren't their own "thing", they just fall out naturally from array patterns. So it's not possible for associative patterns to conflict with array shapes, as they are literally the same thing.
I'd have to check with Ilija but I don't believe there's much internal difference between list and associative patterns. This one isn't on the ADT hot path, so it could be postponed
I see no way for associative array patterns/shapes to conflict with generics at all.
8. Capturing values out of a pattern and binding them to variables if matched
Ok I think that's stepping a bit far out of scope. Maybe `is` should
simply check and not have any side effects.
As above, this is core functionality of pattern matching for ADTs, as well as a core feature of every other language that has pattern matching, I believe. It's not out of scope, it's core scope.
9. match .. is
Nice shorthand to have but i'd rather not see short hands forced in as
an all or nothing type thing as was done with property hooks. I'd also
argue that maybe short hands should not be added until a feature has
been around for at least one release and is generally accepted. That
way we're not using up syntaxes and limiting the ability to add other
syntax features without breaking backwards compatibility. Keep in mind
that the `is` functionality alone allows this (or at least it should)
and a shorter version may or may not be desired.
match(true) {
$var is Foo => 'foo',
...
}
This is also core scope of pattern matching in most languages. It's not just a shorthand, it's a direct enhancement.
--Larry Garfield