Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126381 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 A13EF1A00BC for ; Wed, 12 Feb 2025 20:57:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1739393716; bh=Y+zrmLsVDiDRxJmDTWaZJcefcYk4/o0YiyCjKV0e89E=; h=Date:From:To:Cc:In-Reply-To:References:Subject:From; b=M7QmwzdC2NDz6zgDJmw4fWfYVadCdrrx1as9QjYzZGDEIsAyY2S2NAZZALwNVKwMC /1eHSn+gRV9FWf6hwOSy4/yzVquqLqRcBqxWJa4n9rv1E4tp+Oy64PZyUB2rly00rc bn5AZ9nyefnSxZ/b7HT7Rog9Z2gus/50K+S9m9BmZjQO/4W8y8ZZQzhLRIXliU1qDy 1cjm9onliLZgClAFwm4pZLpOerX6Swjru41OjiNwN/ra8X3zDt/nZk4so6itXxUsgk O/wO/cYBcu6dJZw+cX/pduQOa7LYm3EmTSzg7rXAWZsy5/xR584U9Navq0YvuBhb6z Fyqa6tP4cipfw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id D85D3180084 for ; Wed, 12 Feb 2025 20:55:14 +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,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from fout-b2-smtp.messagingengine.com (fout-b2-smtp.messagingengine.com [202.12.124.145]) (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 ; Wed, 12 Feb 2025 20:55:14 +0000 (UTC) Received: from phl-compute-13.internal (phl-compute-13.phl.internal [10.202.2.53]) by mailfout.stl.internal (Postfix) with ESMTP id D6E8A114016D; Wed, 12 Feb 2025 15:57:56 -0500 (EST) Received: from phl-imap-10 ([10.202.2.85]) by phl-compute-13.internal (MEProxy); Wed, 12 Feb 2025 15:57:56 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bottled.codes; h=cc: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=1739393876; x= 1739480276; bh=AaDT0NnCNnuL8CRSxBk9zUufKk4wnE+zPzlq4vVZhAU=; b=O trd2EvpIr7220fxKf4xKzrQzZG1fqUiJsC1fMhsx3IyC1jvYHXkNtV16ugZlHpcB sCtqDeJXqGpvp5NwzeQBwVD+hIIXG9hNpjXheewZ11uZ/IkSHWOATXUrvo6fOHCZ NdftzTDGI7j7ycm+q50pud94Qavin+F1CHDCCmZa8vCZRcoblHKDq041P32gCKLN Jjhdor8Fuo1lwhmjGaY9hRmw4vAsAhnod7fDXIiHMVvv1qa5+tKdNiLsB/Nyg2lq QVAsf7wauiOwDOaopPClHnL2hKrfYR5Guesi7nQ4YMEq/pNnSmz+2fvy7fqQd1Nm 1xNSi6dbypncOfB2wiwJg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc: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= 1739393876; x=1739480276; bh=AaDT0NnCNnuL8CRSxBk9zUufKk4wnE+zPzl q4vVZhAU=; b=qCZ5AQ7EsRnR5s5VU8si4FVs6tWZvJZoTXleLh76UfpyIviVIiN KcBKtUaBhhf2iub+V2Es2A26pr5CZlR19YAdcfUsZYfS4Ljk+HHGAmpGVIbs867I eK3C3h1UP1ALDJLoGfQummAvAT9iQOlMD2DK3SRx1uY4WhteC9n12qOizUp8G/Ff wukT+euzpunC0KCCtaTiJcPC9k+LWBwWOpc98puIGg35h/3R7/z5qhGdE1ihj4LT zLF3j+qj+ZZtVmfCRdg/cgDAP37y0P2h9VvaLhbhq5nEWiTVz/fSvsN4Y+HPnFf+ F/0xclXSwsB2hri2ElZct8OE16k9JzMfJoA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdeggeeltdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdp uffrtefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivg hnthhsucdlqddutddtmdenucfjughrpefoggffhffvvefkjghfufgtsegrtderreertdej necuhfhrohhmpedftfhosgcunfgrnhguvghrshdfuceorhhosgessghothhtlhgvugdrtg houggvsheqnecuggftrfgrthhtvghrnhepieeuteehvddvfeejhffgieehleehhedthfef keejffelgfevvdekudetjeejtddtnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrg hmpehmrghilhhfrhhomheprhhosgessghothhtlhgvugdrtghouggvshdpnhgspghrtghp thhtohepgedpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtohepthhimhessggrshhtvg hlshhtuhdrsggvpdhrtghpthhtohepthgvkhhivghlrgdvgeeisehgmhgrihhlrdgtohhm pdhrtghpthhtohepihhnthgvrhhnrghlsheslhhishhtshdrphhhphdrnhgvthdprhgtph htthhopehvohhlkhgvrhesthhiuggvfigrhihsqdhgmhgshhdrtghomh X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 457E23C0066; Wed, 12 Feb 2025 15:57:56 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Date: Wed, 12 Feb 2025 21:57:34 +0100 To: =?UTF-8?Q?Tim_D=C3=BCsterhus?= , "Kamil Tekiela" Cc: "Volker Dusch" , "php internals" Message-ID: <46f5a4ab-ae85-4a15-9781-27a94eedc512@app.fastmail.com> In-Reply-To: <95a69ca549b246c3645f8c6db519f669@bastelstu.be> References: <95a69ca549b246c3645f8c6db519f669@bastelstu.be> Subject: Re: [PHP-DEV] RFC: Marking return values as important (#[\NoDiscard]) Content-Type: multipart/alternative; boundary=d766a4c28ecd45a19c0b938045a8dcdf From: rob@bottled.codes ("Rob Landers") --d766a4c28ecd45a19c0b938045a8dcdf Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Wed, Feb 12, 2025, at 17:43, Tim D=C3=BCsterhus wrote: > Hi >=20 > Am 2025-02-12 15:07, schrieb Kamil Tekiela: > > I'd be honest, I have a very negative attitude towards this proposal > > and I'd be voting against it. It seems to me like it's creating a > > problem and then trying to find a solution for it. >=20 > Given that even Rust with a modern stdlib and ergonomic language=20 > features has such an attribute, we do not believe it's an invented=20 > problem. With the `bulk_process()` example, we also tried to provide=20 > coherent user-story with a use-case that the readers might've already=20 > encountered themselves in the same or a similar fashion. Personally I=20 > encountered situations where I wished such an attribute would've warne= d=20 > me both in PHP and JavaScript/TypeScript. Also in C of course, but giv= en=20 > that C doesn't have Exceptions, the situation is somewhat different. >=20 > For an additional example use-case, consider a function returning a=20 > resource object with side-effects which will automatically clean up th= e=20 > resource when being destructed. Specifically a function to spawn a new=20 > process or thread: >=20 > class Process { > public function __destruct() { /* kill the process */ } > } >=20 > #[NoDiscard("the process will be terminated when the Process obje= ct=20 > goes out of scope")] > function start_process(string $executable): Process { > return new Process($executable); > } >=20 > start_process('/my/background/process'); >=20 > Depending on timing, the process might or might not run to completion=20 > before PHP gets around to kill it, for example when a step debugger is=20 > attached to PHP, making the bug disappear when debugging. You yourself has said this will behave differently depending on whether = or not opcache is available. Would that not make the warning disappear i= n dev (where opcache and xdebug are not usually compatible) only to show= up in production, potentially causing a worse situation for those throw= ing warnings as exceptions? >=20 > > A return value is always supposed to be used. If some API is returni= ng > > a value that can be safely ignored, it's a badly designed API. If a >=20 > We agree that in a greenfield ecosystem, we would make ignoring the=20 > return value of a function a warning by default (with an opt-out=20 > mechanism), as done in Swift. However in PHP we do not have a greenfie= ld=20 > situation, there a number of functions where the return value is usele= ss=20 > and only exists for historical reasons. This includes all functions=20 > which nowadays have a return-type of just `true`, which was only added=20 > for this singular purpose. There will eventually be a php 9, where BC changes will be possible. > There's cases where ignoring the return value is safe and reasonable,=20 > without being a badly designed API. `array_pop()` would come to mind: = If=20 > one is only interested in the side-effect of removing the last element=20 > in the array, one does not need the return value without necessarily=20 > doing something unsafe. I have to stop you here. It is absolutely NOT safe and reasonable to ign= ore the output of array_pop. You popped it for a reason. If you just car= e about removing the last element, then you should use unset. Unset give= s the intention. If I review code with array_pop, I=E2=80=99ll spend qui= te a bit of time checking that it was intentionally ignoring the return = value (and leave a comment of the same, asking to use unset instead). >=20 > > doesn't feel like the solution. In fact, it's creating a problem for > > users who want to ignore the value, which you then propose to solve > > with (void) cast. >=20 > Ignoring the return value of functions having the attribute should be = a=20 > rare occurrence given the intended use-case of pointing out unsafe=20 > situations. But as with static analyzers there needs to solution to=20 > suppress warnings, after carefully verifying that the warning is not=20 > applicable in a given situation. And what if it isn=E2=80=99t? There=E2=80=99s a non-zero possibility we = will be seeing RFCs for years arguing over whether one function or anoth= er should have this attribute (like array_pop), not to mention libraries= using it as well. >=20 > > the compilation phase. In PHP warnings are runtime errors. The code > > should emit an exception instead of a warning. It would also make it >=20 > See Volker's reply to Derick. >=20 > > much easier to handle and you wouldn't need any special construct to > > allow users to ignore the new attribute. And I am really not a fan of >=20 > Even if an Exception would be thrown, there would be a mechanism to=20 > suppress the Exception. A catch-block wouldn't work, because if the=20 > Exception is thrown, the function is not executed / control flow is=20 > interrupted. Many people turn warnings into exceptions. I=E2=80=99m not a fan, person= ally, but the codebase I work in daily does this. >=20 > > the PHP engine generating E_USER_WARNING which should be reserved on= ly > > for warnings triggered by trigger_error. >=20 > This follows the lead of the `#[\Deprecated]` attribute, which emits=20 > `E_USER_DEPRECATED` for userland functions and `E_DEPRECATED` for nati= ve=20 > functions, despite being triggered by the engine. >=20 > > The examples you used don't support the need for the new attribute. > > Regarding the DateTimeImmutable methods, you said yourself: "The > > methods are badly named, because they do not actually set the updated > > value". So your proposal suggests adding a brand new thing to PHP to > > deal with bad method names? >=20 > `DateTimeImmutable` is not part of the =E2=80=9CUse Cases=E2=80=9D sec= tion: Our intended=20 > use-case is the kind of `bulk_process()` functionality that is used fo= r=20 > all the code snippets. But given that the attribute is also useful for=20 > `DateTimeImmutable`, we made it part of the proposal, without it being=20 > part of the intended =E2=80=9Cuser-story=E2=80=9D. >=20 > > This problem should be solved using static analysers, IDE, and proper > > code refactoring. >=20 > See Volker's reply to Matteo. >=20 > Best regards > Tim D=C3=BCsterhus >=20 =E2=80=94 Rob --d766a4c28ecd45a19c0b938045a8dcdf Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable

=
On Wed, Feb 12, 2025, at 17:43, Tim D=C3=BCsterhus wrote:=
Hi

Am 2025-02-12 15:07, schrieb Kamil Tekiela:
> I'd be honest, I have a very negative attitude towards this= proposal
> and I'd be voting against it. It seems to m= e like it's creating a
> problem and then trying to fin= d a solution for it.

Given that even Rust w= ith a modern stdlib and ergonomic language 
features = has such an attribute, we do not believe it's an invented 
problem. With the `bulk_process()` example, we also tried to provi= de 
coherent user-story with a use-case that the read= ers might've already 
encountered themselves in the s= ame or a similar fashion. Personally I 
encountered s= ituations where I wished such an attribute would've warned 
me both in PHP and JavaScript/TypeScript. Also in C of course, bu= t given 
that C doesn't have Exceptions, the situatio= n is somewhat different.

For an additional = example use-case, consider a function returning a 
re= source object with side-effects which will automatically clean up the&nb= sp;
resource when being destructed. Specifically a functio= n to spawn a new 
process or thread:
     class Process {
&nbs= p;        public function __destruct(= ) { /* kill the process */ }
     }

     #[NoDiscard("the pro= cess will be terminated when the Process object 
goes= out of scope")]
     function start_p= rocess(string $executable): Process {
   &n= bsp;     return new Process($executable);
<= div>     }

  =    start_process('/my/background/process');

=
Depending on timing, the process might or might not run to co= mpletion 
before PHP gets around to kill it, for exam= ple when a step debugger is 
attached to PHP, making = the bug disappear when debugging.

<= div>You yourself has said this will behave differently depending on whet= her or not opcache is available. Would that not make the warning disappe= ar in dev (where opcache and xdebug are not usually compatible) only to = show up in production, potentially causing a worse situation for those t= hrowing warnings as exceptions?


> A return value is al= ways supposed to be used. If some API is returning
> a = value that can be safely ignored, it's a badly designed API. If a

We agree that in a greenfield ecosystem, we would= make ignoring the 
return value of a function a warn= ing by default (with an opt-out 
mechanism), as done = in Swift. However in PHP we do not have a greenfield 
situation, there a number of functions where the return value is useles= s 
and only exists for historical reasons. This inclu= des all functions 
which nowadays have a return-type = of just `true`, which was only added 
for this singul= ar purpose.

There will eventua= lly be a php 9, where BC changes will be possible.

<= blockquote type=3D"cite" id=3D"qt" style=3D"">
There's cases where i= gnoring the return value is safe and reasonable, 
wit= hout being a badly designed API. `array_pop()` would come to mind: If&nb= sp;
one is only interested in the side-effect of removing = the last element 
in the array, one does not need the= return value without necessarily 
doing something un= safe.

I have to stop you here.= It is absolutely NOT safe and reasonable to ignore the output of array_= pop. You popped it for a reason. If you just care about removing the las= t element, then you should use unset. Unset gives the intention. If I re= view code with array_pop, I=E2=80=99ll spend quite a bit of time checkin= g that it was intentionally ignoring the return value (and leave a comme= nt of the same, asking to use unset instead).


> do= esn't feel like the solution. In fact, it's creating a problem for
> users who want to ignore the value, which you then propose= to solve
> with (void) cast.

<= div>Ignoring the return value of functions having the attribute should b= e a 
rare occurrence given the intended use-case of p= ointing out unsafe 
situations. But as with static an= alyzers there needs to solution to 
suppress warnings= , after carefully verifying that the warning is not 
= applicable in a given situation.

And what if it isn=E2=80=99t? There=E2=80=99s a non-zero possibility = we will be seeing RFCs for years arguing over whether one function or an= other should have this attribute (like array_pop), not to mention librar= ies using it as well.


> the compilation phase. In = PHP warnings are runtime errors. The code
> should emit= an exception instead of a warning. It would also make it
=
See Volker's reply to Derick.

> much easier to handle and you wouldn't need any special construct= to
> allow users to ignore the new attribute. And I am= really not a fan of

Even if an Exception w= ould be thrown, there would be a mechanism to 
suppre= ss the Exception. A catch-block wouldn't work, because if the 
<= /div>
Exception is thrown, the function is not executed / control fl= ow is 
interrupted.

Many people turn warnings into exceptions. I=E2=80=99m not a fa= n, personally, but the codebase I work in daily does this.

> the PHP engine generating E_USER_WARNING which should be reserved= only
> for warnings triggered by trigger_error.

This follows the lead of the `#[\Deprecated]` att= ribute, which emits 
`E_USER_DEPRECATED` for userland= functions and `E_DEPRECATED` for native 
functions, = despite being triggered by the engine.

>= The examples you used don't support the need for the new attribute.
=
> Regarding the DateTimeImmutable methods, you said yourse= lf: "The
> methods are badly named, because they do not= actually set the updated
> value". So your proposal su= ggests adding a brand new thing to PHP to
> deal with b= ad method names?

`DateTimeImmutable` is not= part of the =E2=80=9CUse Cases=E2=80=9D section: Our intended 
=
use-case is the kind of `bulk_process()` functionality that i= s used for 
all the code snippets. But given that the= attribute is also useful for 
`DateTimeImmutable`, w= e made it part of the proposal, without it being 
par= t of the intended =E2=80=9Cuser-story=E2=80=9D.

=
> This problem should be solved using static analysers, IDE, and= proper
> code refactoring.

See Volker's reply to Matteo.

Best regard= s
Tim D=C3=BCsterhus

=

=E2=80=94 Rob
--d766a4c28ecd45a19c0b938045a8dcdf--