Hi Andrea

I realize there's a lot of noise in the mailing list right now, I'll
keep this my only e-mail for today.

> I share others' concern that it is inconsistent with PHP's
> existing statements

Can you elaborate on what exactly the concerns are? Note that even if
we added block expressions to the language there are still certain
sanity checks we'd likely need to make, so the differentiation between
statement/expression would still not go away. For example:

```
match ($y) {
    1 => {
        echo 'Foo';
        echo 'Bar';
        // This is fine
    },
}

$x = match ($y) {
    1 => {
        echo 'Foo';
        echo 'Bar';
        // Error, block must return a value.
    },
};
```

At the moment there are very limited use cases for the block
expression. The only ones I can think of are the match expression,
arrow functions and maybe normal functions. And as that would
introduce two ways to return a value from a function it's questionable
whether we should even allow that or not.

```
$arrowFn = fn() => {
    echo 'Foo';
    'Bar'
};

// Questionable. You're saving a few characters
function getFoo() {
    echo 'Foo';
    $this->foo
}
```

> It is a shame you don't suggest taking this opportunity to add
> pattern matching.

My main concern here is just complexity. There's so much to consider.
We need to think well about each pattern, how it should work, what it
should look like, how it should be implemented, etc. Furthermore
pattern matching usually isn't restricted to the match expression.
There's often pattern matching for `if`, `while`, `foreach`, function
params, normal assignment, etc. So I don't think it should be mixed
with this RFC. IMO if we implement pattern matching we should make it
available for all of these cases.

```
let [string $x, 10] = ['foo', 20]; // Error: Unmatched pattern

if (let Foo { bar: $bar } = $foo) {}

while (let 1..<10 = $x) {}
```

> Using a keyword prefix (e.g. `let`) in future means we end
> up with two kinds of arm (one with === behaviour, one with
> pattern-matching behaviour), but wouldn't it be simpler to
> have just one?

I personally don't think so. Consider this case:

```
$x = 10;
$y = 20; // This variable is unused

match ($x) {
   $y => { // Always true
      echo $y; // Outputs 10
   },
}
```

`$y` is an identifier pattern and it always matches and assigns the
given value to the variable. This is rather confusing. A keyword like
`let` would make it more obvious that you're using a pattern. I'd also
suspect that it's more common to pass expressions to the lhs of a
match statement than patterns so it makes sense that this is the
default.

Also, imagine you want to equate multiple dynamic values with each other:

```
$x = ...;
$y = ...;
$z = ...;

match ($x) {
    $y => ...,
    $z => ...,
}

// If we only have pattern matching
match (true) {
    true if $x === $y => ...,
    true if $x === $z => ...,
}
```

Without allowing dynamic lhs expressions this becomes pretty awkward.

> Relatedly, it is a shame not to have guards

I don't think guards are awfully useful without pattern matching.
What's the benefit over this?

```
match ($x) {
    1 => {
        if ($foo === BAR) {
            ...
        } else {
            ...
        }
    },
}

// vs

match ($x) {
    1 if $foo === 'Bar' => {
        ...
    },
    1 => {
        ...
    },
}
```

That just makes it harder to generate a jump table. It does reduce
nesting a bit but the same could be said for if statements in loops
where we don't have guards.

> It is unfortunate if we have to add another reserved word

My previous draft was mainly criticized because of the usage of the
`switch` keyword.

Ilija

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

Reply via email to