Hi Nikita > I think part of the problem is that it's a case of either / or.
I agree that your example is an unpleasant limitation. > I'm not quite sure what the way forward regarding that is. I can understand > the reluctance to propose the Rust-style block expression syntax, given its > currently fairly limited usefulness outside match expressions. I do think > that this is principally the right approach though, if we want to introduce > control flow expressions like match. I personally don't have anything against that approach. I only fear that proposing a block expression RFC first will most likely fail because at present the only real use case is arrow functions. If PHP had block scoping it could have other benefits. $this->foo = { $foo = new Foo(); $foo->prop1 = ...; $foo->prop2 = ...; $foo }; But since $foo escapes the block this isn't incredibly helpful either other than making it a little more readable. There are also a few issues we'll have to tackle. In my prototype block expressions had the following grammar: '{' inner_statement_list expr '}' This means the following would be invalid. $x = fn() => { return 'Foo'; // Parse error, expression expected }; match ($x) { 0 => { echo 'Foo'; // Parse error, expression expected } } Neither of those are great. If we define the grammar like this: '{' inner_statement_list optional_expr '}' Well have a conflict with statement lists and if statements. function foo() { { // Valid today } } if ($x) { // Is this a block expression or just an if block? }; So to make that implementation compatible we'd have to allow dropping the semicolon in this case as well which was highly criticized in this RFC. We'd also have to check on a case per case basis if the ending expression in the block expression is allowed/required or not. Since there's quite a bit of time left until the feature freeze I can try to think of a few solutions and propose this RFC but I'm afraid if it fails we'll be right back where we started. > But if we stay consistent with the remaining proposal, then > $c should be interpreted as a value to match against here, just like 1 and > 2. The way to actually capture $c should be > > match ($value) { > let [1, 2, let $c] => ... > } This isn't quite how I imagined it. In this example, 1 and 2 are not arbitrary expressions but literal patterns. https://doc.rust-lang.org/reference/patterns.html#literal-patterns Thus every member of the pattern array itself is a pattern, not an arbitrary expression which would make the let keyword in the array pattern unnecessary (and actually invalid). Of course it doesn't necessarily need to be this way. Your example would work but as you said prefixing every single pattern would be very tedious. With the pattern only approach, if you wanted to check if some member of the array has a dynamic value you'd do something like this: match ($value) { let [1, 2, $c] if $c === $y => ... } In other words, the let is more of a prefix of the whole arm, not just a single pattern. > Another consideration here is that "let" carries a very strong implication > of block scoping. Agreed. I couldn't think of a better keyword but I'm definitely open to suggestions. > Finally, the use of "," to specify multiple match values could be a > composition problem. Rust uses | to specify multiple match values, and also > allows its use in sub-patterns (this is the "or patterns" feature). This > allows you to write patterns like Unfortunately using | is not possible for arbitrary expressions as it collides with the bitwise or operator. However it can be used in patterns because they would not allow arbitrary expressions. match ($x) { let [1|2, 3|4] => ..., } The inconsistency is a little unfortunate. But I don't think there's another feasible way. Ilija -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php