Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:109658 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 15142 invoked from network); 15 Apr 2020 17:25:25 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 15 Apr 2020 17:25:25 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 315D71804F6 for ; Wed, 15 Apr 2020 08:55:23 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.2 required=5.0 tests=BAYES_20,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-yb1-f182.google.com (mail-yb1-f182.google.com [209.85.219.182]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 15 Apr 2020 08:55:22 -0700 (PDT) Received: by mail-yb1-f182.google.com with SMTP id e17so271582ybq.0 for ; Wed, 15 Apr 2020 08:55:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=NWhLwXdnNIcV4oGdzC16sTnunEIe/sPRrGPpz4TyWUQ=; b=DwgDk+qBo3+J92EMkUlTVvQVTEcAay7lTajYj7f+Yw4CSGCO/uiNWN0ZOmh74y0+6X RvsflilPymZEHT9RVtg5OOvST0kYg0YyxnEmLc/2pXI7of3lFpXZmu+6lTWSMWXkrdMd sSlN5uvTUEps10lVBDHHRNSUdHg/txhi2aA6XEwR+MlHJq3s6vl6S+mXurWZLB2lYz9e WdqnE+cog+Z+vWSZkiYu9Bxbb7TUMMvL8TV6U4wR8YkS5d5CLKaIq02aliYZd2b0UxqM GRaXuAUa1j64SFOW52fjFVfnTCexG/G7Dvs8JN/jkBAlbJjfV3/E5rNEbi+Wkk304bk9 VMcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=NWhLwXdnNIcV4oGdzC16sTnunEIe/sPRrGPpz4TyWUQ=; b=grnOCID+bwRnr+9sFa/Wvix/KD4+bIfpBuHOFf+emPuLJtwvHpMf2jGNg05vPdac6d DUXXAXggTPRqd1ezOwYQ94uKhKovNlD4SQaEgv/Qif/kJ3Ckq/j/J+HCP1+qlxUoKnaw rYPB7UD2JcbEQFh4YuRzn6/S4oKVfGyQmY50H0ooXxJf/S0HCuQs7x0O8AaAkDAD8p8U i7MEsjt2K3gDZlBGbnmF3dvGcaLV0j0oW+god/0FZFdlPl9p1bQjAX88ra2SedAnIC7d l9zUSQFllfUqllThMLGRRESFl9SNLXE5bygoxjRcdfzhAL3ldervzzAi60k55xk4J1OS BvAw== X-Gm-Message-State: AGi0PuYTO95mWSqZAyZEFU5qJgfSjtDuUiu93OTKUIjMGbW3bmlBY30j HEzL8TgkEPJ4IYPEUAuP3qMhRouCYs9KoL4J6zpZVYij X-Google-Smtp-Source: APiQypIOe9XxsJsHBqElx34yu125Rl9bejhh2XHOmy+R2tdYykOtvEm1jm78tGIGto/CNqFuc+M8NW4avbkcT4WNZX0= X-Received: by 2002:a25:5f07:: with SMTP id t7mr9281968ybb.411.1586966119410; Wed, 15 Apr 2020 08:55:19 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Wed, 15 Apr 2020 17:55:07 +0200 Message-ID: To: PHP internals Content-Type: text/plain; charset="UTF-8" Subject: Re: [PHP-DEV] [DISCUSSION] Match expression From: tovilo.ilija@gmail.com (Ilija Tovilo) 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