Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:109897 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 59157 invoked from network); 29 Apr 2020 01:55:14 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 29 Apr 2020 01:55:14 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 839881804C7 for ; Tue, 28 Apr 2020 17:28:32 -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.6 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS11403 64.147.123.0/24 X-Spam-Virus: No X-Envelope-From: Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Tue, 28 Apr 2020 17:28:31 -0700 (PDT) Received: from compute7.internal (compute7.nyi.internal [10.202.2.47]) by mailout.west.internal (Postfix) with ESMTP id D67E2913 for ; Tue, 28 Apr 2020 20:28:30 -0400 (EDT) Received: from imap26 ([10.202.2.76]) by compute7.internal (MEProxy); Tue, 28 Apr 2020 20:28:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; bh=X5Cs3q 6Qi7KG4u48TQ3JnRH/UCBeVzGyecW/JesQz9E=; b=rXcnzZQuXr/d1C1LH2Tog0 aEVrhEZgcF4B/bljHcuzEQzDN96pKJQgcIyMbsAzMEqWTmReVQKD1rsPB9Na7zup wXtajaFV8bMGsoHHUHUl3yGfXfA1+Z/PJKHuMlNmNa9wbRQoNd4Fc0ci4CZqeRoi VsRsovMQrSb5dw//OEX9fbqGhZqwVpOh6IP/+YveURZoGIuxyskJg5+dkf142hyW 1y+O7mZg/oMyCQYTN1iP66i1kmlJ9q4TNk4Dv1rDboRxhDtQ2L3LIeJHCW2LC9h+ Z/qQQYPeYU72OwWNvmFud0huu2sVxGkuXgX8YmN74yavrnJOXCfCL8yGUplGFtLA == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduhedriedvgdeffecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefofgggkfgjfhffhffvufgtsehttdertderredtnecuhfhrohhmpedfnfgrrhhr hicuifgrrhhfihgvlhgufdcuoehlrghrrhihsehgrghrfhhivghlughtvggthhdrtghomh eqnecuffhomhgrihhnpehgihhtsghoohhkshdrihhopdhgohgshigvgigrmhhplhgvrdgt ohhmnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheplh grrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhm X-ME-Proxy: Received: by mailuser.nyi.internal (Postfix, from userid 501) id 1F8C414200A2; Tue, 28 Apr 2020 20:28:30 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.3.0-dev0-351-g9981f4f-fmstable-20200421v1 Mime-Version: 1.0 Message-ID: <969c6150-a084-48c0-ae8f-b8043dce321d@www.fastmail.com> In-Reply-To: References: <5ea6e4b0.1c69fb81.cf3ee.2bbfSMTPIN_ADDED_MISSING@mx.google.com> Date: Tue, 28 Apr 2020 19:26:59 -0500 To: "php internals" Content-Type: text/plain Subject: Re: [PHP-DEV] [VOTE] match expression From: larry@garfieldtech.com ("Larry Garfield") On Tue, Apr 28, 2020, at 10:31 AM, Rowan Tommins wrote: > On Tue, 28 Apr 2020 at 16:10, Bob Weinand wrote: > > > I think you should first think about why the "case" needs to exists at > > all. In particular it exists to distinguish goto labels from the case > > expressions in switch. With match, match restricting statements (and thus > > goto labels) into { brackets }, it now is not necessary to do such a > > distinction and we can get rid of the extra token. > > > > > That may be obvious if you're used to writing parsers, but to users, the > case keyword is simply how switch statements work. Removing it just makes > the new statement look less familiar and isn't justified by the aims stated > in the RFC. > > > > > "=>" is logical as well, we use the return value of the expressions (see > > fn() and array syntax), the colon is exclusively used for pure statement > > boundaries. > > > > > You've missed the context of my e-mail: I was explicitly discussing a > hypothetical syntax that *doesn't* resolve to a value, and where the colon > *is* introducing a statement not an expression. > > > > > The comma is necessary for the expression syntax at least (consider > > match($a) { 1 => 2 + 2 + 2 => 3 } - is this now match($a) { 1 => 2, (2 + > > 2) => 3 } or match ($a) { 1 => (2 + 2), +2 => 3 } ?) You may argue to make > > it optional behind a statement block though. > > > > Again, expressions are explicitly out of scope for this thought experiment. > As such, the result of every case is delimited either by a closing brace or > a semi-colon, and the above example is simply a syntax error. > > > As I've said many times now, I really like the match expression, with the > current syntax, as a pure expression. I was explicitly addressing the > question of why I think a straight-forward switch replacement would not > look the same if we weren't trying to squeeze two features into one syntax. > > Regards, > -- > Rowan Tommins > [IMSoP] I agree that there seems to be two entirely different problem spaces being smushed together here, which is creating a problem (both for the code and for the discussion). Which... suggests we really should try to split them up. To that end, I'm going to refer to them as rustmatch (an expression that only supports expressions and returns things; basically a fancier alternative to ternary) and switchtng (a procedural branching statement that is basically switch but with the lessons of the 40 years since C switch was invented, which PHP blindly inherited) to avoid privileging one or the other. Based on the current RFC voting, it seems like there's strong interest in rustmatch, using the syntax currently proposed: $expressionResult = match ($condition) { 1, 2 => foo(), 3, 4 => bar(), default => baz(), }; I'm calling this "rustmatch" because its semantics and syntax are largely borrowed from Rust's match expression (https://aminb.gitbooks.io/rust-for-c/content/control_flow/index.html). (Yes, Rust supports multi-line expressions but it does all over the place, which is a separate issue.) The other is what, I think, Ilja was originally trying to do, which is a more Go-style switch (https://gobyexample.com/switch) than a C-style switch. That is, still a procedural construct but less bug-prone. One issue that was discussed a few weeks ago, and led to the current syntax, was too many variations within the switch syntax; of course, trying to do it all in one syntax is perpetuating that problem. However, I think Rowan has suggested a syntax that may be sufficiently self-documenting. To wit, independent of rustmatch (above): switch ($foo) { case 1: { Many statements here. } case 2: { Many statements here. } } The curly braces are already understood by most PHPers to mean "a block of statements", and so it's a logical jump in this case. As Rowan suggests, the {} imply a break. To keep it simple we should probably not allow mixing and matching in a single switch. Either list-style (break required) or {}-style (break implied). That handles break; the other problems listed in the RFC for switch are: * weak comparison * Inexhaustive * No return The no-return is only an issue for the expression-centric approach, which belongs to rustmatch, and thus in a split approach is off topic. If you want multi-prong branching that evaluates to a returned value... use the rustmatch option and be done with it, go away. For the other two, would a simple "strict" keyword be acceptable to people? The net result being: switch strict ($foo) { case 1: { Many statements here. } case 2: { Many statements here. } } That does a strict type comparison on $foo, triggers a warning/error/whatever if nothing matches (default is still supported of course), and the curly braces replace break. It can NOT return anything, but that's OK, because it's a flow control construct, not an expression. Never the twain shall meet. If this seems reasonable to folks, particularly Ilja, I'd suggest pulling the current vote/letting it expire, and then reintroducing it as *just* an expression, with single-expressions only, semi-colon required always, and an implicit default match value of true (as the current polls very strongly indicate; thank you Ilja for including the extra data gathering). Then in parallel introduce a second RFC that adds the strict keyword and {} alternative, and *nothing else*. Let that have its own, separate vote. Based on the current voting I strongly suspect the more limited match expression v2 would pass easily. I don't know if the strict switch would pass or not, but it would at least be able to get a fair shake on its own without trying to do double-duty as an expression and a statement at the same time, which the current RFC is trying to do. --Larry Garfield