Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129978 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 D6DBC1A00BC for ; Mon, 2 Feb 2026 15:51:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1770047498; bh=AXf/Wi0FOBmvYCYNpb1h/VcyTNcAzkpGloAULkmk78k=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=c27kbzjofCWU7Mm9q4jU4diOBN/4geZOyDMUvfgFirafPuW5yrtWQNgM6MCvHwJes OxNGfk0DM3n6PPWDMmLoF+h7tpPMhH5ggO77xKygM1+kSmlt2u/tz8Z0czVLGw1rwn de5VP7ozhINq8eYkvhRNHetS8TaNOq/tWZ5Qd92BcPGyPue2ugI9Q12XaVhHg5sMJb t5KcKIKbqfFb3QvYLnLNIwP+V8LchCC2NSfbZXKpfKQUWGmrXPArgfBCth0V1Q0P0o 0Q0xTovQ9VgrDS4zR4SxPtnge8Z8fwx5Xs3ABF0a8J3ucCThvizM3U3ySilZlRbc0o 0y0evcB8+54wg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 54F1E180069 for ; Mon, 2 Feb 2026 15:51:37 +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.8 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_50, DKIM_SIGNED,DKIM_VALID,DMARC_MISSING,HTML_MESSAGE,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-ua1-f51.google.com (mail-ua1-f51.google.com [209.85.222.51]) (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 15:51:37 +0000 (UTC) Received: by mail-ua1-f51.google.com with SMTP id a1e0cc1a2514c-9489b08c211so1400750241.3 for ; Mon, 02 Feb 2026 07:51:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1770047491; cv=none; d=google.com; s=arc-20240605; b=QLwnIXgwWHGk/9l2rmXRBWQgLgGHMw8EtvcT0Yh//xNLQ6jt+wiJeImWLwIJAkG5yh uHJyC2L0/cTaXqFPUu7F69tPIW13dJs1xeTKNvyWZmVMiWNhG+Tsu4buDzzASljOiQmD JOOlUJtOvNy5CBobhGicWOyUMX6f9soTJOKWFAHT54vH4Y8HynCcxU0v2gwrKaa1FDvS YBl+quV5SeVRkM466JB4A21IfNfd/dQOCU4f8pqcmLbV/XXkRQPJ/19fO2bilsQd/D6/ JJX7gGRQWFvc6FetCbLEm57inonWJOweoRMlazW+yAstoLTVL+cLi5bUXZMOjfisppEz Zd3A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=pDpT0cU+6/UNAql4IyLr2FV+P4onCffZO5rF9BIRSb8=; fh=a2UmS3UPhOQSEgu4f/utmrOFMcvVWR9qKLeZmQUqoNc=; b=Vdig1EshwdhpFQW1DUqqnKoMLygfbenQkqKtC4SOH9y29R4g/N/PNxEi5nyDyzJTiN 5GCbaG0kceJJbcKTlziBTapcwbuKa2Qijz1hlDvoVCLkQYEwVdl6fB60O/rLgIhtruS5 w8CY9xlJMyH5Y21Y+HCS8FWa5dkPwtXJ+S6a4bFJ6HwHqZlbt2U6k95pT6aJdd0xoQRD lHSgP6VOKwjHPzMTc5vf+TDN9JrTbERD4yn97S7l3ErxFGX4xdDQ3KSYqBEDIyRW76EG Ov/TdwP22GMeG9+xpPuCeZmmeecqgDvom72aBpHD1jfc9k4DqGMFHiH60T/A8vJ2uNZs BJDw==; darn=lists.php.net ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=carthage-software.20230601.gappssmtp.com; s=20230601; t=1770047491; x=1770652291; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=pDpT0cU+6/UNAql4IyLr2FV+P4onCffZO5rF9BIRSb8=; b=Wg5/YT7Hc2XHSY5nOvX3hQGXqJQ4fdT0F3yWwq6FV1wDiOz50+t+G9yvzc8lCMQE+l QzowTTQOXry/f0K/bQEKDiNSGAkzkLWS2pC3AC6V9ReC07PjgdOC+BaosAnJHUZub/Mo ONFJBg4OBXlI+j/tDm6lrnllUpWMsIRYR1eTwZpk9821/bZJw8G+XXXyWu+ZYicPIU64 I6ce44LYtiSsrR+5mv9pdxpOzGeoZgYpbe774T19oBSkYZwl9SDqF3L06BpqW/5a1Sz6 vSltDdAX9cay7+oy+HTRj+sxERWS47uVBwu/lZbEi6QsxckIqhZOuYKVUDN03A+atF1P KbaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770047491; x=1770652291; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=pDpT0cU+6/UNAql4IyLr2FV+P4onCffZO5rF9BIRSb8=; b=lWCNVCIM2b9DgAHilVhn6vZNIYIOkOeaDld5bxo5GFYnB39oUdyzYSRm1159AuhTHN Qjl6ilK06GkiwOd0FezUtJ1Vqabt4usGLKxP0Sk6YulVLN/k6j8rVgIyIvpoYfAvahX7 qALWBBBB6KZnmb8YmEtNaGJ8XyPoq/Y9Cbp2kfeZv3K9RygosjnCG67Pjtu8d5/ti2Jm Qrzhsoht8uUYAQ0zxm1zt9FQdz+OaAgxL/oqYuGzCfO/S25959OudZD2cuOChLSrrvgZ GFtHkXU3HHFE+9Eb4GPp5XCv1zPL+SeihBLDBmkaIqszQOQMBtyhVTqEmY8ck8QjGjNG b2/Q== X-Gm-Message-State: AOJu0YzReuCPIWuMcNdAiXfc8I1apejaWpVV0xE66esKT2VKl6WF+ksI t71sjZ8SYahvlOVTuowHKoVyM3z5RXkQl/w/tJRRdnOZckNZYrY9YstDPw1Ln9w0s8bknCXXXCe z3gYz4qOyjYtidDUlUUtIPWgICcOxGISBH5weOIt2Ijj3G0U/PkaF8Oc= X-Gm-Gg: AZuq6aILPhWS7F32N74yI8oRbfnknvrqOBZigJZ8Rq++bdIk497eUiVh9eXiKOOsIdQ t9ujVkhRfHFGC9GPpKtiKN3lBe3yRlKF3ZrXc4wo4Sr18F8Dr1pYA604Gc/RMPY8gI5gG97k/zU ZbWpCWFswnB+b1LEvkeUvHEWdkSm/exD2PkkPuDaifMVX7JPgJph4G1BwNJzgGGwSj1RPNUXqRh 4b0M4m2SFRaAllH1x0UUQcubyyTcbeAJXzQbLzpRJPJtV8F2dni+7hK/A6A1bZIx29nC1b8JgA/ LDZ+dnM= X-Received: by 2002:a05:6102:f06:b0:5f1:c561:8dc7 with SMTP id ada2fe7eead31-5f8e268d3b5mr4154928137.38.1770047490862; Mon, 02 Feb 2026 07:51:30 -0800 (PST) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: <78e9c0ed-8c30-499f-8597-7352f6fb8d51@varteg.nz> <918fbb69-9bb3-42f9-a3df-d1d7fdbaa65e@app.fastmail.com> In-Reply-To: <918fbb69-9bb3-42f9-a3df-d1d7fdbaa65e@app.fastmail.com> Date: Mon, 2 Feb 2026 16:51:19 +0100 X-Gm-Features: AZwV_Qje_JqyuAFmJMIk9IVTMb5d-KYzxfHEFsmnoGElKJFfVahR2o12faA6mDs Message-ID: Subject: Re: [PHP-DEV] Return expression To: Rob Landers Cc: internals@lists.php.net Content-Type: multipart/alternative; boundary="000000000000edbd180649d94be7" From: azjezz@carthage.software (Seifeddine Gmati) --000000000000edbd180649d94be7 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Mon, 2 Feb 2026 at 09:57, Rob Landers wrote: > > > > 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 lost me when you said return'= s > > type is "never". > > > > https://3v4l.org/plpIf#v8.5.0 > > > > We can clearly see the type is "null", unless you mean something more > > abstract? > > > I'm referring to the expression's value as it may exist in a larger > 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 "$split =3D return false;"? Evaluation never come= s > back to the 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 $split were something still visible after function return ("$o->p"), > since the assignment didn't happen it would still have its previous value= . > > But as I alluded and you noted, this wouldn't be observable: the caller > gets the value of the return expression's operand (or null, if no such > operand was provided, in which case why are you trying to see the value > of a function of type void?) > > If you were doing static analysis, making the type of a return > expression that of its operand could be an issue: in that match{} > example there is no assertion that $split is supposed to contain 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|Exception" is just as invalid, but throwing > exceptions from inside expressions is pretty well-behaved; I think > modelling 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 type of a throw. > > > I would say the weirdest thing about making return an expression boils down 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 this, it would make finding method/function returns like hunting for a needle in a haystack. > > =E2=80=94 Rob I think all those examples actually make sense. `return ` would itself become an expression, which means you could use it anywhere, all those places already support `throw`. example: https://3v4l.org/nqbkU static analyzers would be able to warn about unreachable code and `never` being used within expressions: https://mago.carthage.software/playground#019c1d99-449c-e1bf-2517-726d0b9f9= b5f --000000000000edbd180649d94be7 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable

On Mon, 2 Feb 2026 at 09:57, Rob Landers <rob@bottl= ed.codes> wrote:
>
>
>
> On Mon, Feb 2, 2026, at= 04:46, Morgan wrote:
>
> On 2026-02-02 13:18, Rob Landers wrot= e:
> >
> >
> >
> > =C2=A0From an observ= ability point of view, you lost me when you said return's
> > = type is "never".
> >
> > https://3v4l.org/plpIf#v8.5.0 <https://3v4l.org/plpIf#v8.5.0>
> >=
> > We can clearly see the type is "null", unless you m= ean something more
> > abstract?
> >
> I'm refe= rring to the expression's value as it may exist in a larger
> exp= ression, primarily for type checking. To use the match{} example,
> w= hat value does $split get when $len =3D=3D 1, because in that case the
&= gt; statement boils down to "$split =3D return false;"? Evaluatio= n never comes
> back to the 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 $sp= lit were something still visible after function return ("$o->p"= ;),
> since the assignment didn't happen it would still have its = previous value.
>
> But as I alluded and you noted, this wouldn= 't be observable: the caller
> gets the value of the return expre= ssion's operand (or null, if no such
> operand was provided, in w= hich case why are you trying to see the value
> of a function of type= void?)
>
> If you were doing static analysis, making the type = of a return
> expression that of its operand could be an issue: in th= at match{}
> example there is no assertion that $split is supposed to= contain a
> boolean. Let's say it's supposed to be an int. &= quot;int|bool" would be an
> incorrect inference; since never is= a bottom type and thus a subtype of
> every type, "int|never&qu= ot; =3D=3D "int".
>
> On the other hand, "int|Ex= ception" is just as invalid, but throwing
> exceptions from insi= de expressions is pretty well-behaved; I think
> modelling return'= ;s semantics the same way would work, but I don't know
> enough o= f the internals to make that judgement.
>
> Basically, the type= of a return expression would be the type of a throw.
>
>
&g= t; 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 thr= ead about this, it would make finding method/function returns like hunting = for a needle in a haystack.
>
> =E2=80=94 Rob

I think al= l those examples actually make sense. `return <expr>` would itself be= come an expression, which means you could use it anywhere, all those places= already support `throw`.

example: https://3v4l.org/nqbkU

static analyzers would be able to warn = about unreachable code and `never` being used within expressions: https://mago.carthage.software/playground#019c1d99-449c-e1bf-2517-= 726d0b9f9b5f
--000000000000edbd180649d94be7--