Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:109291 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 87523 invoked from network); 25 Mar 2020 15:53:04 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 25 Mar 2020 15:53:04 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id AB25C1804D0 for ; Wed, 25 Mar 2020 07:17:42 -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_H3,RCVD_IN_MSPIKE_WL,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-ot1-f44.google.com (mail-ot1-f44.google.com [209.85.210.44]) (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, 25 Mar 2020 07:17:42 -0700 (PDT) Received: by mail-ot1-f44.google.com with SMTP id 22so2080774otf.0 for ; Wed, 25 Mar 2020 07:17:42 -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=QhF009EU2zEq8FpUlm0KDVwFTpAYSCTY4k4i+v2FKPI=; b=j1ui/ZEGtQ6y6pkx9bulBb8hU419vyjEaHv57yr0JNJbDEQvF4SRHcqIFq6AcPWBvI +Kc40KCcb/OO+3sT25yenyok8+D8nbNGW4gaYWCIEMGv+NPslHYg9QE1pF/b7yjHPq8B tG6//Tua0BRoi0zgK1hqsAFF2lg8NPWFp7uO0StwhVtpOvvFOn7eGnx5DGiwpfoxvDCx LVOkwhYZarlWXVlDXMJKxmqWD6KOZ8YRZcDvfjhTWRuMihl1de6eYKBR/cRFaJfcWMYV V3MGBGadu77NqnNXdmBTN4pAR0oLZ/SOwRIk81bI+JmKb7ky119yEw87G/sCYn3ZNyhf hPog== 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=QhF009EU2zEq8FpUlm0KDVwFTpAYSCTY4k4i+v2FKPI=; b=e6vd4G/90LyqM0eTaHXqKJe4nJibWKupocrZttda1YKCv+9QXaBxdZzTBN1avvHCij PASo8mhRnys0CeurlKuJfdKavesyxF8lDQdQVVyNqByvIIB3XzoUpjkjM5QPr6YoVELZ Y7uwCtdANKVLASdec29HUsRALr6H8MvRBVR793koXasClwVVSCf8UzysjkBV/laVJFjg M05hs99kaSwhp6OKdV7zzFyZtkVkAziHFzRhJyk/FoyeSxibv2gVmIsNmuMKZsgO8i0F /hqT5Jb2sMcZfOPCKj3+o+f5VGFlRbIJsFBsJZNTdRBrKnlFFyaO66k67P18l5EBeO4J qibw== X-Gm-Message-State: ANhLgQ2r8mFOsWtKUTiSMJQRMLCYUbe7iwYaYCVY2g5IQAnEmizlp2Rd 8VZsOLvtv7nY97YAHMpu/x8BJxy3wz/E5pwclqY= X-Google-Smtp-Source: ADFU+vv7ByiQeTsEx9wVbNQGrZSDG11m8gdfQYkuzv1oAp/2066gtpDbaZYDEqN2Mrl2ULp+miKa/UXum2zA+sOApRo= X-Received: by 2002:a9d:5781:: with SMTP id q1mr2733903oth.258.1585145858352; Wed, 25 Mar 2020 07:17:38 -0700 (PDT) MIME-Version: 1.0 References: <047092C7-84FB-42AB-8084-7B83F76F55C1@me.com> In-Reply-To: <047092C7-84FB-42AB-8084-7B83F76F55C1@me.com> Date: Wed, 25 Mar 2020 15:17:26 +0100 Message-ID: To: Ilija Tovilo Cc: PHP Internals List Content-Type: multipart/alternative; boundary="000000000000cdf11905a1ae87b1" Subject: Re: [PHP-DEV] [RFC] switch expression From: michal.brzuchalski@gmail.com (=?UTF-8?Q?Micha=C5=82_Brzuchalski?=) --000000000000cdf11905a1ae87b1 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Ilija, =C5=9Br., 25 mar 2020 o 13:10 Ilija Tovilo napisa=C5= =82(a): > Hi everybody! > > > > A few years ago I suggested adding a new `match` expression to the PHP > language: > > https://externals.io/message/100487 > > > > I arrogantly assumed someone will implement it for me which of course > didn't happen. I'd finally like to get my own hands dirty. I have a very > rough, incomplete prototype but I'd like to get your feedback before I > continue working on the details. > > > > # Introduction > > > > This is what it looks like: > > > > ```php > > echo $i switch { > > 0 =3D> "i equals 0", > > 1 =3D> "i equals 1", > > 2 =3D> "i equals 2", > > 3, 4 =3D> "i equals 3 or 4", > > }; > > > > // is roughly equivalent to > > > > switch ($i) { > > case 0: > > $tmp =3D "i equals 0"; > > break; > > case 1: > > $tmp =3D "i equals 1"; > > break; > > case 2: > > $tmp =3D "i equals 2"; > > break; > > case 3: > > case 4: > > $tmp =3D "i equals 3 or 4"; > > break; > > default: > > throw new InvalidArgumentException('Unhandled switch case'); > > } > > > > echo $tmp; > > ``` > > > > Some things to note: > > > > * Each case only accepts a single expression > > * The entire switch expression evaluates to the result of the executed ca= se > > * There is no fallthrough, an implicit break is added after every case > > * Multiple case conditions are possible with comma separation > > * The default case throws a InvalidArgumentException by default > > * The switch keyword is used as an infix operator > > > > # Syntax > > > > Originally, I expected to reuse the current syntax and transform it into > an expression. > > > > ```php > > $x =3D switch ($y) { ... }; > > ``` > > > > Turns out this is ambiguous. > > > > ```php > > switch ($y) { ... } > > [$a] =3D ...; > > > > // Could also be interpreted as > > switch ($y) { ... }[$a] =3D ...; > > ``` > > > > I stole the new syntax from C# 8.0 which means at least some people will > already be familiar with it: > > > https://docs.microsoft.com/en-us/archive/msdn-magazine/2019/may/csharp-8-= 0-pattern-matching-in-csharp-8-0#the-evolution-of-pattern-matching-in-c-80 > > > > # Type coercion > > > > One of the bigger weak points of the `switch` statement is the fact that > it performs implicit type coercion. > > > > ```php > > switch ('foo') { > > case 0: > > echo "Oh no!\n"; > > } > > ``` > > > > While it's very tempting to fix this in the new `switch` expression it > adds a confusing discrepancy between the `switch` statement and expressio= n. > I think it would be preferrable to keep the two the same and change the > behavior of both in a new PHP edition ( > https://github.com/php/php-rfcs/pull/2). > > > > # Pattern matching > > > > I decided against pattern matching because PHP doesn't have algebraic dat= a > types and classes rarely have public properties. In my opinion the limite= d > use cases don't justify the significant complexity added to the language. > It would also, once again, add an unjustified discrepancy between the > `switch` statement and expression. If at some point we do want to introdu= ce > pattern matching it might be better to introduce a different keyword (e.g= . > `match`) and make it work for both the statement and expression. In case > you need to match a more complex expression the following still works fin= e: > > > > ```php > > echo true switch { > > is_int($x) =3D> 'int', > > is_float($x) =3D> 'float', > > is_string($x) =3D> 'string', > > ... > > }; > > ``` > > > > # Blocks > > > > Sometimes it would be useful to split the expression into multiple > statements to make it more readable. Unfortunately, in PHP there are no > block expressions. Rust allows returning the last value by omitting the > semicolon: > > > > ```php > > echo $x switch { > > 1 =3D> { > > foo(); > > bar(); > > baz() > > }, > > }; > > ``` > > > > This is indeed possible in PHP and could be implemented as part of the > `switch` expression or as a general language feature. A nice side effect = is > that this could also be used in arrow functions: > > > > ```php > > $x =3D fn() =3D> { > > foo(); > > bar(); > > baz() > > }; > > ``` > > > > This would, however, make it inconsistent with closures as they use the > return keyword. Thus we would probably have to make sure arrow functions > still work with return statement which would decrease the need for such a > language construct. It is also very unlike anything else in PHP. > > > > # Poll > > > > This is a short overview of what I'll be working on in the coming weeks. = I > created a short poll for you guys to let me know if this idea is worth > pursuing: > > https://forms.gle/stXMv72CAaDDxfwf8 > > > > Stay safe! > > That looks like what I've described a few months ago in https://wiki.php.net/rfc/switch-expression-and-statement-improvement If you dig into the mailing list you can even find almost ready to use patch which implements it. I'd love switch expression inclusion in PHP. Cheers, Micha=C5=82 Brzuchalski --000000000000cdf11905a1ae87b1--