Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:112835 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 52714 invoked from network); 10 Jan 2021 20:25:05 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 10 Jan 2021 20:25:05 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 12FB51804D3 for ; Sun, 10 Jan 2021 12:02:37 -0800 (PST) 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.6 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sun, 10 Jan 2021 12:02:36 -0800 (PST) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id D5BF85C00DE for ; Sun, 10 Jan 2021 15:02:35 -0500 (EST) Received: from imap26 ([10.202.2.76]) by compute4.internal (MEProxy); Sun, 10 Jan 2021 15:02:35 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=TqcEaa sASVGPdDVe+OkvymsnnXE3vHv1tiDK3tWFP7g=; b=opsz94KjaTnLCThRNmnfGJ R/YBuMaMsCrIkGYQPgRIwL6zT1x23mL9qI4BL/d4ga//tOE2YlqcWUwvLgIlmaIC Y68EJ1E6bj9gz2rkiZN+FeWXGy3OM86jbnA8B7FeIj3Fc8cWzAIIQT/jIJ50tH4L YYfdNcs+CweFUOy7dBZtAJwuLyzUgyji0fYZzsn30p2n8F6wvfrojDSL2dt4Gjq5 CILyzP2J3jYmk9KXQIFI1owFEs5R8oJNXtsL7zvOHB6UCpI1qeS99Dg8Y2Q2q462 cP30EuN2J6N0DAiKjcncYYSFpyNzZHNCE9o1M0jEcS4P0VJ50MXZOU3MQh8/vW8Q == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrvdegledgudeffecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpefofgggkfgjfhffhffvufgtsehttdertderreejnecuhfhrohhmpedfnfgr rhhrhicuifgrrhhfihgvlhgufdcuoehlrghrrhihsehgrghrfhhivghlughtvggthhdrtg homheqnecuggftrfgrthhtvghrnhepgfeiheeltdevieekleetuddtudekkeeiieekvdff ueekvddvleeugefhhedtkeffnecuffhomhgrihhnpehpvggrkhgurdgtohhmnecuvehluh hsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheplhgrrhhrhiesghgr rhhfihgvlhguthgvtghhrdgtohhm X-ME-Proxy: Received: by mailuser.nyi.internal (Postfix, from userid 501) id 60F6D14200A2; Sun, 10 Jan 2021 15:02:35 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.3.1-61-gb52c239-fm-20201210.001-gb52c2396 Mime-Version: 1.0 Message-ID: <75b2b6a3-ad9d-4c46-acbd-00fa3fc8e64a@www.fastmail.com> In-Reply-To: References: <1d0abb04-4987-43a9-85bc-bccc3bd6be9a@www.fastmail.com> <03108284-740a-4a5d-130f-15b2e67e9df9@mabe.berlin> <459d7ff7-e553-dce9-7d43-c3b1e772e572@gmail.com> <7f4fe9ca-1c20-6f69-cef0-a9718af742a3@gmail.com> <30906866-1971-8395-05a0-fd78d054bb89@gmail.com> <34d6a045-f7c3-4a77-8b22-378e84b2d1f9@www.fastmail.com> <12c6939d-14ed-4f7c-b2bc-189307a20f74@www.fastmail.com> Date: Sun, 10 Jan 2021 14:02:11 -0600 To: "php internals" Content-Type: text/plain Subject: =?UTF-8?Q?Re:_[PHP-DEV]_Analysis_of_property_visibility,_immutability,_a?= =?UTF-8?Q?nd_cloning_proposals?= From: larry@garfieldtech.com ("Larry Garfield") On Sat, Jan 9, 2021, at 7:24 PM, G. P. B. wrote: > On Sun, 10 Jan 2021 at 00:33, Larry Garfield wrote: > > It took a few days, but I am back with some more concrete examples. I > > decided to try and convert PSR-7 to the various options considered in my > > previous post. Here are the results: > > > > https://peakd.com/hive-168588/@crell/object-properties-part-2-examples > > > > Along with an analysis of the pros/cons of each. As shown there, > > `initonly` creates backdoors that make any but the most basic cases > > untennable. > > > > --Larry Garfield > > > > Thanks for dwelling into this. > > However, one can already have asymmetric visibility in PHP, just declare a > __get() handler. > Sure it is slow due to the VM -> User code -> VM jumps but it is possible. Many things are technically possible, but only in lame ways. The __get() callback is one such lame way of doing many things. The existence of a lame workaround for something hasn't stopped us from improving the developer experience of the language before nor should it now. > Moreover, asymmetric visibility does not prevent mutating an object by > calling the constructor once again as follows: > $obj->__construct(...$args); I agree with Rowan's point here. This is a bug in the language. I've never actually seen that bug exploited in the wild, but the answer here is to fix that bug, not to use it as justification to not improve the language. > This is IMHO the main reason why we want immutability/init only, not to > reduce getter methods or wither methods, even if this makes some of them > redundant. The "main reason" for immutability depends on who you ask. :-) My original post laid out some of the main arguments I've seen. Which one is the "main reason" is subjective and I don't think there's any clear consensus on it. Fortunately, if we do it right we can all get what we want out of it and it doesn't matter which benefit was more important in hindsight. > Also clone-with {} and clone "arguments" could very well be combined by > having the props list being passed to the clone-with instruction as a > $cloneContext array only available in __clone(), similar to how > $http_response_header is populated. [1] > The advantages I see in such a construct is that clone-with can handle any > type concerns (single/union, enums, literals, typed arrays, generics > if/when we get them) for the properties before passing them even to > __clone(). > If no __clone() handler is defined then it can just assign them but if > there needs to be one to handle extra validation, such as the type not > being sufficient or a property being dependent on another you are already > guaranteed that the property only needs minimal extra validation. That would entail assigning the properties first, then allowing __clone() to override if desired, if I understand you correctly. That means the object is in an invalid state at least for a time. I'm not wild about that. It would also change the logic of when __clone() happens, which right now is immediately after the object is duplicated. What you're suggesting is changing it to: * Duplicate object * Assign with'ed properties * Call __clone(), which could throw To be fair, I didn't consider where the with'ed properties would be assigned relative to __clone() in my writeup. (I should perhaps have done so.) But that still doesn't resolve the issue of all the validation being shoved into one big method. It only removes the "just assign it blindly" default case. All of the other validation is still needed, and still just as fugly. > As such I still believe immutability and asymmetric visibility are > orthogonal features which might be related but fundamentally solve > different problems. > One is about data integrity, the other is about removing getters/setters. Disagree. Asymmetric visibility achieves nearly all the same end results as initonly, but without introducing data integrity problems or fugly hacks (__clone()) to resolve them. The main takeaway from my experimentation, as I see it, is that initonly offers very little *in practice* in the way of data integrity guarantees beyond what asymmetric visibility does. Only in the trivial case where a property is fully validated by the type system automatically and has no inter-dependencies does it have any benefit. And the benefit is, actually, only moving the `clone with` statement from inside a single-expression method (which I'm hoping to make simpler, as noted) to the calling code. I'm not sure that's always a net win. --Larry Garfield