Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:93018 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 26324 invoked from network); 1 May 2016 11:57:33 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 May 2016 11:57:33 -0000 Authentication-Results: pb1.pair.com header.from=francois@php.net; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=francois@php.net; spf=unknown; sender-id=unknown Received-SPF: unknown (pb1.pair.com: domain php.net does not designate 212.27.42.6 as permitted sender) X-PHP-List-Original-Sender: francois@php.net X-Host-Fingerprint: 212.27.42.6 smtp6-g21.free.fr Received: from [212.27.42.6] ([212.27.42.6:20295] helo=smtp6-g21.free.fr) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id E1/E1-03860-B2FE5275 for ; Sun, 01 May 2016 07:57:32 -0400 Received: from [127.0.0.1] (unknown [82.232.41.54]) (Authenticated sender: flaupretre@free.fr) by smtp6-g21.free.fr (Postfix) with ESMTPSA id C126678038B; Sun, 1 May 2016 10:10:36 +0200 (CEST) To: Rowan Collins , internals@lists.php.net, Sara Golemon References: <4fc01507-3d07-2309-a4e4-4cad7325249b@gmail.com> Message-ID: <5725EF21.90304@php.net> Date: Sun, 1 May 2016 13:57:21 +0200 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.5.0 MIME-Version: 1.0 In-Reply-To: <4fc01507-3d07-2309-a4e4-4cad7325249b@gmail.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Antivirus: avast! (VPS 160501-0, 01/05/2016), Outbound message X-Antivirus-Status: Clean Subject: Re: [PHP-DEV] [RFC] Pipe Operator From: francois@php.net (=?UTF-8?Q?Fran=c3=a7ois_Laupretre?=) Ho Rowan, Le 01/05/2016 01:14, Rowan Collins a écrit : > On 29/04/2016 20:58, Sara Golemon wrote: >> This is one of my favorites out of HackLang. It's pure syntactic >> sugar, but it goes a long way towards improving readability. >> https://wiki.php.net/rfc/pipe-operator > > I like this idea, for the same reason I like chained method calls - the > code reads left to right, rather than inside to outside. > > One problem with that, though, is that the output from the whole > expression ends up on the left, if you want to save it out somewhere. To > take an example from the RFC: > > $ret = scandir($arg) > |> array_filter($$, function($x) { return $x !== '.' && $x != '..'; }) > |> array_map(function ($x) use ($arg) { return $arg . '/' . $x; }, $$) > |> getFileArg($$) > |> array_merge($ret, $$); > > Once you've read through this whole sequence of steps, you have to go > right back to the beginning to find that the result is saved into "$ret". > > It's not clear to me whether the RHS in the current implementation can > be an arbitrary expression, since all the examples use function calls at > every step; would this be valid? > > scandir($arg) > |> array_filter($$, function($x) { return $x !== '.' && $x != '..'; }) > |> array_map(function ($x) use ($arg) { return $arg . '/' . $x; }, $$) > |> getFileArg($$) > |> array_merge($ret, $$) > |> ($ret = $$); > > Even if it is, it looks a bit ugly; what about adding an extra operator > for assignment, like "|>=" or "|=>"? > > scandir($arg) > |> array_filter($$, function($x) { return $x !== '.' && $x != '..'; }) > |> array_map(function ($x) use ($arg) { return $arg . '/' . $x; }, $$) > |> getFileArg($$) > |> array_merge($ret, $$) > |=> $ret; > > > I think this would also improve the situation around debugging and > error-handling, because you could more freely mix piped and non-piped > code by "breaking the chain" with an assigment. > > Let's say I want to add a condition just before getFileArg(); with the > current version I've got to: > - go to the beginning of the chain, and assign to something other than $ret > - go to where I want to break the chain, and reintroduce the $ret > assignment > - add my check in the gap, using the variable I just added at the > beginning of the chain > > $fileList = scandir($arg) > |> array_filter($$, function($x) { return $x !== '.' && $x != '..'; }) > |> array_map(function ($x) use ($arg) { return $arg . '/' . $x; }, > $$); > if ( someCheck($fileList) { > something(); > } > $ret = getFileArg($$) > |> array_merge($ret, $$); > > The syntax is fighting me here, making me jump around the code. But if > assignment was always on the end of the chain, I would only need to make > changes at the point where I was breaking the chain. The basic pattern > would be: > > |=> $tempVar; // terminate the chain and capture the value > // do stuff with $tempVar > $tempVar // restart the chain > > So: > > scandir($arg) > |> array_filter($$, function($x) { return $x !== '.' && $x != '..'; }) > |> array_map(function ($x) use ($arg) { return $arg . '/' . $x; }, $$) > |=> $fileList; > if ( someCheck($fileList) { > something(); > } > $fileList > |> getFileArg($$) > |> array_merge($ret, $$) > |=> $ret; > > If I don't need the condition any more, I can delete lines 4 to 8, and > I've got back my original chain. > > > Again, I'm not clear from the RFC if it's currently valid to use > "return" in a piped expression, but it makes sense to me for the same > reasons outlined above. This example is from the Hack docs, where it > puts the "return" on the left, breaking the flow: > > return $arr > |> array_map($x ==> $x->getNumber(), $$) > |> array_filter($$, $x ==> $x % 2 == 0) > |> count($$); > > To me, that reads better as: > > $arr > |> array_map($x ==> $x->getNumber(), $$) > |> array_filter($$, $x ==> $x % 2 == 0) > |> count($$) > |> return $$; > > > Personally, I'd quite like it if the chain *had* to have a left-to-right > form like this, and always constituted a statement, not an expression. > > Regards, > I find your suggestion brilliant, including ending with a 'return' statement. Just a question : do we really need a different operator ? I may be wrong but '|> $ret' or '|> return $$' doesn't seem ambiguous to me (the parser should be able to recognize an assignable LHS or 'return'). I even suggest we use a '... |> $var |> ...' syntax to assign intermediate variables. I am currently writing a message proposing a way to complement these 'piped calls' with a way to get rid of the '$$' placeholder. This will address the long-running sadness of argument order. Regards François