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
>   la...@garfieldtech.com
> 

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

Reply via email to