On Tue, 4 Feb 2025 at 07:35, Larry Garfield <la...@garfieldtech.com> 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
>

Hi, Larry!

First of all, I'm very excited about your Pattern Matching RFC and looking
forward to it.

> Because PHP uses only an LL(1) parser

Are there any plans to upgrade the parser to bypass these limitations? I
remember Nikita shared some thoughts on why this is not trivial in
https://wiki.php.net/rfc/arrow_functions_v2. Maybe something has changed
since then?

-- 
Valentin

Reply via email to