Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:100502 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 17796 invoked from network); 10 Sep 2017 14:43:25 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 10 Sep 2017 14:43:25 -0000 Authentication-Results: pb1.pair.com header.from=rowan.collins@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=rowan.collins@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 74.125.82.66 as permitted sender) X-PHP-List-Original-Sender: rowan.collins@gmail.com X-Host-Fingerprint: 74.125.82.66 mail-wm0-f66.google.com Received: from [74.125.82.66] ([74.125.82.66:34991] helo=mail-wm0-f66.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id C1/5E-10715-B8F45B95 for ; Sun, 10 Sep 2017 10:43:23 -0400 Received: by mail-wm0-f66.google.com with SMTP id e64so4985440wmi.2 for ; Sun, 10 Sep 2017 07:43:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-transfer-encoding; bh=u63vIMIvcDADvOZBCrZXnvPnazPJBPsnECqh8YKU8Ko=; b=iv2X1EfRIGnRUKqTl9uYNVnS2R1QxrDmPFWYdJRoQBo+e0JhmNinZEgjPevn5hSUu8 YbSuAhQ/tuKqjPU4kjy9NmgpXUwucFkgFfhe4AN62xoDQGBjfidwC2Jq8OQV6GrIYk41 b13zuuw78S7dWML8SHPkuaK0pIFxbb96nqM8sdU4L7IWENNRQoyOBezGVmSYr4nnDYFh yyrYNjyabpDrELTPxJM/4MGA3vqOo/4H5gWjoYsu5RXJz1mdAspNbd1AVRO4tN1yvRR2 k+W4BbNjmus2ZDLYFTSrlJKuZKtLysc6L+pYgc1mquZ61vIuXI9eHgvVuDa7K7V/I3Vq q84g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding; bh=u63vIMIvcDADvOZBCrZXnvPnazPJBPsnECqh8YKU8Ko=; b=LfZ1/CWzICqZia06A0ttS5hbiAKXH6UHyom0OCQgqu8meXTC/QFn4qu2xBqiLRnQeD P95d3dOXes1Pu9mwQYgiv8yTVGeq3TUOEEHIM5hsj/j4IxtW6n/gIdNhkTH6YooWFu8T AtWNG93e8FzofenUVBNz5GP2VdhO2PBRmEq1Ne79/20UAXvohYTyAQ9n7wJXoZyPODF/ f1Z0znDEPHRgcjxOqNEYw3qTp//QxG+oWC4QOnxGrF7jD/jHySXyv+hVvNHRDXM2yTJu EB5I79p1cpoBbzMG24dbIKNka5VZ+nMfA1ssqlSeKW74JGRgcCvYgz8H0MGdlZ0vu72z viRQ== X-Gm-Message-State: AHPjjUjExxwVZrad8n7Ls++EIOuRnhc6kZDgN/jQlYPSiygLFwSjlf6f GbgXVmO6y06iRaGE X-Google-Smtp-Source: ADKCNb4UHPtlagNIMVWrDRM56GoNjpxnqzzsjVchaXoIXw4hs2vXd097f2CmVFpDefsjHiCWTe8f8A== X-Received: by 10.80.194.9 with SMTP id n9mr2451481edf.17.1505054600079; Sun, 10 Sep 2017 07:43:20 -0700 (PDT) Received: from ?IPv6:2a00:23c4:4b81:ae00:897b:9022:b7c6:ef8? ([2a00:23c4:4b81:ae00:897b:9022:b7c6:ef8]) by smtp.googlemail.com with ESMTPSA id z12sm2114500edz.78.2017.09.10.07.43.18 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 10 Sep 2017 07:43:19 -0700 (PDT) To: internals@lists.php.net References: Message-ID: <85e5039e-f50e-6c02-ce41-d2d586bf909a@gmail.com> Date: Sun, 10 Sep 2017 15:43:18 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Subject: Re: [PHP-DEV] [RFC] Match expression From: rowan.collins@gmail.com (Rowan Collins) On 09/09/2017 12:21, ilija.tovilo@me.com wrote: > Hi everybody! > > Has this idea been discussed before? > > I find myself writing switch statements in PHP quite rarely. This has a few reasons: > > 1. It doesn’t have a "strict_types” version > 2. It is quite verbose (lots of breaks) > 3. It is a statement rather than an expression > > Often, if / elseif statements turn out to be shorter, safer and easier to read than the switch statement. I've had the idea kicking around my head for some time of a "switch-use" statement. I keep hoping to find the time to play around with the PHP parser and see if I can write a proof of concept implementation, just as an excuse to get deeper into the source, but since this has come up, I'll outline the idea. The general form would be "switch ( expression ) use ( op ) { ... }", where "op" is any binary operator which gives a boolean result, and the rest looks the same as a normal PHP switch statement. The simplest example would be to do a strict comparison by using "===": switch ( someFunction() ) use ( === ) { case 42: // ... break; case '42': // ... break; } Which would approximately de-sugar to: $temp = someFunction(); switch ( true ) { case $temp === 42: // ... break; case $temp === '42': // ... break; } As you can see, the switch(true) version has to use an explicit variable to avoid re-computing the expression, which switch does for you, and you then have to repeat the "$temp ===", obscuring the fact that all cases are checking the same thing. A normal switch, however, can't distinguish 42 from '42', because it uses the == comparison rules. If this were the only useful operator, we might just call it "switch strict" or something, but here are a couple of examples with other operators: // Generic exception handling function // Also useful when accepting various incompatible implementations of something and wrapping or converting them switch ( $e ) use ( instanceof ) { case FooException: case BarException: // ... break; case SomeOtherException: // ... break; } // Dividing a circle into arbitrary sectors, based on this Stack Overflow question: https://stackoverflow.com/q/44183771/157957 // Note the ability to place "default" at the top, rather than duplicating code in an else clause switch ( $angle ) use ( <= ) { case 30: default: return Direction::Right; break; case 60: return Direction::UP_RIGHT; break; case 120: return Direction::UP; break; case 150: return Direction::UP_LEFT; break; case 210: return Direction::LEFT; break; case 240: return Direction::DOWN_LEFT; break; case 300: return Direction::DOWN; break; case 330: return Direction::DOWN_RIGHT; break; } There are a couple of ways to expand this further, if we wanted: * Allow operators whose result isn't strictly a boolean, such as bitwise & * Allow any 2-parameter callable in place of an operator, to have more complex comparisons. With Andrea's "operator functions" suggestion, operators would technically just be a subset of this anyway. The below would be quite useful, but unfortunately preg_match takes ($pattern, $subject) and this would need ($subject, $pattern), so you'd need some extra transform: switch ( $message ) use ( 'preg_match' ) { case '/^Missing parameter:/': case '/^Unexpected parameter:/': return self::MALFORMED_REQUEST; break; case '/.*try again later.$/': return self::TEMPORARY_ERROR; break; } Any thoughts? Regards, -- Rowan Collins [IMSoP]