Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126512 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 1B31C1A00BC for ; Wed, 26 Feb 2025 13:02:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1740574785; bh=i1y4s5wz0yr4cGmAzeU4byOwBdfbrBWDak89yfoEge8=; h=Date:From:To:In-Reply-To:References:Subject:From; b=F0cX80JYwQlYHd/lcMd94BFYThcNmPK3igJQA9ZAUn4FssN0dUNLdcSLl0wjNUwto vri4c8QtuSolVSVKc18vKf6UCKCUIgjhC7AV7NJjM+e3CBjsQTI/wx58sp8go0IQIF 7n9UJk8W+WKeKDK9eECmxMIZ60Jl8C2+r/D4LQLbHy0eNLIb0NttP63bkCzCD5xexJ WB+6KXYodVJp5r7IbdjvtHkqPilzg3VNr2Z9pMMXSOy4ecnBZQtwee1uottcIgSBIs vCpYX0vWjKIl4EcLK2xdzBOeFtRRHsXRgnUp+DMSZGzQ/+5rO1cPNbgVpMjGu8acBN zCn0nV7FxJ5vg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 56BDB1801D4 for ; Wed, 26 Feb 2025 12:59:44 +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=-4.6 required=5.0 tests=BAYES_00,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.0 X-Spam-Virus: No X-Envelope-From: Received: from fout-a1-smtp.messagingengine.com (fout-a1-smtp.messagingengine.com [103.168.172.144]) (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, 26 Feb 2025 12:59:43 +0000 (UTC) Received: from phl-compute-13.internal (phl-compute-13.phl.internal [10.202.2.53]) by mailfout.phl.internal (Postfix) with ESMTP id 9ECC01381DB9 for ; Wed, 26 Feb 2025 08:02:21 -0500 (EST) Received: from phl-imap-09 ([10.202.2.99]) by phl-compute-13.internal (MEProxy); Wed, 26 Feb 2025 08:02:21 -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=fm2; t=1740574941; x=1740661341; bh=i1y4s5wz0y r4cGmAzeU4byOwBdfbrBWDak89yfoEge8=; b=pJD5ooYPSaxfHIjRUR3SOc3R8X H04XbZU7aTseR9o1ekPeDoapt49FoPB/nhlq3UJBT5FnjnGKqqFXbTXrgsiTPVvk dswd201a8bUiYzMPfWh7cSlKuMyN8GDhqtKf8mqaB/CQpmIIvRSwdbP+cPa7POSN AoHA/rsbEm1mrKl0tyWX02rHdZjQ5GEU7uTsBo8jXQKYzEwzwe/J9U5k6n68qoCP rf2BjT6t4AmkBFUpkITcHsWZ/6nNeNLfZBIGe7JuhxJaCD/YzVYoGErADj0MwUnB jIPkCDBYtFrRx+EJPg9P23/cX4dRLvfqaeYWtidqWW8olE5qWtd8DHEiihDg== 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=fm1; t= 1740574941; x=1740661341; bh=i1y4s5wz0yr4cGmAzeU4byOwBdfbrBWDak8 9yfoEge8=; b=SaJ7YaFrFhOAiZrROebx6W3GZxtujQF1mjhskcS9Zquy9yE3YGq Loqis4OTxDk7rhzVMV/KnWLbKtTL/fsZrp8qHsk4S+Li1CFURZC4wqLtJsNFYRSh U4kiIl8IIz6ES1ASngUYYsysOnzIPrD8YR5DF6WVAKYPuFMyJm++eIK8Cucq/Jmz NPbBmV7q9RpcL9aR4qJVwJgcF8LYI7Ole9aGW6lVY2WF0bGftOILr5zhbEtur5tU Q0A79qcK9rzkhcACe2q1juP7BwNyocVMgKiY9FYpJJdd87MBVD0p2dhgo2Z19tNe rxseHkeXSH7mscZ4B4g97isjpZQajS7bzpQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdekgeeihecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdp uffrtefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecunecujfgurhepofggff fhvffkjghfufgtsegrtderreertdejnecuhfhrohhmpedftfhosgcunfgrnhguvghrshdf uceorhhosgessghothhtlhgvugdrtghouggvsheqnecuggftrfgrthhtvghrnheptdeuje dttefhueelhfdtleeiudetlefftdduleehffegtdeihefhleeijefgveegnecuvehluhhs thgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheprhhosgessghothhtlh gvugdrtghouggvshdpnhgspghrtghpthhtohepuddpmhhouggvpehsmhhtphhouhhtpdhr tghpthhtohepihhnthgvrhhnrghlsheslhhishhtshdrphhhphdrnhgvth X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 49A16780068; Wed, 26 Feb 2025 08:02:21 -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, 26 Feb 2025 14:02:00 +0100 To: internals@lists.php.net Message-ID: In-Reply-To: <1EBBCAA7-AC32-4C2F-8EB3-B1A69E1D1783@rwec.co.uk> References: <0b408765-04c4-49ed-bd5a-bceb34a2a3f1@app.fastmail.com> <1EBBCAA7-AC32-4C2F-8EB3-B1A69E1D1783@rwec.co.uk> Subject: Re: [PHP-DEV] Consensus gathering: allowing unsetting of backed property hooks Content-Type: multipart/alternative; boundary=13fc90f226324608ae6f8a91be0ebeb9 From: rob@bottled.codes ("Rob Landers") --13fc90f226324608ae6f8a91be0ebeb9 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Wed, Feb 26, 2025, at 09:17, Rowan Tommins [IMSoP] wrote: >=20 >=20 > On 25 February 2025 23:31:25 GMT, tight.fork3192@fastmail.com wrote: > >On 2/25/25 4:51 PM, Rowan Tommins [IMSoP] wrote: > >> I actually started writing an RFC to rationalise some of this behav= iour > > > >I'm glad I'm not the only one who considers this an issue worth pursu= ing! >=20 > Sorry, I wasn't clear: I was looking at the existing typed vs untyped,= unrefined vs uninitialised mess, before property hooks even existed. >=20 >=20 > > > >> Here are some of the things that might happen as a result of unset(= $foo->bar): > > > >I don't disagree that there's a lot of weirdness. But for better or w= orse that's where PHP is now - it's a fundamentally weird language. I th= ink it's better to be consistently weird than to be inconsistently weird. >=20 > My point is that it's *already* inconsistently weird. >=20 >=20 > > It would be inconsistent to allow unsetting some types of properties= but not others, and which ones can and can't be unset are indistinguish= able to a 3rd-party consumer. >=20 > unset() can already have a bunch of different effects depending on the= implementation of the class. As well as __unset being able to do *absol= utely anything*, I missed from my list "readonly" properties, which reas= onably enough *always throw an error for unset*, just like hooked proper= ties. >=20 >=20 > >I can't comment from an implementation perspective, but as a user of = PHP I would expect unsetting a backed property to return the property th= e "uninitialized" state, and subsequent access would proceed as if it we= re the first access of the uninitialized property. >=20 > An untyped property is currently never in the "uninitialised" state, o= nly a different "undefined" state. Presumably this inconsistency would n= eed to be preserved (for consistency) >=20 >=20 > >Unsetting a virtual property could simply do nothing, but not result = in a fatal error. I don't think a warning is even necessary because no a= ction is taken. >=20 > I don't see how that would be useful. The user presumably expected it = to do *something*, so informing them that it didn't seems preferable to = silently ignoring their request. It would also be inconsistent: a virtua= l property with no "set" hook throws an error when you try to set it, it= doesn't silently discard the value. >=20 >=20 >=20 > > I certainly don't want to be required to define an unset hook for ev= ery single backed property; rather `unset()` should have a default behav= ior. >=20 > I think you're focusing too closely on one use case, rather than all t= he ways people will want to use hooked properties. Imagine you have two = properties which you want to keep in sync: setting either of them recalc= ulates the other, using set hooks. >=20 > * It would be really surprising to the class author if a user of the c= lass could "reach in" and invalidate the state by calling unset() on one= of the properties. > * It would be really surprising to the user if doing so worked on one = of the properties, but silently did nothing on the other because it was = implemented as virtual. > * It might be appropriate for the class author to add "unset" hooks to= both properties, and for the user to see that unsetting one unset the o= ther, just as setting one sets the other. >=20 > That's just one scenario, I'm sure there are others where you could pi= cture different expectations, particularly accounting for some of the ot= her behaviour of unset(). That's what I mean by it being hard to specify= the behaviour; nothing to do with the implementation. >=20 > Regards, > Rowan Tommins > [IMSoP] I do think it makes sense to have an unset hook though, so long as it is= thought out well. For example, would the unset hook be called automatic= ally during garbage collection? Is it only called via unset() or are the= re other cases where it could be called too? Regardless of how wise it is to unset from outside a class, doing the su= ggested workaround from inside the class seems a bit odd as well. =E2=80=94 Rob --13fc90f226324608ae6f8a91be0ebeb9 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable
On Wed, Feb 26,= 2025, at 09:17, Rowan Tommins [IMSoP] wrote:


On 25 Feb= ruary 2025 23:31:25 GMT, tight.fork3192@fastmail.com wrote:
>On 2/25/25= 4:51 PM, Rowan Tommins [IMSoP] wrote:
>> I actually= started writing an RFC to rationalise some of this behaviour
<= div>>
>I'm glad I'm not the only one who considers t= his an issue worth pursuing!

Sorry, I wasn'= t clear: I was looking at the existing typed vs untyped, unrefined vs un= initialised mess, before property hooks even existed.

=

>
>> Here are some of t= he things that might happen as a result of unset($foo->bar):
>
>I don't disagree that there's a lot of weir= dness. But for better or worse that's where PHP is now - it's a fundamen= tally weird language. I think it's better to be consistently weird than = to be inconsistently weird.

My point is tha= t it's *already* inconsistently weird.


=
> It would be inconsistent to allow unsetting some types o= f properties but not others, and which ones can and can't be unset are i= ndistinguishable to a 3rd-party consumer.

u= nset() can already have a bunch of different effects depending on the im= plementation of the class. As well as __unset being able to do *absolute= ly anything*, I missed from my list "readonly" properties, which reasona= bly enough *always throw an error for unset*, just like hooked propertie= s.


>I can't comment from = an implementation perspective, but as a user of PHP I would expect unset= ting a backed property to return the property the "uninitialized" state,= and subsequent access would proceed as if it were the first access of t= he uninitialized property.

An untyped prope= rty is currently never in the "uninitialised" state, only a different "u= ndefined" state. Presumably this inconsistency would need to be preserve= d (for consistency)


>Unse= tting a virtual property could simply do nothing, but not result in a fa= tal error. I don't think a warning is even necessary because no action i= s taken.

I don't see how that would be usef= ul. The user presumably expected it to do *something*, so informing them= that it didn't seems preferable to silently ignoring their request. It = would also be inconsistent: a virtual property with no "set" hook throws= an error when you try to set it, it doesn't silently discard the value.=



> I certa= inly don't want to be required to define an unset hook for every single = backed property; rather `unset()` should have a default behavior.

I think you're focusing too closely on one use ca= se, rather than all the ways people will want to use hooked properties. = Imagine you have two properties which you want to keep in sync: setting = either of them recalculates the other, using set hooks.
* It would be really surprising to the class author if a us= er of the class could "reach in" and invalidate the state by calling uns= et() on one of the properties.
* It would be really surpri= sing to the user if doing so worked on one of the properties, but silent= ly did nothing on the other because it was implemented as virtual.
* It might be appropriate for the class author to add "unset" h= ooks to both properties, and for the user to see that unsetting one unse= t the other, just as setting one sets the other.

That's just one scenario, I'm sure there are others where you coul= d picture different expectations, particularly accounting for some of th= e other behaviour of unset(). That's what I mean by it being hard to spe= cify the behaviour; nothing to do with the implementation.

Regards,
Rowan Tommins
[IMSo= P]

I do think it makes sense t= o have an unset hook though, so long as it is thought out well. For exam= ple, would the unset hook be called automatically during garbage collect= ion? Is it only called via unset() or are there other cases where it cou= ld be called too?

Regardless of how wise it= is to unset from outside a class, doing the suggested workaround from i= nside the class seems a bit odd as well.

=E2=80=94 Rob
--13fc90f226324608ae6f8a91be0ebeb9--