Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:128061 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 921DA1A00BC for ; Tue, 15 Jul 2025 18:11:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1752602990; bh=UKQgpcNC2exUOgCIQISTqFRSueI/PByzneerc7jqxE4=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=e04Hzivs6rTd4l1g+4HdgBXlpfJKaHkxDI+8ThG1RE85IOj9UKPJYvOIeiU6gAOPm 0DbPeLUrWit1WvE8DLqi6DUqMtd4tb5cCG/AAIi7j4Mfy+18KPk5qV1llq+bOSUIPv D6+KRp3+h6gdiotJCGsk7seSqSawXvFPBSDbk5I3l6yFctz+hquzAQDry5h67wYNKF JG5n8gIlqy1PXwoSFSyrgLTqaAqy2Um+MvpEW7WaFwIqQv0fRhAq1xV8Aa7EvZykxw fpVfWoPDXUNDjhN3F1rASmbMlY8hlbQaFaS28zI/AA7U1Xs8sJAvddqiMXUQv+qMOk 9C1/AWbb4kU7Q== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id A2880180039 for ; Tue, 15 Jul 2025 18:09:49 +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.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, FREEMAIL_REPLY,HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from mail-lf1-f54.google.com (mail-lf1-f54.google.com [209.85.167.54]) (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 ; Tue, 15 Jul 2025 18:09:49 +0000 (UTC) Received: by mail-lf1-f54.google.com with SMTP id 2adb3069b0e04-553dceb342fso5069493e87.0 for ; Tue, 15 Jul 2025 11:11:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1752603096; x=1753207896; 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=nDBDvFfEI7PbVTcDdOEI6MLMunX2Oy0A1a4DeSXVcpo=; b=QAe+BnZTFHhzKaVnEjK+pVeXQdEJp6Mej4TsCI+reydDRq4+2IN64B1r08BCDFMcyN /qWB6xDqBR1+oUwriu0aZDHENT7xps3BuH/QKxZk5DFLgwJNwo3AQBpMe7H067uNppAG CrRwqL7hyLLS2xM3X1jSp4nuaqkATzoEmKeibh1x2ZO9HWnlEu3cVkrgh5nO1qsgn3gK cJhzkCgumd8E65mVY+LdnSCM39jEMUU32YjuoEUxkDVMvrD1GyJDqPv1zfYkeZywWZaY FeA+5P1CWdYVuBg/kpfZBYlBuhyWYfqfnhPo+MlvA9eE39/mg9+Lnyf3HALSHmsQ2mqE pLNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752603096; x=1753207896; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=nDBDvFfEI7PbVTcDdOEI6MLMunX2Oy0A1a4DeSXVcpo=; b=rP3gicOJjK1GL6lAybgQIVPzdcfh8Cl4BIFXfE6yHxi0KdIO7vdsDV2lP4E9+axQa1 r6z1/j6j1pDrlFLNLSC+KR7Zhtm8uIS0HNbU2osHQopqzVp0CJB5d6G3WI50dsOw+lRE x3Y7bWVtqrCchPPXwmrM9GF6qkN1+eQrMqIq1ShXW3EBBLYgHy3LaUoy+GP1dEyoz0Fv WgnT35bRzdVQlLdSvoDrBNhPbIkLndWLT2UaicClDsF4pB+IUAiFVcE4YwXWcMvwRXpr OTmj+lyweQun/6p5412R2qBVBUJEXc5bEWn0BUtztvQMKt7DdwhZw5aPInMctqqRlJYl rpxQ== X-Gm-Message-State: AOJu0Yz7fvvMwDbkjrX2awo34Kw+0lUToH2bQQjQsUttgCTHcGaT1Hx1 GoVn0b/UQHuAq466zJn+/Z+10O9/oWc/un1CwBZLOxfbxQNS/wG/7bunumteUPNov4065iKFRYM fONSXn75RLX7D+28OWJY+FzAMMt9mH+U= X-Gm-Gg: ASbGncvWc3IIik5G5VSYQ+29mmh3ohmbVMh+lktUMGQ1mNCszWabyB3fSeTAuurrnyq SxitjqTXWdFN2Sln+o8dRzwwNRuT5zuIM7GdE0yn1pUWnnM3N+56PMGk1WmI7F3zQ87IegT2TzK LFDGpmS7aqE9pqVxalyOo6wEzM9Xy7QFOH6HmJ10h7Vegthto6i8oKAOu3QZAImZPro1FgJv1jq k7u X-Google-Smtp-Source: AGHT+IFm/h7ZOW9O7bLqYojqTjPBdzgyK5bc9N+HZylck4KP9gZB+yAq+5slMjTF1N9sBpZR8SDJGBug9BNhQ5u3xw4= X-Received: by 2002:a05:6512:3b98:b0:553:2dce:3aad with SMTP id 2adb3069b0e04-55a233025cemr173694e87.7.1752603095287; Tue, 15 Jul 2025 11:11:35 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 References: <3Yl0UGauXmKqk7s7Hqbv6iaXru-hZHf8Wj6VjwwihgRSaqZo5EZ2ndsOle-ae41C-lvnirynWt6PpuD7UJPL0zPCw18QHFE81Eb--fiiEbc=@gpb.moe> In-Reply-To: Date: Tue, 15 Jul 2025 20:11:23 +0200 X-Gm-Features: Ac12FXwNaJsB7ZYhnwVGxpxAKpGIw8gwjE-9ZFoKN_6SUv7yR4gyBEIK3ofHlnA Message-ID: Subject: Re: [PHP-DEV][RFC] Deprecate type juggling to and from bool type within the function type juggling context To: "Gina P. Banyard" Cc: PHP internals Content-Type: multipart/alternative; boundary="000000000000ed4cef0639fbb42e" From: nicolas.grekas+php@gmail.com (Nicolas Grekas) --000000000000ed4cef0639fbb42e Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Le ven. 11 juil. 2025 =C3=A0 13:00, Gina P. Banyard a = =C3=A9crit : > > On Monday, 30 June 2025 at 10:26, Nicolas Grekas < > nicolas.grekas+php@gmail.com> wrote: > > Hi Gina > > Thanks for experimenting with this on > https://github.com/symfony/symfony/pull/60890/files > > It's good to see that fitting this RFC requires a relatively small number > of lines to change even on a codebase like Symfony. We're not at 100% but > still nice. > > Yet, it IS a big bang in terms of deprecations to fix that this will > trigger. Their number is super high, because these boolean conversions > happen on hotpath / in loops. > > This reminds me of the mandatory "?" for arguments with null defaults: th= e > change made sense from a language design PoV, but the impact was, and sti= ll > is very high. It was and still is a very costly deprecation for the > community, and it's not over yet. That made me say at conferences that th= is > was maybe not a good idea... > > Looking at the diff above, I think I can draw two sets of changes: > 1. the ones that patch a cast-to-bool > 2. the ones that patch a cast-from-bool > > The latter, cast-from-bool, I think they're all useful improvements. Whil= e > most likely harmless in all the specific cases of the PR, doing e.g. an > strpos() on false feels hardly legit. I'm therefore sympathetic to making > these changes. > > For cast-to-bool, I'm WAY less convinced. From the PR above, explicit > casts like "return (bool) preg_match(...)" on a method that returns a > "bool" or "(bool) ($this->loggedErrors & $type)" are a clear downgrade: > it makes the typing PHP just more verbose without any real benefit. That > doesn't look worth asking the whole ecosystem to fix those deprecations. = It > is especially hard to see this as an improvement when comparing to using > the same expressions with e.g. the "if ()" operator, which doesn't need t= he > explicit cast (and shouldn't of course). > > > Every cast-to-bool example you are providing are int-to-bool coercions, > not string nor float casts type. > That's correct. I feel quite strongly about this: int-to-bool casts should be handled gracefully by the engine seamlessly. Deprecating them will (plan to) break many apps that are just fine, and as Rob wrote (and you also in a gist), casting to (bool) is what many will do, wrongly. This won't improve the language, quite the contrary. About string-to-bool PHP is still that language that allows quickly consuming $_GET['foo'] as whatever it looks like as a string. I suspect tons of codebases rely on this behavior. To me, that's where the costs might outweigh the benefits... Especially that even within SFs test suite, various cases of string-to-bool > casts seems to be highlighting some sort of bug in the test suite. > Moreover, the fixes for the bitwise & operator are following the styles > from surrounding functions that _already_ do that, and I was slightly > confused about the inconsistencies. > That's an inconsistency favored by the strict-mode hype: people blindly cast (and introduce bugs)... That inconsistency should be fixed the other way around: removing these needless (and dangerous) casts. > The preg_match() API is just unfortunate that it returns a boolean value > as integers rather than booleans, as it uses a false return to communicat= e > it emitted a warning instead of null. > Unfortunate but still to be acknowledged as a likely contribution to making this RFC a high-cost one for userland. > Improving this API, is a very orthogonal problem to this, that we probabl= y > should be doing anyway (e.g. see if we can promote the warnings to > exceptions). > And I could be convinced to carve out an exception for int-to-bool, > however that retains some complexity remembering PHP's type juggling rule= s, > or have it as a secondary vote. > > In the RFC, you write that its motivation is to allow making the bool typ= e > equivalent to the true|false union. To do so you propose to make the bool > type always behave like in "strict" mode. > > Personally, I'm moot about the motivation. I understand it, but it looks > inappropriate to push deprecations from this somewhat (IMHO) theoretical > angle. The added friction would need way stronger arguments to be justifi= ed > IMHO. > > Would it be possible to trigger the deprecation only in the cast-from-boo= l > direction, and accept casts-to-bool as seamlessly as there are now? If ye= s, > then would it also be possible to make the true and false types have the > same behavior (aka non-strict in casts-to-bool direction - when not in > strict mode of course)? If yes to both questions, then that'd look like a > better outcome that'd still allow fulfilling your goal, while providing > maximum value to the community. > > As is, the cost/benefit ratio doesn't make this RFC look worth it to me. > > > As said above, it is even possible to only warn on string- and > float-to-bool and not on int-to-bool coercions. > But I still think theoretical angles are important, because allowing edge > cases always adds complexity that has causes us countless headaches in th= e > past. > > Last but not least, I'm not sure it's a good idea to rush this into 8.5. > This is a high-impact change. We should give some time to the discussion, > understand the impact and explore variants. Merging this in 8.6 would als= o > give a few more months for open-source projects to adapt to the change > (since many do run their CI with the master branch of PHP to spot changes > as early as possible.) > > > I'm not exactly certain I buy the argument that delaying this deprecation > is worthwhile, especially as I don't really think is as high impact as it > is made out to be. > Deprecating implicit null-ness was (still is) a high impact deprecation, and this one has a higher potential impact IMHO. > And I don't really see what "variants" there are to explore other than a > possible allowance for int-to-bool. > The variant I suggested is to relax the true and false types and make them not-strict when not in strict-mode. Your motivation for the RFC is to make the bool type equivalent to true|false. This can be achieved by relaxing true and false types. Nicolas PS: what about null-forwarding cast operators? (?bool) to let null get through the cast? Just throwing in case it reaches anyone :) --000000000000ed4cef0639fbb42e Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


Le=C2=A0ven. 11= juil. 2025 =C3=A0=C2=A013:00, Gina P. Banyard <internals@gpb.moe> a = =C3=A9crit=C2=A0:

On Monday, 30 June 2025 at 10:26, Nicolas Grekas <nicolas.grekas+php@gm= ail.com> wrote:
Hi Gina

Thanks for experimenting with this on https://github.com/symfony/symfony/pull/60890/files

It's good to see that fitting this RFC requires a = relatively small number of lines to change even on a codebase like Symfony.= We're not at 100% but still nice.

Yet, it IS = a big bang in terms of deprecations to fix that this will trigger. Their nu= mber is super high, because these boolean conversions happen on hotpath / i= n loops.

This reminds me of the mandatory "?&= quot; for arguments with null defaults: the change made sense from a langua= ge design PoV, but the impact was, and still is very high. It was and still= is a very costly deprecation for the community, and it's not over yet.= That made me say at conferences that this was maybe not a good idea...

Looking at the diff above, I think I can draw two set= s of changes:
1. the ones that patch a cast-to-bool
2. the ones that patch a cast-from-bool

The latt= er, cast-from-bool, I think they're all useful improvements. While most= likely harmless in all the specific cases of the PR, doing e.g. an strpos(= ) on false feels hardly legit. I'm therefore sympathetic to making thes= e changes.

For cast-to-bool, I'm WAY less conv= inced. From the PR above, explicit casts like "return (bool) preg_matc= h(...)" on a method that returns a "bool" or "(bool) ($this<= /span>->loggedErrors & $type<= /span>)" are a clear downgrade: it makes the typing PHP just mor= e verbose without any real benefit. That doesn't look worth asking the = whole ecosystem to fix those deprecations. It is especially hard to see thi= s as an improvement when comparing to using the same expressions with e.g. = the "if ()" operator, which doesn't need the explicit cast (a= nd shouldn't of course).

Every cast-to-bool example you are providing are in= t-to-bool coercions, not string nor float casts type.

That's correct. I feel quite strongly=C2= =A0about this: int-to-bool casts should be handled gracefully by the engine= seamlessly.=C2=A0Deprecating them will (plan to) break many apps that are = just fine, and as Rob wrote (and you also in a gist), casting to (bool) is = what many will do, wrongly. This won't improve the language, quite the = contrary.

About string-to-bool PHP is still that l= anguage that allows quickly consuming $_GET['foo'] as whatever it= =C2=A0looks like as a string. I suspect tons of codebases rely on this beha= vior. To me, that's where the costs might outweigh=C2=A0the benefits...=

Especially= that even within SFs test suite, various cases of string-to-bool casts see= ms to be highlighting some sort of bug in the test suite.
Moreove= r, the fixes for the bitwise & operator are following the styles from s= urrounding functions that _already_ do that, and I was slightly confused ab= out the inconsistencies.

= That's an inconsistency favored by the strict-mode hype: people blindly= cast (and introduce bugs)... That inconsistency should be fixed the other = way around: removing these needless (and dangerous) casts.
=C2=A0=
The preg_match() API is j= ust unfortunate that it returns a boolean value as integers rather than boo= leans, as it uses a false return to communicate it emitted a warning instea= d of null.

Unfortunate=C2= =A0but still to be acknowledged as a likely contribution to making this RFC= a high-cost one for userland.
=C2=A0
Improving this API, is a very orthogonal problem to t= his, that we probably should be doing anyway (e.g. see if we can promote th= e warnings to exceptions).
And I could be convinced to carve out = an exception for int-to-bool, however that retains some complexity remember= ing PHP's type juggling rules, or have it as a secondary vote.

In the RFC, you write that its m= otivation is to allow making the bool type equivalent to the true|false uni= on. To do so you propose to make the bool type always behave like in "= strict" mode.

Personally, I'm moot about = the motivation. I understand it, but it looks inappropriate to push depreca= tions from this somewhat (IMHO) theoretical angle. The added friction would= need way stronger arguments to be justified IMHO.

Would it be possible to trigger the deprecation only in the cast-from-bool= direction, and accept casts-to-bool as seamlessly as there are now? If yes= , then would it also be possible to make the true and false types have the = same behavior (aka non-strict in casts-to-bool direction - when not in stri= ct mode of course)? If yes to both questions, then that'd look like a b= etter outcome that'd still allow fulfilling your goal, while providing = maximum value to the community.

As is, the cost/benefit ratio doesn't make this RFC look worth it to m= e.

As said a= bove, it is even possible to only warn on=C2=A0string- and float-to-bool an= d not on int-to-bool coercions.
But I still think theoretical ang= les are important, because allowing edge cases always adds complexity that = has causes us countless headaches in the past.

Las= t but not least, I'm not sure it's a good idea to rush this into 8.= 5. This is a high-impact change. We should give some time to the discussion= , understand the impact and explore variants. Merging this in 8.6 would als= o give a few more months for open-source projects to adapt to the change (s= ince many do run their CI with the master branch of PHP to spot changes as = early as possible.)

I'm not exactly certain I buy the argument that delaying this deprecat= ion is worthwhile, especially as I don't really think is as high impact= as it is made out to be.

Deprecating implicit null-ness was (still is) a high impact deprecation, a= nd this one has a higher potential impact IMHO.
=C2=A0
And I don't really see what &quo= t;variants" there are to explore other than a possible allowance for i= nt-to-bool.

The variant I= suggested is to relax the true and false types and make them not-strict wh= en not in strict-mode.=C2=A0Your motivation for the RFC is to make the bool= type equivalent to true|false. This can be achieved by relaxing true and f= alse types.
=C2=A0
Nicolas
PS: what about null-forwarding cast operators? (?bool) to let null get thr= ough the cast? Just throwing in case it reaches anyone :)
--000000000000ed4cef0639fbb42e--