Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:128554 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 lists.php.net (Postfix) with ESMTPS id 170D21A00BC for ; Mon, 25 Aug 2025 19:54:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1756151600; bh=/xA8gvr4fCn8agNuY1oapuh0ShgNWPpP5KGgB6BlPdI=; h=Date:From:To:In-Reply-To:References:Subject:From; b=eT2PEx+Kohjj1cVL4cPIU7tdglltC4LoRRyo0+nupVTAH+nDcfRGdVUvmp61kVNHy STOJpbZPX+ZlJ0eZZxGmCg8Fvqa41xwzstHm3aHw8Y8a9xQqMtMhHgY1Zzo7Ml/JDd wru+gMRJVlUiLu0z3oZmg9bYCmgMtLlnhbky69CAaLkRYoYaTM/J6oHCKtqVYMSEx/ 5XtUjmBLYuX0dzsiLKuFVZqzlEQmFbPsaH1CsAyRT6b89kcXYcCIqmBA2BL6cpb0pw crqXAjMdVjInFATsCMg8BM9rfBbG6FmA/VSBUvZ6jlFMJcF9p8d8OBuzaKk4PW4Jad NLIzvZfD6YqQw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id F136D180032 for ; Mon, 25 Aug 2025 19:53:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) 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.1 X-Spam-Virus: No X-Envelope-From: Received: from fout-a6-smtp.messagingengine.com (fout-a6-smtp.messagingengine.com [103.168.172.149]) (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 ; Mon, 25 Aug 2025 19:53:19 +0000 (UTC) Received: from phl-compute-10.internal (phl-compute-10.internal [10.202.2.50]) by mailfout.phl.internal (Postfix) with ESMTP id C73E8EC03B8 for ; Mon, 25 Aug 2025 15:54:51 -0400 (EDT) Received: from phl-imap-02 ([10.202.2.81]) by phl-compute-10.internal (MEProxy); Mon, 25 Aug 2025 15:54:51 -0400 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=1756151691; x=1756238091; bh=KSOWUtReN/1VqgUpvcWug rtuvVMfVsw4VTIcchlfUGo=; b=0g/m+8oPGiEwvtePqPmr5ZG2SO/eij/I3VaEK 2O86e9jjD5nXfS7mUvPeUNNJR+lo4BCzaKiRqQX7EIzG/YRuAW/dcFzPIwMxnEy5 n68NpEqMh/WZrcZuWRlpAZRrGKtj4yfs1nqH9VnB4ITqsqv81XtpUt3V37qBT6T7 iPGSwg+a7XknN5LKTCxYv21npSwCm/loXWTqYQo5mF+58Ixs+kOz4JcuH0HKqIpA fyFOHAc6uNUZsSQENrVCrMMlLrGkdYiOasHiMedgne79u4+vNfyu9ecKx9SiXTKV cU7sZ32wobd5vGiLwKwJlAGaypJt+sToc2jsCLfL3X0B2AEfQ== 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=1756151691; x=1756238091; bh=K SOWUtReN/1VqgUpvcWugrtuvVMfVsw4VTIcchlfUGo=; b=Ho6IRSPppuYxFJapc mlxgFJbStdi4udIfWM+bUmtib0W3Kur3njlCgZSspdu4jqyzUPOLd0BYCG2/DPdd jQnqIG5qvrbFWaCA2vGyl//I5xv+18xVEH93EFZjWUaJ81/B0efmNt9xgi9WAmz7 vayvx8DkdvVmc5j0GQeFdOGpEsJwnBXEJIPyLjEXffSHvR3UG3ZX63LtGXWgZdJN YwqQjfaqjPNYaFVFuzZsw2dbmcssdxR873FUZW3z4xsYTMnvUySq0XNkxB1rynUG sRTD91xkY3+3mkTZfEcU9/FJapGAqDc41x1lPe6upvtBtIAXwgFKXKGCrBiRwNIF HdyTQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdefgddujeefvdekucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujf gurhepofggfffhvffkjghfufgtgfesthejredtredttdenucfhrhhomhepfdfnrghrrhih ucfirghrfhhivghlugdfuceolhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhmqe enucggtffrrghtthgvrhhnpeelfeefleevvdffueejgfegveevgfdthefhveetgeegfeff tdekvefhveegvdehudenucffohhmrghinhepphhhphdrnhgvthdpghhithhhuhgsrdgtoh hmnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheplhgr rhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhmpdhnsggprhgtphhtthhopedupdhmoh guvgepshhmthhpohhuthdprhgtphhtthhopehinhhtvghrnhgrlhhssehlihhsthhsrdhp hhhprdhnvght X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 778B2700065; Mon, 25 Aug 2025 15:54:51 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface Precedence: list list-help: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 X-ThreadId: A_uc5gk8jjW7 Date: Mon, 25 Aug 2025 14:54:30 -0500 To: "php internals" Message-ID: <8ee48385-a6a2-463d-8708-e6c1cc1f0914@app.fastmail.com> In-Reply-To: References: Subject: Re: [PHP-DEV] Pipe precedence challenges Content-Type: text/plain Content-Transfer-Encoding: 7bit From: larry@garfieldtech.com ("Larry Garfield") On Thu, Aug 14, 2025, at 2:30 PM, Larry Garfield wrote: > So far, the best suggestion that's been put forward (though we've not > tried implementing it yet) is to disallow a pipe inside a short-closure > body, unless the body is surrounded by (). So this: > > fn($x) => $x > |> fn($x) => array_map(strtoupper(...), $x) > |> fn($x) => array_filter($x, fn($v) => $v != 'O'); > > Today, that would run somewhat by accident, as the outer-most closure > would claim everything after it. With the new approach, it would be > interpreted as passing `fn($x) => $x` as the argument to the first pipe > segment, which would then be mapped over, which would fail. You'd > instead need to do this: > > fn($x) => ($x > |> (fn($x) => array_map(strtoupper(...), $x)) > |> (fn($x) => array_filter($x, fn($v) => $v != 'O')) > ); > > Which is not wonderful, but it's not too bad, either. That's probably > the only case where pipes inside a short-closure body would be useful > anyway. And if PFA > (https://wiki.php.net/rfc/partial_function_application_v2) and similar > closure improvements pass, it will greatly reduce the need for mixing > short closures and pipes together in either precedence, so it won't > come up very often. > > There are a few other operators that bind lower than pipe (see > https://github.com/php/php-src/blob/fd8dfe1bfda62a3bd9dd1ff7c0577da75db02fcf/Zend/zend_language_parser.y#L56-L73), > which would therefore need wrapping parentheses. For many of them we > do want them to be lower than pipe, so just moving pipe's priority down > isn't viable. However, most of those are unlikely to be used inside a > pipe segment, so are less likely to come up. The most likely would be > a bail-out exception: > > $value = null; > $value > |> fn ($x) => $x ?? throw new Exception('Value may not be null') > |> fn ($x) => var_dump($x); > > Which would currently be interpreted something like: > > $c = function ($x) { > $c = function ($x) { > return var_dump($x); > }; > return $x ?? throw $c(new Exception('Value may not be null')); > }; > $c(null); > > This would not throw the exception as expected, unless parentheses are > added. It would var_dump() an exception and then try to throw the > return of varl_dump(), which would fatal. > > RM approval to address this during the 8.5 beta phase has been given, > but we still want to have some discussion to make sure we have a good > solution. > > So, the question: > > 1. Does this seem like a good solution, or is there a problem we've not > spotted yet? > 2. Does anyone have a better solution to suggest? > > Thanks to Derick, Ilija, and Tim for tracking down this annoying edge case. Ilija has implemented the above solution, and it has now been merged. It's not ideal, but it seems like the best option at present. Hopefully, we can land both composition and PFA in 8.6, which should make this situation a fairly rare occurrence anyway. Thanks, Ilija! --Larry Garfield