Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:109654 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 93566 invoked from network); 15 Apr 2020 14:56:16 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 15 Apr 2020 14:56:16 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 5746E1804C2 for ; Wed, 15 Apr 2020 06:26:11 -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=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,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-lj1-f174.google.com (mail-lj1-f174.google.com [209.85.208.174]) (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 06:26:10 -0700 (PDT) Received: by mail-lj1-f174.google.com with SMTP id u6so2055126ljl.6 for ; Wed, 15 Apr 2020 06:26:10 -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 :cc; bh=DsUZjmRnGbmtCFixRveg4DYg1ER7yrH14Ic++JgQOqk=; b=N9zsh0kAcW9pUYlJ/sQtgULzc51reuu7qdiYpTis2k7/odUmNZX72gYe53rKz4GAYe c/x/Ze8pjdEqCfyVPrK9YuozwmNeRhaR3nwKZCYc/h5K4xjSEwLfyVeOaAR8+quh9KD8 xevHKD7yXmeQRcX0RysPIW42UgVAb43cX8m1pjg2JvNTqNtK8yyabIaBWJtnH5QsnmXq 3dlQ1iTOR3OPVnTLUTcFjuM4pi/xm/XZNcOfPYjfIy8TrHg4QNK+zl5NXH9urJqqgaxH meW2rxOlWFTKyOelceOFZA9CGhRl1yjr1POCVOHUF66nbsj4zqsGiJp9PlAbj3Y5vXzb kY0A== 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:cc; bh=DsUZjmRnGbmtCFixRveg4DYg1ER7yrH14Ic++JgQOqk=; b=mdfMb0kBfuoLHkJdYiHNt9ODg5DHOK+P68CLxGFSJJgCZCJs+dXUv5h6WSc2H6BLM6 auRfJlvuVjAhff80sbC2POGJU9egcomFpptfPckzT8n81NzgCABKYhgMhwv/hkUcqRfq z6k/lsejFfsYdHuVW1MAYOKorTiVIyIJKy0iJYh2TmWFnaqv16G2x1c8qY0/p8ob5FBB RsWq0J7FB5L/XTyxay1vt6F+NJvkc4qojZ9L+RdcnbyZfG4nYxqKY3wh/NnpZ2N2N2Dg 0fQzUN8M4ofSXa2Z8jlyl9T8z2AgDhI7gAq6kktXfyYq3Y/mwuJQsdw6gHkrNv7JIskA MmhQ== X-Gm-Message-State: AGi0PuZvmWaTrsywbYC4rDp4ixj8ZTRzlxw7J0S7b+wyUj5AXvY5MWNX C1VaGI8boyIKlTwkIoEIvAJLhSeLn73ybiw/Yy0= X-Google-Smtp-Source: APiQypJsHCEpTUaGrOSEPUPsUbOM7pejL48tTSOQ/LPzjiqriZlXOcNW+yJTgpEWvsVw0Yh7O+iBTGDFxO9sz/bElb4= X-Received: by 2002:a2e:a179:: with SMTP id u25mr3287708ljl.192.1586957166921; Wed, 15 Apr 2020 06:26:06 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Wed, 15 Apr 2020 15:25:50 +0200 Message-ID: To: Ilija Tovilo Cc: PHP internals Content-Type: multipart/alternative; boundary="000000000000354d9105a3544242" Subject: Re: [PHP-DEV] [DISCUSSION] Match expression From: nikita.ppv@gmail.com (Nikita Popov) --000000000000354d9105a3544242 Content-Type: text/plain; charset="UTF-8" On Sun, Apr 12, 2020 at 2:16 AM Ilija Tovilo wrote: > Hi internals > > I'd like to announce the match expression RFC that replaces the switch > expression RFC I announced a few weeks ago. > New: https://wiki.php.net/rfc/match_expression > Old: https://wiki.php.net/rfc/switch_expression > > Due to the feedback I decided to take the RFC in a slightly different > direction. The main objections were: > > 1. It didn't behave like the traditional switch so it shouldn't use > the switch keyword > 2. It didn't fix type coercion > 3. The RFC was poorly structured > > In hindsight I understand why I had a hard time writing the RFC. I > tried making a case against the switch statement while really not > addressing the switch statement at all. The new RFC proposes a match > expression that fixes all the objections raised against the switch > statement. Additionally, match arms can now contain statement lists > which allows you to use the match expression anywhere the switch > statement would have been used previously. > > While some people have suggested statement lists aren't necessary I > don't think it makes sense to raise objections against the switch > statement without offering an alternative. > > I also experimented with pattern matching but decided against it. The > exact reason is described in the RFC. > > I'm now confident this is the right approach. I hope you will be > happier with this proposal. > > Happy Easter! > Thanks for the proposal, I like the direction. Regarding the block syntax: I do think that block support is pretty important, but the way it is introduced in the RFC is not very clear to me. I think part of the problem is that it's a case of either / or. If you have a match that returns a value, but one of the match cases becomes too complicated and would benefit from a temporary variable, you cannot introduce it easily. You have to go all the way from $x = match ($y) { 0 => foo(), 1 => bar(), 2 => baz(), 3 => oof(), }; to match ($y) { 0 => { $x = foo(); }, 1 => { $x = bar(); }, 2 => { $x = baz(); }, 3 => { $tmp = foobar(); // <-- The only new part! $x = oof($tmp); } } While what you really wanted is the Rust-style: $x = match ($y) { 0 => foo(), 1 => bar(), 2 => baz(), 3 => { $tmp = foobar(); oof($tmp) }, }; We already have a similar issue with arrow functions, where adding an extra line requires conversion to a normal closure. This is already not great, but it's a very contained change. Here you may have to refactor a large match expression to incorporate a local change. 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. The alternative is to leave match as a statement only. (If we do not support both expressions *and* statements, then I believe we should only be supporting statements, not the other way around.) Regarding pattern matching: I agree that we shouldn't tackle this topic as part of this proposal, but we do need to already have a pretty firm idea of how that is going to look like to avoid forward-compatibility hazards. It is very easy to run into pattern vs expression ambiguities. The section of your RFC discussing pattern matching tries to avoids most of the problem by prefixing patterns with "let". However, even under that premise there are going to be issues. For example, you have this example: match ($value) { let [1, 2, $c] => ..., // Array pattern } The intention here is clearly that $c is supposed to capture the third array element. 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] => ... } I believe, which is sub-optimal. If we allow arbitrary expressions as match values, then every captured variable would have to be prefixed by let individually to make things work (I think, correct me if I'm missing something here). Another consideration here is that "let" carries a very strong implication of block scoping. Block scoping is something we might well want to have, but I'm not sure we would want it to be bound to pattern matching matching syntax. 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 Some(Enum::A | Enum::B | Enum::C | Enum::D) => ... which are equivalent to Some(Enum::A) | Some(Enum::B) | Some(Enum::C) | Some(Enum::D) => .. Picking "," as separator makes that impossible, as it would cause ambiguities with commas in array patterns, if nothing else. On the other hand, we cannot use "|" if we want to allow arbitrary expressions for match values. (Do we really want that?) Regards, Nikita --000000000000354d9105a3544242--