Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:118565 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 55779 invoked from network); 5 Sep 2022 14:41:06 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 5 Sep 2022 14:41:06 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 38C111804B1 for ; Mon, 5 Sep 2022 07:41:01 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-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,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS, SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS19151 66.111.4.0/24 X-Spam-Virus: No X-Envelope-From: Received: from out3-smtp.messagingengine.com (out3-smtp.messagingengine.com [66.111.4.27]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Mon, 5 Sep 2022 07:41:00 -0700 (PDT) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id 677B65C00D8 for ; Mon, 5 Sep 2022 10:40:59 -0400 (EDT) Received: from imap50 ([10.202.2.100]) by compute1.internal (MEProxy); Mon, 05 Sep 2022 10:40:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= garfieldtech.com; h=cc:content-transfer-encoding:content-type :date:date:from:from:in-reply-to:in-reply-to:message-id :mime-version:references:reply-to:sender:subject:subject:to:to; s=fm1; t=1662388859; x=1662475259; bh=iP6ZVrc9KgLvQki7omMD7jmQl yC10QG/QMEQGzGc/Ec=; b=VT8YEm6mMoEaoBs7CDM7vSW16236UoJEsLyHjHZiO s/bICOjf/ybA1Ua+jvd4fh9VNtEdOZsZz5VP/+EGwCj3LQRj8F29Enp1Z09JIdJ0 lBieHQt8fIE8r7tdgbyBQwJbdn8Bv5QUvIRaAkRP5dTi1pgLzqnuxuBxfK5pd2GO bz8rEDLlVyObd+iS4uwSKosvhf0kJNgOB9Gqm6zTzIU0ISP+5Aqnbd28uq5vP98v bH+uztUY5zWMpx0G5zFgXt/G3Xq0NN66bQqfFInlz42ZniDp5ZOxhR/TpQtvdv/M kbuPm7g2XcsPPcwwQjR43a+EQHscJYPNpN5OrHVtikZNg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:date:feedback-id:feedback-id:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to:x-me-proxy:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; t=1662388859; x=1662475259; bh=i P6ZVrc9KgLvQki7omMD7jmQlyC10QG/QMEQGzGc/Ec=; b=2QcqEtHvBkIExSDz9 Q1uUqM1uVznBX6X0Ra6wWvTZYgqMIsnYWYkUReUBJdW8U8TzFii2c/2rKxBeKNqf Ib0j42TpvcuBx3EDBc/Q0H+0qfgtPjKvnBxuTJwzmARVPHGkTHC4zBlFFCzTFtJ5 yY3I9pWbRTmMC8AviPMMC34FPjLg6KRWrCLQ7QnEocIrWMH3K8YcWWYwW0g6nn3X RZI1ttByDBkQsR3s/s7m3Rn6OsnZUDjucXXvKX6zULIJWqqqLzlKGvEjq21RPwFM eMGAOwfK9w27EGjwMlxPlTREfXM5R6Mm4rEDLSFP8OGSCJFuCzVEXdf129IfDXVC BkPNw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedrvdeliedgkeduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepofgfggfkjghffffhvffutgfgsehtqhertderreejnecuhfhrohhmpedfnfgr rhhrhicuifgrrhhfihgvlhgufdcuoehlrghrrhihsehgrghrfhhivghlughtvggthhdrtg homheqnecuggftrfgrthhtvghrnhepffffffejffdugfegvedviedttedvgfejffefffej leefjeetveehgefhhfdvgfelnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpe hmrghilhhfrhhomheplhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhm X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.nyi.internal (Postfix, from userid 501) id 2EA491700082; Mon, 5 Sep 2022 10:40:59 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.7.0-alpha0-927-gf4c98c8499-fm-20220826.002-gf4c98c84 Mime-Version: 1.0 Message-ID: In-Reply-To: References: Date: Mon, 05 Sep 2022 09:40:26 -0500 To: "php internals" Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Re: Issues with readonly classes From: larry@garfieldtech.com ("Larry Garfield") On Mon, Sep 5, 2022, at 4:01 AM, M=C3=A1t=C3=A9 Kocsis wrote: > Regarding your main question: I understand your problem with readonly > classes, and I'd be happy if we found a solution which fits your use-c= ases > and keeps consistency for the engine at the same time. To give you more > context about the inheritance related restriction in the RFC: I went w= ith > forbidding the extension of readonly classes by non-readonly ones so t= hat > the invariants of the parent (no dynamic or mutable properties are all= owed) > don't occasionally get violated by the child. However, I cannot think = about > a proper scenario now where this would cause any problems... I'm wonde= ring > if anyone could come up with one? I don't have a real-world example, but a general pattern. The advantage= of a readonly object (either conventionally like PSR-7 or enforced by t= he `readonly` keyword) is that you can store a reference to it without h= aving to worry about it changing out from under you. That means you can= code on the assumption that any data derived from that object is also n= ot subject to change. If you accept a readonly object of type Foo, you would write code around= it on that assumption. If you're then passed an object of type Bar extends Foo, which has an ex= tra non-readonly property, that assumption would now be broken. Whether= that counts as a Liskov violation is... a bit squishy, I think. Where that might be a problem is a case like this: readonly class Person { public function __construct(public string $first, public string $last)= {} public function fullName() { return "$this->first $this->last";=20 } } class FancyPerson extends Person { public string $middle =3D ''; public function setMiddle(string $mid) {=20 $this->middle =3D $mid;=20 } public function fullName() {=20 return "$this->first $this-middle $this->last";=20 } } class Display { public function __construct(protected Person $person) {} public function hello() { return "Hello " . $this->person->fullName(); } } Now, Display assumes Person is readonly, and thus fullName() is idempote= nt, and thus Display::hello() is idempotent. But if you pass a FancyPer= son to Display, then fullName() is not safely idempotent (it may change = out from under you) and thus hello() is no longer idempotent. Whether or not that problem actually exists in practice is another quest= ion. And to be fair, the same risk exists for conventionally-readonly c= lasses today (PSR-7, PSR-13, etc.), unless they're made final. Arguably= the safety signaling of a lexically readonly class is stronger than for= a conventionally readonly class, so one would expect that to not be bro= ken. But that's the case where a non-readonly child of a readonly paren= t can cause problems. Personally I'm undecided at the moment whether or not it should be allow= ed. I'm sympathetic to the "it's easier to disallow and allow later tha= n vice versa" argument, but still not sure where I stand. The above at = least gives a concrete example of where the problem would be. --Larry Garfield