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

Reply via email to