Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:128132 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 BEB8C1A00BC for ; Sat, 19 Jul 2025 07:46:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1752911090; bh=0rRGG2hfIqOMf02uQAt0bWECDmi6cAmSOuqVQb9sugA=; h=Date:From:To:Cc:In-Reply-To:References:Subject:From; b=D9vT5gtbIHhVW8dHzVM+JsRx4lPmDSkphYVOk4QGiC9Idr0AIH44SOxlIzlyPzuIk sqhioB8Wt3nI3+qeZQ944qIcjqfeshz/Yqqk0F0HVMcqH43mzEOMencWW4tEyZ//pV 3bUZdPRKZqA82jVWqd43JngtJ99j2oMtGb9pQ1Xtkl7SsB0fz/WHezSXbSg08xfyn7 nJc3JOLqcrhbFEub0pX4X8r+mh+o/icGRN3pk553LJA4GNiO3/cqnVumF27ITMdH/U ckFBfxgyzXY2g6t1W8rzEkKat3bRXTVMT5rOrUYcr9izC47w7V/7bF49GvUxENjXfb PUhebH+Z/tWIA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 13D19180074 for ; Sat, 19 Jul 2025 07:44:50 +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.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.1 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from fhigh-a2-smtp.messagingengine.com (fhigh-a2-smtp.messagingengine.com [103.168.172.153]) (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 ; Sat, 19 Jul 2025 07:44:49 +0000 (UTC) Received: from phl-compute-05.internal (phl-compute-05.phl.internal [10.202.2.45]) by mailfhigh.phl.internal (Postfix) with ESMTP id E9A2014000DF; Sat, 19 Jul 2025 03:46:35 -0400 (EDT) Received: from phl-imap-05 ([10.202.2.95]) by phl-compute-05.internal (MEProxy); Sat, 19 Jul 2025 03:46:35 -0400 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=fm3; t=1752911195; x= 1752997595; bh=X2ZDIXz6VNxV0FuyANfXIHvoiJJrHxoUXHBKqx+1yf8=; b=c 1hiP4cFT9HdAQCsYkPkiG1aJz64Jdly1rNrG8ISjlbAXcJwRIYLOhU8YTQBN0y9v YMfRMnaaDIie8yNw5I/ItS4t3jBBb4fvmJEMpqS8MK/H2+93VHI2RszglRnadGv5 wy8wJ9lBfHQEcxwdGgqk9u5qc0DXzlWh8ye6DTL539T/4slNauG6Fum08EhyKt5x N582MW7RTxiuMY6afbJzPYDu65AS/eBipC03w9GGOk0NVgX2BcSGMZyOzu7fz82/ uptyEFcGGW2ZFH8q/kGrprQoGfXFj8OW8IPUzAYqMAtSnw83oBvH0P7JmscAovjC rYXoXuqfO/f0VojAHIZAA== 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=fm2; t= 1752911195; x=1752997595; bh=X2ZDIXz6VNxV0FuyANfXIHvoiJJrHxoUXHB Kqx+1yf8=; b=kt73W74TpHmGt2+1FjnlXLCEDfxAoebb5FXBw8+skOjLPLFIRcP b+qMHZ4TMd5LL7k+XaVxwE8llUQk7Ctxw3ke6ZJjt4jQ/RlgfuwgSbtJkpeJeEiq VImpsTDu8A61Nnjqahy3mKCnBhTXqsuR0nKEttEJyRS8c5z47gyISosTISG6d+l1 HZ/YnRT4UQDB4mZMAM7ZzVYoi2GSTshL6qy+oBb+P4H81q0Edijgx01PMajHzQ8h LXIQnUIIZ4zuujZtVjpIgKc+A7WzcZPZ6RVcRFLBX63VljS7Cs6o3S4vb71x2uZZ 0h6xYh1GTf1wuRs+empsnQx/Ux37kX7q5Dg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdefgdeiheejiecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpuffrtefokffrpgfnqfghnecuuegr ihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjug hrpefoggffhffvvefkjghfufgtsegrtderreertdejnecuhfhrohhmpedftfhosgcunfgr nhguvghrshdfuceorhhosgessghothhtlhgvugdrtghouggvsheqnecuggftrfgrthhtvg hrnhepieeuteehvddvfeejhffgieehleehhedthfefkeejffelgfevvdekudetjeejtddt necuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheprhhosg essghothhtlhgvugdrtghouggvshdpnhgspghrtghpthhtohepiedpmhhouggvpehsmhht phhouhhtpdhrtghpthhtohepthhimhessggrshhtvghlshhtuhdrsggvpdhrtghpthhtoh eplhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhmpdhrtghpthhtoheptghlrghu uggvrdhprggthhgvsehgmhgrihhlrdgtohhmpdhrtghpthhtohepvghrihgtthhnohhrrh hishesghhmrghilhdrtghomhdprhgtphhtthhopehnihgtohhlrghsrdhgrhgvkhgrshdo phhhphesghhmrghilhdrtghomhdprhgtphhtthhopehinhhtvghrnhgrlhhssehlihhsth hsrdhphhhprdhnvght X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 37CBE1820074; Sat, 19 Jul 2025 03:46:35 -0400 (EDT) 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 X-ThreadId: T5f4527d1a0d4de24 Date: Sat, 19 Jul 2025 09:46:14 +0200 To: "Claude Pache" Cc: erictnorris@gmail.com, "Nicolas Grekas" , "Larry Garfield" , =?UTF-8?Q?Tim_D=C3=BCsterhus?= , "php internals" Message-ID: <247034b6-04cf-4f3e-a145-a30171af8c12@app.fastmail.com> In-Reply-To: <77128196-8D53-40D6-9BB7-77160AD71ED9@gmail.com> References: <378cd8b0-c4a8-4e53-b0bd-e9e4f30a454d@app.fastmail.com> <77128196-8D53-40D6-9BB7-77160AD71ED9@gmail.com> Subject: Re: [PHP-DEV] Re: [RFC] Readonly property hooks Content-Type: multipart/alternative; boundary=3312265fb50a43a4a2fa5360eff95da9 From: rob@bottled.codes ("Rob Landers") --3312265fb50a43a4a2fa5360eff95da9 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Sat, Jul 19, 2025, at 03:04, Claude Pache wrote: >=20 >=20 >=20 >> Le 19 juil. 2025 =C3=A0 00:41, Rob Landers a =C3=A9= crit : >>=20 >> The original author (Nikita) suggested that there's nothing in the or= iginal design that precludes accessors -- and highlights languages where= there are both and they are doing just fine more than 5 years later. >>=20 >=20 > Hi Rob, >=20 > It is indeed entirely reasonable to have both readonly properties and = hooked properties (aka accessors), and today PHP has indeed both of them= (and even asymmetric visibility on top of that, as a separate feature c= ontrarily to C#). But it doesn=E2=80=99t mean that it is reasonable for = the *same* property to be *both* readonly and hooked, which is the point= that is currently disputed. =E2=80=94 What do the other languages allow= ? Is it possible to define a readonly property with a user-defined gette= r? (Disclaimer: Even if one of them allows such a thing, I=E2=80=99ll st= ill think that it is a bad idea.) >=20 > =E2=80=94Claude=20 Hey Claude, From what I've seen in other languages, this combination is fairly commo= n and not inherently poblematic. - C# allows get hooks with user-defined logic, even in readonly structs. - Kotlin uses val with a get() body, which is readonly from the consumer= 's perspective, even though the value is computed. - TypeScript allows a get-only accessor which acts readonly. - Swift also allows get-only computed accessors/hooks. Most languages treat these as an abstraction boundary: allowing you to e= xpose computed state while still guaranteeing external immutability. This RFC is proposing something similar: the public surface is observabl= y immutable, even if a value is derived. We can already do this today wi= th more boilerplate: class Foo { public function __construct(private readonly int $_bar) {} public int $bar { get =3D> $this->_bar * 2; } } The RFC reduces that boilerplate and clarifies intent. In the example ab= ove, there is nothing mutable about it. It is "read only" from a public = contract point-of-view, we just can't mark it as a readonly class. As for side-effects or non-determinism, that is a valid concern, but one= that applies to any property hook and non-scalar property. A readonly d= eclaration doesn't necessarily encourage or prevent that, it simply decl= ares that the instance state cannot be mutated after construction. I'd argue the RFC aligns well with the conventions and capabilities of o= ther languages, and builds on what PHP already allows. =E2=80=94 Rob --3312265fb50a43a4a2fa5360eff95da9 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable


On Sat, Jul 19, 2025, at 03:04, Claude Pache wrote:


<= br>
Le 19 juil. 2025 =C3=A0 00:41, R= ob Landers <rob@bottled.codes> a =C3=A9crit :

The original author (Nikita) suggested= that there's nothing in the original design that precludes accessors --= and highlights languages where there are both and they are doing just f= ine more than 5 years later.


Hi = Rob,

It is indeed entirely reasonable to have b= oth readonly properties and hooked properties (aka accessors), and today= PHP has indeed both of them (and even asymmetric visibility on top of t= hat, as a separate feature contrarily to C#). But it doesn=E2=80=99t mea= n that it is reasonable for the *same* property to be *both* readonly an= d hooked, which is the point that is currently disputed. =E2=80=94 What = do the other languages allow? Is it possible to define a readonly proper= ty with a user-defined getter? (Disclaimer: Even if one of them allows s= uch a thing, I=E2=80=99ll still think that it is a bad idea.)
=
=E2=80=94Claude 

Hey Claude,

From what I've seen in oth= er languages, this combination is fairly common and not inherently = poblematic.

- C# allows get hooks with user-def= ined logic, even in readonly structs.
- Kotlin uses val with a= get() body, which is readonly from the consumer's perspective, even tho= ugh the value is computed.
- TypeScript allows a get-only acce= ssor which acts readonly.
- Swift also allows get-only compute= d accessors/hooks.

Most languages treat these a= s an abstraction boundary: allowing you to expose computed state while s= till guaranteeing external immutability.

This R= FC is proposing something similar: the public surface is observably immu= table, even if a value is derived. We can already do this today with mor= e boilerplate:

class Foo {
 = public function __construct(private readonly int $_bar) {}
&n= bsp; public int $bar { get =3D> $this->_bar * 2; }
}

The RFC reduces that boilerplate and clarifies int= ent. In the example above, there is nothing mutable about it. It is "rea= d only" from a public contract point-of-view, we just can't mark it as a= readonly class.

As for side-effects or non-det= erminism, that is a valid concern, but one that applies to any property = hook and non-scalar property. A readonly declaration doesn't necessarily= encourage or prevent that, it simply declares that the instance state c= annot be mutated after construction.

I'd argue = the RFC aligns well with the conventions and capabilities of other langu= ages, and builds on what PHP already allows.

=E2=80=94 Rob
--3312265fb50a43a4a2fa5360eff95da9--