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