On Tue, Feb 4, 2025, at 05:31, Larry Garfield wrote:
> Hi folks. Ilija is still working on the implementation for the pattern
> matching RFC, which we want to complete before proposing it officially in
> case we run into implementation challenges.
>
> Such as these, on which we'd like feedback on how to proceed.
>
> ## Object property patterns
>
> Consider this code snippet:
>
> class C {
> public $prop = 42 is Foo{};
> }
>
> The parser could interpret this in multiple ways:
>
> * make a public property named $prop, with default value of "the result of
> `42 is Foo`" (which would be false), and then has an empty (and therefore
> invalid) property hook block
> * make a public property named $prop, with default value of "whatever the
> result of `42 is Foo {}`" (which would be false).
>
> Since the parser doesn't allow for ambiguity, this is not workable. Because
> PHP uses only an LL(1) parser, there's no way to "determine from context"
> which is intended, eg, by saying "well the hook block is empty so it must
> have been part of the pattern before it."
>
> In practice, no one should be writing code like the above, as it's needlessly
> nonsensical (it's statically false in all cases), but the parser doesn't know
> that.
>
> The only solution we've come up with is to not have object patterns, but have
> a property list pattern that can be compounded with a type pattern. Eg:
>
> $p is Point & {x: 5}
>
> Instead of what we have now:
>
> $p is Point{x: 5}
>
> Ilija says this will resolve the parsing issue. It would also make it
> possible to match `$p is {x: 5}`, which would not check the type of $p at
> all, just that it's an object with an $x property with value 5. That is
> arguably a useful feature in some cases, but does make the common case
> (matching type and properties) considerably more clunky.
>
> So, questions:
>
> 1. Would splitting the object pattern like that be acceptable?
> 2. Does someone have a really good alternate suggestion that wouldn't confuse
> the parser?
>
> ## Variable binding and pinning
>
> Previously there was much discussion about the syntax we wanted for these
> features. In particular, variable binding means "pull a sub-value out of the
> matched value to its own variable, if the pattern matches." Variable pinning
> means "use some already-existing variable here to dynamically form the
> pattern." Naturally, these cannot both just be a variable name on their own,
> as that would be confusing (both for users and the engine).
>
> For example:
>
> $b = '12';
>
> if ($arr is ['a' => assign to $a, 'b' => assert is equal to $b]) {
> print $a;
> }
>
> Based on my research[1], the overwhelming majority of languages use a bare
> variable name to indicate variable binding. Only one language, Ruby, has
> variable pinning, which it indicates with a ^ prefix. Following Ruby's lead,
> as the RFC text does right now, would yield:
>
> $b = '12';
>
> if ($arr is ['a' => $a, 'b' => ^$b]) {
> print $a;
> }
>
> That approach would be most like other languages with pattern matching.
>
> However, there is a concern that it wouldn't be self-evident to PHP devs, and
> the variable binding side should have the extra marker. Ilija has suggested
> &, as that's what's used for references, which would result in:
>
> $b = '12';
>
> if ($arr is ['a' => &$a, 'b' => $b]) {
> print $a;
> }
>
> There are two concerns with this approach.
>
> 1. The & could get confusing with an AND conjunction, eg, `$value is int &
> &$x` (which is how you would bind $value to $x iff it is an integer).
> 2. In practice, binding is almost certainly going to be vastly more common
> than pinning, so it should likely have the shorter syntax.
>
> There are of course other prefixes that could be used, such as `let`
> (introduces a new keyword, possibly confusing as it wouldn't imply scope
> restrictions like in other languages) or `var` (no new keyword, but could
> still be confusing and it's not obvious which side should get it), but ^ is
> probably the only single-character option.
>
> So, question:
>
> 1. Are you OK with the current Ruby-inspired syntax? ($a means bind, ^$b
> means pin.)
> 2. If not, have you a counter-proposal that would garner consensus?
>
>
> Thanks all.
>
> [1] https://github.com/Crell/php-rfcs/blob/master/pattern-matching/research.md
>
> --
> Larry Garfield
> [email protected]
>
Hey Larry,
Instead of symbols, why not use words?
We already have &&, but it looks like this uses & instead, which is a
bitwise-and. But the language does have “and” as a keyword. So instead of:
$value is int & &$x
It would be:
$value is int and &$x
Which removes the confusion you mentioned before (also for someone like me who
uses bitwise-and quite a bit).
— Rob