Re: [DISCUSSION] Match expression
| From: | Rowan Tommins | Date: | Mon, 13 Apr 2020 14:49:36 +0000 |
| Subject: | Re: [DISCUSSION] Match expression | ||
| References: | 1 2 3 4 5 6 7 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-109606@lists.php.net to get a copy of this message | ||
On 13/04/2020 12:28, Ilija Tovilo wrote:
Then why not introduce the match expression first, and add block expressions (as a general concept) later? That way, we don't need all the special restrictions on when to use them, and can work out a consistent set of rules for them which can apply language-wide, rather than being constrained later by decisions we make half-implementing them now. The ability to use them with short closure syntax would be very interesting, if the scoping/capture rules could be agreed.It would be possible for the blocks to return values (though not with the return keyword). [...]We can't do everything at once.
Not really. In Rust, it's about making a whole bunch of control structures, which are already consistent with each other, more user friendly (but still consistent). In your proposal, it's about making one specific control structure look slightly more like other syntaxes in the same language, by adding a special case which applies nowhere else. To be specific, in PHP, there is no "omitted semicolon" at the end of "if ($x) { y(); }" - that is just how the syntax is defined. There's no need to have a parser rule to allow it to look like C or Java, because it already does.it makes *all* the control flow blocks in Rust feel more natural to developers coming from other languages.Same thing here. If you don't use the result value, it looks just like the switch. That's why I'd feel odd to require a semicolon.
This code is parsed like this:I'm not sure what you mean by "we can't have ambiguous grammar" - the code above *is* ambiguous, in that it could be defined to mean one of two things; what you've shown is which definition your implementation defines. That resolution makes sense for that example, but consider some others: // As proposed, parsed as two meaningless expression-statements; as a normal expression, would select and then invoke a callable match($x) { 1 => 'print', 2 => 'var_dump' } ($x); // Invalid under the proposed rule, but a valid method call if match was always a normal expression match($x) { 1 => new Foo, 2 => new Bar } ->doSomething(); To be fair, the same limitation exists for closures, where this is invalid: function($x) { echo $x; } ("Hello"); and you have to write this instead: (function($x) { echo $x; }) ("Hello"); So I guess the above would follow the same rule to force expression context: (match($x) { 1 => 'print', 2 => 'var_dump' })($x); (match($x) { 1 => new Foo, 2 => new Bar })->doSomething(); The only downside is that omitting the parentheses wouldn't be an error, as with the closure case, it would just silently do nothing, which might be rather confusing. Dropping the special semicolon handling would mean it either did the expected thing or gave a parse error straight away. Regards, -- Rowan Tommins (né Collins) [IMSoP]match($x) { 1 => ['foo', 'bar'] } [0];* statement list* match expr * array literalNote that we can't have ambiguous grammar since Bison would immediately expose it.