Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126342 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id F17A11A00BC for <internals@lists.php.net>; Fri, 7 Feb 2025 21:04:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1738962109; bh=ZYCXcGaKFMOsDF4w+rLsVlm51bXG2wkUW5IKC1NHGao=; h=Date:From:To:In-Reply-To:References:Subject:From; b=mepHMMgPtMhXZ+YWlC1CqU6h67hT1wzb98tMPSFrrEpHxNj1G2E0MEMEch+o93DK+ 1zXqEzgR7Ai8ImmUR6WAolqsjrGAd/EjJAJt3z9LKUTNJafIb4t9VpKDSxwJy2CLeb dUmfdQguTBEs8YfvvulX1OflTVWCnj+jAa3niKX+Pj0tWGKbIm3CbrDNbjjpKJnWGc HEs+TYclwv9L6lVfSO4wa8onmaMezyAybtlJiXC2qf5pM96iBSph31OThfTeA6Pbph EzTTY/tltr4prtTNp0JKGs9HQB3Bn/CwUEX+puOBxgHtIGDIBflLZP/K2qORzH6B/U +ov/OM+GMbrSA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id CF845180086 for <internals@lists.php.net>; Fri, 7 Feb 2025 21:01:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,RCVD_IN_DNSWL_LOW, SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: <larry@garfieldtech.com> Received: from fout-b8-smtp.messagingengine.com (fout-b8-smtp.messagingengine.com [202.12.124.151]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for <internals@lists.php.net>; Fri, 7 Feb 2025 21:01:48 +0000 (UTC) Received: from phl-compute-01.internal (phl-compute-01.phl.internal [10.202.2.41]) by mailfout.stl.internal (Postfix) with ESMTP id A201D11400FD for <internals@lists.php.net>; Fri, 7 Feb 2025 16:04:32 -0500 (EST) Received: from phl-imap-06 ([10.202.2.83]) by phl-compute-01.internal (MEProxy); Fri, 07 Feb 2025 16:04:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= garfieldtech.com; h=cc:content-transfer-encoding:content-type :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to; s=fm3; t=1738962272; x=1739048672; bh=t3TZNPRe+6jNwcGpwqIY+ hsKJeVrBeKUbDo1G/a/wdQ=; b=AwpYS7ywl3ALkvYsf6FxSUzgS+SD2QcCZ6dv7 wplx+h8jHToG4MeQkkRYDuEdkxJFGS2mDmJM5CPnyysMCD2Dm9+ZP27ZkWSskmct kKlSOcz2LKbXl8e6Ua8TZQ/hf5q5KF/3SeuU3ahIBLtblTQtEMX0IoUg+pTmd/J6 zDpQDsXMJyiwh9D0ZjQYyG1ku9Dn49MzU9nbT49Fvt6y/SXeQ3Hx9kynvbkuoJkS nVS51SiG79UzKo7Ardh3qhps9bJjItv1bkQHE9tl9c2sflB7rufuLkiKa/4hz6Cd EfAqKR9STooMM7QacI7RGCSKJgUdaFjuu8VlJHnSVHLQQZZQw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1738962272; x=1739048672; bh=t 3TZNPRe+6jNwcGpwqIY+hsKJeVrBeKUbDo1G/a/wdQ=; b=NuhWqxwTISHQTiBvO ZQ4WwNHQJldnj16brskUsw1UT1NTETlPtyfuYJH2FxqdyewNEwbUoVG3VIQH16jS VgqNHYAqcvRwKYoYhvSQhCe1KutlCwP02wbEtYWuAXrrCz8y0G0A4wV/IaRx2ZQO hewSg94tjp8xEwHwGjh3kSAHTdUiDCO7ANpTNECIMumh2w/eURw1hlRs2wVsyDpo +9L5mlUWamIC76Ge8/cPRSboK03Z4RYeskbVWozNQdOM3auklSyofMIOIEc5poTa DRzDF/Azzjwlo9/9GYefWSkI4uSwXQ8t+iyOkpRhHeqaqa0193Y0V3g6An58Td83 dSpSg== X-ME-Sender: <xms:YHWmZ0xhjsJryKyKPnhrvfcwQa4tp5WD4lfZBjLulYNjT3tpU8_yFQ> <xme:YHWmZ4TRD6SIhFVc5Ava72sPw_U0eXXUD86-a04uHNdTR6MTHebVxlvpPut0YlkdW WJ79S9AjzIUjQ> X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdeftdefvdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdp uffrtefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivg hnthhsucdlqddutddtmdenucfjughrpefoggffhffvkfgjfhfutgfgsehtqhertdertdej necuhfhrohhmpedfnfgrrhhrhicuifgrrhhfihgvlhgufdcuoehlrghrrhihsehgrghrfh hivghlughtvggthhdrtghomheqnecuggftrfgrthhtvghrnhepleduvdduleekieejkeeu kefgvdeifeelveevjeefhfeftdeugfduieeuheffleeknecuffhomhgrihhnpehphhhprd hnvghtpdhgihhthhhusgdrtghomhenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgr mhepmhgrihhlfhhrohhmpehlrghrrhihsehgrghrfhhivghlughtvggthhdrtghomhdpnh gspghrtghpthhtohepuddpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtohepihhnthgv rhhnrghlsheslhhishhtshdrphhhphdrnhgvth X-ME-Proxy: <xmx:YHWmZ2UlCabjm3HkqNSLo9snPIfg2KSVjlxcyCFoRc7Fj50JLmz8qQ> <xmx:YHWmZygWfT2X9kFFBHNyEF1Y6H-0QwCw9ooYAfVDmVg2z83SSXsU-A> <xmx:YHWmZ2AjTukWMGu4Wiz2pbqvh03mkc1kC7bvDNnHwsx8tyLBpV4s_Q> <xmx:YHWmZzLsc-caTZe0ULIHZ4bLEbB1SU6_GqScy5w3nHddWFJ5e7utng> <xmx:YHWmZ98wA62SYzM6heGcHGlZPZ6jzWxX6dBg02Wti5YIMpA4SPY92geM> Feedback-ID: i8414410d:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id EFCB129C006F; Fri, 7 Feb 2025 16:04:31 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface Precedence: bulk list-help: <mailto:internals+help@lists.php.net list-unsubscribe: <mailto:internals+unsubscribe@lists.php.net> list-post: <mailto:internals@lists.php.net> List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Date: Fri, 07 Feb 2025 15:04:11 -0600 To: "php internals" <internals@lists.php.net> Message-ID: <bd93bbb9-e970-4211-af59-4ccd643dc52f@app.fastmail.com> In-Reply-To: <5a584219f120385e7e30f6d0a46cc108@bastelstu.be> References: <de8140ab-0941-45cd-ba20-4aece2f69aea@app.fastmail.com> <5a584219f120385e7e30f6d0a46cc108@bastelstu.be> Subject: Re: [PHP-DEV] [RFC] Pipe Operator (again) Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable From: larry@garfieldtech.com ("Larry Garfield") Merging a few replies together here, since they overlap. Also reorderin= g a few of Tim's comments... On Fri, Feb 7, 2025, at 7:32 AM, Tim D=C3=BCsterhus wrote: > Hi > > Am 2025-02-07 05:57, schrieb Larry Garfield: >> It is now back with a better implementation (many thanks to Ilija for=20 >> his help and guidance in that), and it's nowhere close to freeze, so=20 >> here we go again: >>=20 >> https://wiki.php.net/rfc/pipe-operator-v3 > > There's some editorial issues: > > 1. Status: Draft needs to be updated. > 2. The RFC needs to be added to the overview page. > 3. List formatting issues in =E2=80=9CFuture Scope=E2=80=9D and =E2=80= =9CPatches and Tests=E2=80=9D. > > Would also help having a closed voting widget in the =E2=80=9CProposed= Voting=20 > Choices=E2=80=9D section to be crystal clear on what is being voted on= (see=20 > below the next quote). I split pipes off from the Composition RFC late last night right before = posting; I guess I missed a few things while doing so. :-/ Most notably= , the Compose section is now removed from pipes, as it is not in scope f= or this RFC. (As noted, it's going to be more work so has its own RFC.)= Sorry for the confusion. I think it should all be handled now. > 5. The =E2=80=9CReferences=E2=80=9D (as in reference variables) sectio= n would do well=20 > with an example of what doesn't work. Example block added. > 9. In the =E2=80=9CWhy in the engine?=E2=80=9D section: The RFC makes = a claim about=20 > performance. > > Do you have any numbers? Not currently. The statements here are based on simply counting the num= ber of function calls necessary, and PHP function calls are sadly non-ch= eap. In previous benchmarks of my own libraries using my Crell/fp libra= ry, I did find that the number of function calls involved in some tight = pipe operations was both a performance and debugging concern, but I don'= t have any hard numbers laying about at present to share. If you think that's critical, please advise on how to best get meaningfu= l numbers here. Regarding the equivalency of pipes: Tim D=C3=BCsterhus wrote: > 4. =E2=80=9CThat is, the following two code fragments are also exactly=20 > equivalent:=E2=80=9D. > > I do not believe this is true (specifically referring to the =E2=80=9C= exactly=E2=80=9D=20 > word in there), since the second code fragment does not have the short=20 > closures, which likely results in an observable behavioral difference=20 > when throwing Exceptions (in the stack trace) and also for debuggers. = Or=20 > is the implementation able to elide the the extra closure? (Of course=20 > there's also the difference between the temporary variable existing,=20 > with would be observable for `get_defined_vars()` and possibly=20 > destructors / object lifetimes). Thomas Hruska wrote: > The repeated assignment to $temp in your second example is _not_=20 > actually equal to the earlier example as you claim. The second exampl= e=20 > with all of the $temp variables should, IMO, just be: > > $temp =3D "Hello World"; > $result =3D array_filter(array_map('strtoupper',=20 > str_split(htmlentities($temp))), fn($v) { return $v !=3D 'O'; }); Juris Evertovskis wrote: > 3. Does the implementation actually turn `1 |> f(...) |> g(...)` into=20 > `$=CF=80 =3D f(1); g($=CF=80)`? Is `g(f(1))` not performanter? Or is t= he engine=20 > clever enough with the var reuse anyways? There's some subtlety here on these points. The v2 RFC used the lexer t= o mutate $a |> $b |> $c into the same AST as $c($b($a)), which would the= n compile as though that had been written in the first place. However, = that made addressing references much harder, and there's an important ca= veat around order of operations. (See below.) The v3 RFC instead uses a= compile function to take the AST of $a |> $b |> $c and produce opcodes = that are effectively equivalent to $t =3D $b($a); $t =3D $c($t); I have= not compared to see if they are the precise same opcodes, but they net = effect is the same. So "effectively equivalent" may be a more accurate = statement. In particular, Tim is correct that, technically, the short lambdas would= be used as-is, so you'd end up with the equivalent of: $temp =3D (fn($x) =3D> array_map(strtoupper(...), $x))($temp); I'm not sure if there's a good way to automatically unwrap the closure t= here. (If someone knows of one, please share; I'm fine with including i= t.) However, the intent is that it would be largely unnecessary in the = future with a revised PFA implementation, which would obviate the need f= or the explicit wrapping closure. You would instead write $a |> array_map(strtoupper(...), ?); Alternatively, one can use higher order user-space functions already. I= n trivial cases: function amap(Closure $fn): Closure { return fn(array $x) =3D> array_map($fn, $x); } $a |> amap(strtoupper(...)); Which I am already using in Crell/fp and several libraries that leverage= it, and it's quite ergonomic. There's a whole bunch of such simple higher order functions here: https://github.com/Crell/fp/blob/master/src/array.php https://github.com/Crell/fp/blob/master/src/string.php Which leads to the subtle difference between that and the v2 implementat= ion, and why Thomas' statement is incorrect. If the expression on the r= ight side that produces a Closure has side effects (output, DB interacti= on, etc.), then the order in which those side effects happen may change = with the different restructuring. With all pure functions, that won't m= ake a practical difference, and normally one should be using pure functi= ons, but that's not something PHP can enforce. I don't think there would be an appreciable performance difference betwe= en the two compiled versions, either way, but using the temp-var approac= h makes dealing with references easier, so it's what we're doing. Juris Evertovskis wrote: > 1. Do you think it would be hard to add some shorthand for `|>=20 > $condition ? $callable : fn($=F0=9F=98=90) =3D> $=F0=9F=98=90`? I'm not sure I follow here. Assuming you're talking about "branch in th= e next step", the standard way of doing that is with a higher order user= -space function. Something like: function cond(bool $cond, Closure $t, Closure $f): Closure { return $cond ? $t : $f; } $a |> cond($config > 10, bigval(...), smallval(...)) |> otherstuff(...); I think it's premature to try and bake that logic into the language, esp= ecially when I don't know of any other function-composition-having langu= age that does so at the language level rather than the standard library = level. (There are a number of fun operations people build into pipeline= s, but they are all generally done in user space.) --Larry Garfield