Hi Andrea

> Well, I don't think we have any other expressions that are also
> statements with very slightly different syntax

The syntax isn't actually different. We don't have different grammar
for the match statement and expression. There's only one. Think of it
more like a type check. In other languages you couldn't use the result
value of a `void` function (PHP is a little different here since
`void` functions return `null`). Similarly using the result of `{ ...
}` doesn't make sense (as it has none) so we throw a compilation
error. Alternatively we could return `null` here too but I'd really
prefer not to.

> We already have a limited kind of pattern matching in PHP

While that's true I don't think the array pattern should be
implemented in the same way. There's a lot to think about here. For
example:

```
// Traditional array destructuring
[$a, $b] = [1, 2, 3];
//> $a === 1
//> $b === 2
```

This is usually not how array patterns work. The array size is critical:

```
let [$a, $b, $c] = [1]; // Unmatched pattern error
let [$a] = [1, 2]; // Unmatched pattern error

let [$a, $b, $c] = [1, 2, 3]; // Ok
let [$a, ...] = [1, 2]; // Ok
```

There are more things to think about like allowing
`ArrayAccess&Countable`, order, `[$x, ...$y]`, etc. If we get the
details wrong it might be hard to correct them later. Another
challenge is emitting efficient opcodes. Consider this example:

```
let [1, 2, $c] = $value;

// Is roughly equivalent to:

if (
    !is_array($value)
    || count($value) !== 3
    || !isset($value[0])
    || $value[0] !== 1
    || !isset($value[1])
    || $value[1] !== 2
    || !isset($value[2])
) {
    throw new UnmatchedPatternError();
}

$c = $value[2];
```

Since PHP (often) doesn't have enough type information at compile time
the number of opcodes can explode very quickly due to many runtime
checks. I don't know how we would best tackle this yet. Another issue
is scoping that is pretty hard to solve in PHP.

```
$x = 10;

match ([1, 2]) {
    let [$x, 3] => ...,
    default => ...,
}

// $x is now 1 even though the pattern did not match
```

The values shouldn't be assigned until after the pattern has matched
which means more complexity and less efficiency.
I hope you can see now why I'm hesitant here.

> It would be a bit surprising if you are new to the `match` statement

So surprising in fact I'm willing to bet 90% would get it wrong the
first time (if uninstructed, of course).

> True, that is less elegant. But when would you need to do that?

Anytime you would've written code like this:

```
if ($x === $foo) {
    $y = ...;
} elseif ($x === $bar) {
    $y = ...;
}
```

This is not uncommon at all. With match + arbitrary lhs expressions
you can replace it with:

```
$y = match ($x) {
    $foo => ...,
    $bar => ...,
};
```

The switch probably wouldn't have been used here because it's even
more verbose than the if (and more error prone).

```
switch ($x) {
    case $foo:
        $y = ...;
        break;
    case $bar:
        $y = ...;
        break;
}
```

Ilija

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to