> Ilija and I have been working on and off on an RFC for pattern matching since 
> the early work on Enumerations. A number of people have noticed and said 
> they're looking forward to it.

Hello Larry.

Thanks for this Juicy proposal.

I agree that this proposal should be proposed as a whole. If we break
it down into smaller parts, there is a chance some features will not
pass. I will show you that the range pattern and regex pattern have
greater value than what you think, and they must be placed together
with the literal pattern (in Core patterns section, not in Possible
patterns section). I don't want these patterns to fail in the poll.

I don't know the line between "high level" and beyond. I hope that
whatever I discuss here is still "high level".

1. Is there any chance of ```is not``` or ```isnot```? I am tired
looking this ugly code: ```!($foo instanceof Bar)```. If there is,
there should be a restricted version of pattern: no variable binding.
It doesn't make sense if the binding happens but the pattern fails.

2. ```..=``` and ```..<``` make people have to remember what the left
side is: is it greater-than or greater-than-equal. What if those
operators are replaced with ```=..=``` and ```<..=```? We don't have
to align with other languages if they have weaknesses.

3. There are "between" and ```>``` operators explicitly shown in the
proposal (in Range pattern section). I assume that ```>=```, ```<```,
```<=``` implicitly included. What about the ```%``` operator, is it
also included?  ```%``` is not directly produces boolean, but it can
simplify pattern. Note that, we must include additional rules: if
produced number is ```0``` (zero) then it will be converted to
```true```, otherwise ```false```.

```
$foo = 2024; // leap year
$foo is %4; // true

$bar = 2025; // not a leap year
$bar is %4; // false

// furthermore:
$baz is array<%4>; // true if all its members are leap year
```

4. There are numeric range patterns explicitly shown in the proposal.
Hopefully there are also string range patterns.

```
$birthdate is "2000-01-01 00:00:00" <..< "2019-12-31 23:59:59";
$dateOfDeath is <"1980-01-01";
$name is "larry " =..< "larry!"; // true if first name is "larry"
```

I have no idea about string range patterns for array, since it causes
error. If there is currently no solution, hopefully we don't abandon
string range patterns entirely. The same case also occurs with numeric
range patterns for array.

5. It is great that regular expression native syntax is now a first
class citizen in php (at least for pattern matching). I found there
are 2 drawbacks in this case: loss of flexibility and repeated
identical patterns. These things are not found in string based regular
expression.

```
// native syntax
$foo is /^https:\/\/(?<hostname>[^\/]*)/;

// string based: we can use any valid char as delimiter,
// as long as it is not used in the pattern.
$pattern = "/^https:\/\/(?<hostname>[^\/]*)/";
$pattern = "|^https://(?<hostname>[^/]*)/|";    // valid!
$pattern = "@^https://(?<hostname>[^/]*)/@";    // valid!

// ----------------------

// native syntax
$foo is /^https:\/\/(?<hostname>[^\/]*)/ | StringBox{value:
/^https:\/\/(?<hostname>[^\/]*)/};

// string based: RE stored in variable/constant can be used as many as we need
$pattern = "|^https://(?<hostname>[^/]*)/|";
$foo is @RE($pattern) | StringBox{value: @RE($pattern)};
// 1st pattern is scalar string, 2nd is string encapsulated in a class

// furthermore
use GenericPattern as GP;
class Person {
    public string $firstName is @RE(GP::NAME_PTRN);
    public string $lastName is @RE(GP::NAME_PTRN);
// ...
}
```

Hopefully, string based regular expression is also supported.
Honestly, if I could choose whether I should support native or
string-based syntax, I would choose to support string-based, as long
as native syntax is not yet fully supported in general.

```@RE()``` is just an illustration on how to use variable as a
regular expression in the pattern. It is stated that ```@()``` will be
used in arbitrary expressions. Correct me if I'm wrong, regexp are one
of the things in programming that cannot be manipulated or participate
in manipulation with other parties, even with fellow regexp. Regexp
must be used alone. That is why we need dedicated syntax for regexp.

6. It is shown that type pattern, literal pattern, class constant
pattern, and expression pattern can be used to form a compound
pattern. Hopefully, the range pattern and regex pattern have the same
luxury. Furthermore, hopefully they can be mixed.

```
$foo is 2000 =..= 2100 & %4; // leap year in 21st century

class person {
    public string $firstName is /LENGTH_PTRN/
        & /FORBIDDEN_CHARS_PTRN/
        & /FORBIDDEN_WORDS_PTRN/;

    public string $lastName is @RE(GP::LENGTH_PTRN)
        & @RE(GP::FORBIDDEN_CHARS_PTRN)
        & @RE(GP::FORBIDDEN_WORDS_PTRN);


    //  these are hard to maintain
    public string $firstName is @RE(GP::COMPLEX_NAME_PTRN);
    public string $lastName is @RE(GP::COMPLEX_NAME_PTRN);
}

7. I noticed that ```as``` is tightly coupled with exception. Can we
suppress this exception with ```??```?

```
// it is weird to see this statement (as show in the proposal)
$value = $foo as Foo {$username, $password};

// these statements are more make sense
$foo as Foo {$username, $password};
$foo is Foo {$username, $password} ?: throw new Exception();

// if it can be suppressed, "as" is more valuable than what people think.
$newRect = $rect as Rectangle{width: <=10, height: <=5} ?? new
Rectangle(width: 10, height: 5);
```

8. Is there any type checking for object property pattern?

```
class Circle {
    public int $radius;
}

// this statement will always fails unless there is type checking
$circle is Circle{radius: "10"};
```

~~~~~

4 of the 8 points I discussed above are related to range pattern and
regex pattern. Both are used daily. From my point of view, literal
pattern is no more special than range pattern and regex pattern. IMO,
both should be placed in Core patterns section, not in Possible
patterns section.

Regards, Hendra Gunawan.

Reply via email to