Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:93115 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 17731 invoked from network); 8 May 2016 16:08:15 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 8 May 2016 16:08:15 -0000 Authentication-Results: pb1.pair.com smtp.mail=php@fleshgrinder.com; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=php@fleshgrinder.com; sender-id=unknown Received-SPF: error (pb1.pair.com: domain fleshgrinder.com from 77.244.243.86 cause and error) X-PHP-List-Original-Sender: php@fleshgrinder.com X-Host-Fingerprint: 77.244.243.86 mx105.easyname.com Received: from [77.244.243.86] ([77.244.243.86:53204] helo=mx207.easyname.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 55/C1-04420-E646F275 for ; Sun, 08 May 2016 12:08:14 -0400 Received: from cable-81-173-133-15.netcologne.de ([81.173.133.15] helo=[192.168.178.20]) by mx.easyname.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1azRFa-0003Az-PV; Sun, 08 May 2016 16:08:11 +0000 Reply-To: internals@lists.php.net References: <4fc01507-3d07-2309-a4e4-4cad7325249b@gmail.com> <39071a01-a42c-0952-b3a8-b4769c79b56b@fleshgrinder.com> <0ac3be89-6fb4-610a-ef89-0928f264f96c@fleshgrinder.com> <71379db5-b7b8-78b3-ada5-eee34e6e22d6@fleshgrinder.com> To: Ryan Pallas , "internals@lists.php.net" Cc: Sara Golemon Message-ID: Date: Sun, 8 May 2016 18:08:05 +0200 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="cdenuIQHAK8AE9ABpMNPmTVLkD8kdpw9m" X-ACL-Warn: X-DNSBL-BARRACUDACENTRAL Subject: Re: [PHP-DEV] [RFC] Pipe Operator From: php@fleshgrinder.com (Fleshgrinder) --cdenuIQHAK8AE9ABpMNPmTVLkD8kdpw9m Content-Type: multipart/mixed; boundary="hs9gGFxkSniwJdUgEfCvLWx7js9tAnATw" From: Fleshgrinder Reply-To: internals@lists.php.net To: Ryan Pallas , "internals@lists.php.net" Cc: Sara Golemon Message-ID: Subject: Re: [PHP-DEV] [RFC] Pipe Operator References: <4fc01507-3d07-2309-a4e4-4cad7325249b@gmail.com> <39071a01-a42c-0952-b3a8-b4769c79b56b@fleshgrinder.com> <0ac3be89-6fb4-610a-ef89-0928f264f96c@fleshgrinder.com> <71379db5-b7b8-78b3-ada5-eee34e6e22d6@fleshgrinder.com> In-Reply-To: --hs9gGFxkSniwJdUgEfCvLWx7js9tAnATw Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 5/3/2016 11:23 PM, Ryan Pallas wrote: > Waiting for what example? There's been plenty of examples showing how > existing options, rewritten with |> are easier. If you disagree, that's= an > opinion, other's agree. If people think its better, why not add it for > them? Like every other feature discussed on this list, nothing is forci= ng > you to use it. >=20 A real world example. :) Nice to have does not necessarily mean that it should be added because designing a language is a hard task and providing two or more ways to achieve something is sometimes good and sometimes bad. I consider this situation bad. That does not mean that I am right and you are wrong, it is simply my opinion. I am also not saying that I would never use it if it is there nor to I feel forced to use it if it is there. I just believe that it is a bad syntactic sugar that encourages bad programming.= On 5/3/2016 11:23 PM, Ryan Pallas wrote: > On Sat, Apr 30, 2016 at 4:00 AM, Thomas Punt wrot= e: >> >> >> $response =3D loadConfig() >> |> buildDic($$) >> |> getApp($$) >> |> getRouter($app) >> |> getDispatcher($$, $request) >> |> dispatchBusinessLogic($$, $request, new Response()) >> |> renderResponse($$) >> |> buildPsr7Response($$) >> |> emit($$); >> >> Without the pipe operator, it could look like the following: >> >> $config =3D loadConfig(); >> $dic =3D buildDic(config); >> $app =3D getApp($dic); >> $router getRouter($app); >> $dispatcher =3D getDispatcher($router, $request); >> $businessResponse =3D dispatchBusinessLogic($dispatcher, $request, new= >> Response()); >> $renderedResponse =3D renderResponse($businessResponse); >> $psr7Response =3D buildPsr7Response($renderedResponse); >> $response =3D emit($psr7Response); >> >> That's a lot of unnecessary assignments, however, and the variable nam= es >> don't even provide any additional readability benefits because the fun= ction >> names are already self-documenting. >> >> > The first example, with |> is much easier to QUICKLY see what's happeni= ng, > because all the function calls are aligned, so I can read quickly top t= o > bottom knowing what's happening. The second requires much more cognitiv= e > interaction to understand what's going on. Sure you could reformat it t= o > align all the =3D, now you have lots of white-space between your variab= les > and what you're assigning to them... equally as bad in my book. >=20 There are no /unnecessary assignments/ because those assignments happen anyways even with the pipe operator. However, at least you have explicit lifetime management. But that is no my problem with that constructed example, it is the fact that it assumes that all of those functions exist but there is no software that defines such functions for those operations. Pretty much all cool kids are using classes for this kind of stuff. But let us assume we do it as proposed. function getGlobals() { // ... } function parseRequest($globals) { // ... } function buildPsr7Request($request) { // ... } function loadConfig() { // ... } function buildDic($config) { // ... } function getApp($dic) { // ... } function getRouter($app) { // ... } function getDispatcher($router, $request) { // ... } function dispatchBusinessLogic($dispatcher, $request, $response) { // ... } function renderResponse($businessResponse) { // ... } function buildPsr7Response($renderedResponse) { // ... } function emit($psr7Response) { // ... } $request =3D getGlobals() |> parseRequest($$) |> buildPsr7Request($$); $response =3D loadConfig() |> buildDic($$) |> getApp($$) |> getRouter($$) |> getDispatcher($$, $request) |> dispatchBusinessLogic($$, $request, new Response()) |> renderResponse($$) |> buildPsr7Response($$) |> emit($$); Suddenly I magically need to know how all of that procedural stuff goes together just to be able to keep it short while calling all of it?!? I hope you understand now why I am still asking for real world examples that are not based on endlessly bad code. On 5/3/2016 11:23 PM, Ryan Pallas wrote: > None, I don't write Symfony apps, however they wrote quite a few [1]. >=20 I was explicitly asking for userland Kernel and not for the base class that Symfony provides. On 5/3/2016 11:23 PM, Ryan Pallas wrote: >> A rather extreme example of such a /most outer/ but you know how it is= >> with constructed examples: >> >> http://www.yegor256.com/2014/10/03/di-containers-are-evil.html#the-rig= ht-way >=20 > GROSS. This would not be allowed any where I do code reviews. >=20 What would be your answer if the author asks /why?/ On 5/3/2016 11:23 PM, Ryan Pallas wrote: > You didn't address the fact that your "solution" makes it much harder t= o > modify the steps in place. >=20 > $ret =3D getConfig() > |> buildApp($$) > |> buildRouter($$) > |> parseResponse($$); >=20 > Shoot, I forgot to build Dispatcher; Let me add that >=20 > $ret =3D getConfig() > |> buildApp($$) > |> buildRouter($$) > + |> buildDispatcher($$) > |> parseResponse($$); >=20 > Such a minimal change. Lets try yours: >=20 > final class ResponseBuilder { > private $config; > private $app; > private $router; > private $response; >=20 > private function loadConfig() {} >=20 > private function buildApp() { > $this->app =3D new App($this->config); > } >=20 > private function buildRouter() { > $this->router =3D new Router($this->app); > } >=20 > private function parseResponse() { > $this->response =3D new Response($this->router); > } >=20 > public function build() { > $this->loadConfig(); > $this->buildApp(); > $this->buildRouter(); > $this->parseResponse(); >=20 > return $this->response; > } > } >=20 > Shoot, I forgot dispatcher; let me add that >=20 > final class ResponseBuilder { > private $config; > private $app; > private $router; > + private $dispatcher; > private $response; >=20 > private function loadConfig() {} >=20 > private function buildApp() { > $this->app =3D new App($this->config); > } >=20 > private function buildRouter() { > $this->router =3D new Router($this->app); > } >=20 > + private function buildDispatcher() { > + $this->dispatcher =3D new Dispatcher($this->router); > + } > + > private function parseResponse() { > - $this->response =3D new Response($this->router); > + $this->response =3D new Response($this->dispatcher); > } >=20 > public function build() { > $this->loadConfig(); > $this->buildApp(); > $this->buildRouter(); > + $this->buildDispatcher(); > $this->parseResponse(); >=20 > return $this->response; > } > } >=20 > Whoa that's significantly more changes, and therefore significantly mor= e > chances to make a typo! >=20 At least the complexity is not completely hidden behind some arbitrary procedural function call. You assume that the procedural function that you are introducing already exists and returns the correct thingy that continues the chain in exactly the order you want it too. Those are a lot of assumptions considering the fact that the pipe operator is meant for combining arbitrary libraries. Sorry, not convinced but a real world example might change that. ;) --=20 Richard "Fleshgrinder" Fussenegger --hs9gGFxkSniwJdUgEfCvLWx7js9tAnATw-- --cdenuIQHAK8AE9ABpMNPmTVLkD8kdpw9m Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBCAAGBQJXL2RpAAoJEOKkKcqFPVVrYPsP/3NNADOISmKsSOOxw5jyz4jt yihhE12gq+nvLxNWudIJHCqgNREyLlk/92mdi7u7cT+DMbcAWL1HlTA5DsvBTLsM M/WY0h0kCrGbOkAY9qDSOIDUL9UmKoBfHlS5S0aINnriF0Zp0yoMY6MLb8uG997M piGxWKoH65YFFsJKqlnn8arggozw1KAAi4V+pkEQeYlPrivkSAIoDWvXghyYix7w iwbnlTM395QZHveMg5p5c6opmsrarA5o4KB/OV8aoXT+g7UKoVM9pxTjtSWFiztO BaYFADpfLd06C4OqUJLJCGzGBZ/DXTXIAggkwtwTMUD0Ys3jUxBwYIdGd20NuH1s G8UauNrodHInO1u4NQyxCPocM7nRsEpMcB4LFjZbU8i2jRbqURcd+HPrSeoyMaI/ 6jvMLLPSIB5FWWksaTPYyjE0QYdXFifYIZ7A6ZkE9Q+3XrOBdTbaKKXW1dOj2Pzg YedPb5G+bb4zPxXP7TRjuw9z30TFr5QKLliiUZ1BIiFDPlYyKyKlGUtPV9U2Y2ss CZJNRHmIgYBxDo2+OcK65rVHiJxoy7OgV8gmBqr0jf0G+nGibRsI0CUzLpdURA4x gJvqbevqHxAhpBqRhV+V7M18mrmWppqwHL43YqFTolr0XsBcPmyN7Q+PqKCS8/V3 hSO57IHzfdr1JJWEwg6b =tAhj -----END PGP SIGNATURE----- --cdenuIQHAK8AE9ABpMNPmTVLkD8kdpw9m--