Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129975 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 686C71A00BC for ; Mon, 2 Feb 2026 08:56:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1770022588; bh=0JMbIYq5E1dFfxGHSsj1sROYU9HV9JkMpSK1RiAg+8k=; h=Date:From:To:In-Reply-To:References:Subject:From; b=XDGIjRsm9zy+QQhb2R+anoTKbveNC5QVxat4pDQr05pFmRLKcdHbXT4Q9Z2m3Zks9 pt7EoMaO4woMNu5eV5aB11e5UmVPTPUuorZ4yMYiHqKqjQ673qPk2nkFboxOQaoud+ VxAEgS0sg/Kbse7rc7SKG5rKkXZFBNPH3N3DyD85VQU/c04UJlLNmjhxaDApdvUm8W NOR6fUQQHeuBXbHu3AKJ+xuA5qHj+14ehXxy7kLD3iu1+tj76so8PTsSjvMqCrAuKF M4SBwV9HqkWcJWwDClg0OOI5YDz67xGAJyWVKvVbaBpDErc1Z0WLab2FTAAves2bmn iyTm1RdOOPd/w== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id BC70C180084 for ; Mon, 2 Feb 2026 08:56:27 +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=-0.1 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from fhigh-a8-smtp.messagingengine.com (fhigh-a8-smtp.messagingengine.com [103.168.172.159]) (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, 2 Feb 2026 08:56:27 +0000 (UTC) Received: from phl-compute-12.internal (phl-compute-12.internal [10.202.2.52]) by mailfhigh.phl.internal (Postfix) with ESMTP id 05990140007C for ; Mon, 2 Feb 2026 03:56:22 -0500 (EST) Received: from phl-imap-05 ([10.202.2.95]) by phl-compute-12.internal (MEProxy); Mon, 02 Feb 2026 03:56:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bottled.codes; h=cc: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=fm1; t=1770022582; x=1770108982; bh=o263aBnzcJ CS8fGPSplHDCdKDotVjJ3qKfU/3p7GsOk=; b=EjgL7s70CaZY7eE4j0rGHugFM8 pAF8e7W1IcZg3dTNB4IPSQh7TQD/Ef3x6ef1ncLmk2vW2PMNPt31/oq0caGG3nrL Lj2rMLExzgZqtXBHxMH1ceVglrZvNUlXIUbWPF2PBXjKQ47Mol2/kMhGx5p9zI4x snCNA29zkqWXY1T2QnmNoJsvRdmQmFUaQ6mOa3MJhhN/H7J4KAF9CLu1fakM8mOk zeMEkuZli9TQtmY4B3D/DW3lBAueyTWyje1xkfdcJeg+oMBz9D6PqkW5LVuhmBhe NpDIvIUWV/tNStOArAomsZqkumj55v+WmmiBFdkIY4hk4Ow6nqdqLzc3jFYA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc: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= 1770022582; x=1770108982; bh=o263aBnzcJCS8fGPSplHDCdKDotVjJ3qKfU /3p7GsOk=; b=AXZvzLI84X4sKTUbN4tu3pZW6PBSZStwAYXitxSWa2tt0maoLbk SWZkQFOaWkZIaXCsgwLuzhduNuueweotFR/s1tIS61MsoZ/OSsTUlOgEVXueGKE8 8j69inyl2ai+Z8Pxqu0dsDFQRY3Q40YpN9RfyZ8i3mbScBNn7lHmlgDAIDopaqUq 6Lski7X0V5qiJae/mjydTf4uFEFLVq/33hNckC0YXHsgvGpzNTpWBpY7Z4q28gYI HC+0Sn0j0dLAvNdLnw1HAoI5a2YpQFRwN82IAQFPoJeprhF/JHCvnBg5AzWd8qJL v8VuQOfhj6PHU6eF+QnDL5Giy4u5GKexHIw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgddujeejvdduucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucenucfjughrpefoggffhffvkfgjfhfutgesrgdtreerre dtjeenucfhrhhomhepfdftohgsucfnrghnuggvrhhsfdcuoehrohgssegsohhtthhlvggu rdgtohguvghsqeenucggtffrrghtthgvrhhnpedtiedtvddvvefhudffhfegleffteegff evkeehkeefleeuuddtieevkedvteejvdenucffohhmrghinhepfehvgehlrdhorhhgnecu vehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheprhhosgessg hothhtlhgvugdrtghouggvshdpnhgspghrtghpthhtohepuddpmhhouggvpehsmhhtphho uhhtpdhrtghpthhtohepihhnthgvrhhnrghlsheslhhishhtshdrphhhphdrnhgvth X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id A2746182007A; Mon, 2 Feb 2026 03:56:21 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 X-ThreadId: ApKm5apYHwGF Date: Mon, 02 Feb 2026 09:56:00 +0100 To: internals@lists.php.net Message-ID: <918fbb69-9bb3-42f9-a3df-d1d7fdbaa65e@app.fastmail.com> In-Reply-To: <78e9c0ed-8c30-499f-8597-7352f6fb8d51@varteg.nz> References: <78e9c0ed-8c30-499f-8597-7352f6fb8d51@varteg.nz> Subject: Re: [PHP-DEV] Return expression Content-Type: multipart/alternative; boundary=cb1dc0696b934353bbd0a466a0c986bd From: rob@bottled.codes ("Rob Landers") --cb1dc0696b934353bbd0a466a0c986bd Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Mon, Feb 2, 2026, at 04:46, Morgan wrote: > On 2026-02-02 13:18, Rob Landers wrote: > >=20 > >=20 > >=20 > > From an observability point of view, you lost me when you said retu= rn's=20 > > type is "never". > >=20 > > https://3v4l.org/plpIf#v8.5.0 > >=20 > > We can clearly see the type is "null", unless you mean something mor= e=20 > > abstract? > >=20 > I'm referring to the expression's value as it may exist in a larger=20 > expression, primarily for type checking. To use the match{} example,=20 > what value does $split get when $len =3D=3D 1, because in that case th= e=20 > statement boils down to "$split =3D return false;"? Evaluation never c= omes=20 > back to the assignment to assign $split anything, in the same way that= a=20 > call to a function of type never shouldn't see evaluation coming back = to=20 > the call site. >=20 > If $split were something still visible after function return ("$o->p")= ,=20 > since the assignment didn't happen it would still have its previous va= lue. >=20 > But as I alluded and you noted, this wouldn't be observable: the calle= r=20 > gets the value of the return expression's operand (or null, if no such=20 > operand was provided, in which case why are you trying to see the valu= e=20 > of a function of type void?) >=20 > If you were doing static analysis, making the type of a return=20 > expression that of its operand could be an issue: in that match{}=20 > example there is no assertion that $split is supposed to contain a=20 > boolean. Let's say it's supposed to be an int. "int|bool" would be an=20 > incorrect inference; since never is a bottom type and thus a subtype o= f=20 > every type, "int|never" =3D=3D "int". >=20 > On the other hand, "int|Exception" is just as invalid, but throwing=20 > exceptions from inside expressions is pretty well-behaved; I think=20 > modelling return's semantics the same way would work, but I don't know=20 > enough of the internals to make that judgement. >=20 > Basically, the type of a return expression would be the type of a thro= w. I would say the weirdest thing about making return an expression boils d= own to where it could then be used: myFunc(return 123); $arr =3D [1, 2, return 3]; 1 + 2 + return 3 Are just some basic examples. As I mentioned in the other thread about t= his, it would make finding method/function returns like hunting for a ne= edle in a haystack. =E2=80=94 Rob --cb1dc0696b934353bbd0a466a0c986bd Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable


On Mon, Feb 2, 2026, at 04:46, Morgan wrote:
On 2026-02-02 13:18, Rob= Landers wrote:
>=  
>  From an observability point of view, you los= t me when you said return's 
> type is "never".
<= div>> 
> <= /div>
> We can clearly see the type is "null", unless you mean so= mething more 
> abstract?
I'm referring to the expression's value as it may exist in a larger&n= bsp;
expression, primarily for type checking. To use the match= {} example, 
what value does $split get when $len =3D=3D = 1, because in that case the 
statement boils down to "$sp= lit =3D return false;"? Evaluation never comes 
back to t= he assignment to assign $split anything, in the same way that a 
call to a function of type never shouldn't see evaluation coming= back to 
the call site.

If $spl= it were something still visible after function return ("$o->p"), = ;
since the assignment didn't happen it would still have its p= revious value.

But as I alluded and you noted, = this wouldn't be observable: the caller 
gets the value o= f the return expression's operand (or null, if no such 
o= perand was provided, in which case why are you trying to see the value&n= bsp;
of a function of type void?)

If = you were doing static analysis, making the type of a return 
<= div>expression that of its operand could be an issue: in that match{}&nb= sp;
example there is no assertion that $split is supposed to c= ontain a 
boolean. Let's say it's supposed to be an int. = "int|bool" would be an 
incorrect inference; since never = is a bottom type and thus a subtype of 
every type, "int|= never" =3D=3D "int".

On the other hand, "int|Ex= ception" is just as invalid, but throwing 
exceptions fro= m inside expressions is pretty well-behaved; I think 
mod= elling return's semantics the same way would work, but I don't know = ;
enough of the internals to make that judgement.
Basically, the type of a return expression would be the typ= e of a throw.

I would say the weir= dest thing about making return an expression boils down to where it coul= d then be used:

myFunc(return 123);
<= br>
$arr =3D [1, 2, return 3];

1 + 2 = + return 3

Are just some basic examples. As I m= entioned in the other thread about this, it would make finding method/fu= nction returns like hunting for a needle in a haystack.

=E2=80=94 Rob
--cb1dc0696b934353bbd0a466a0c986bd--