Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:112825 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 68346 invoked from network); 10 Jan 2021 01:47:35 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 10 Jan 2021 01:47:35 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id C44A61804DD for ; Sat, 9 Jan 2021 17:24:55 -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.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.49]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sat, 9 Jan 2021 17:24:55 -0800 (PST) Received: by mail-ej1-f49.google.com with SMTP id t16so19594251ejf.13 for ; Sat, 09 Jan 2021 17:24:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=jh6sbOuwU0MqHsqFT+wQyRqE/wEOtzA2RSh0iGXmPU8=; b=iu08UjleuUiCbox6upBeldYj41W9Al4jSIE0SZr8DJKjwWaLw2JTO+izqNpbXtxJOI fW3QRtjtPGBkpRPRE/Md9Zx6Xx3VhwMSpWv1vR8KWOER8LQDH7v+eV8OkxjDpV/RQchs +xQVNuUeEulH2zU5Br98NulBei2TjWANIWHJrfqkDS2ruYpC4Xw5Vg6nuFfzNOOjREfx lju5yUMbGhGLS+IP9zhACfNbFf7tJQK4HD9rXmxUllmnVmlmOnJ7MGRddy0y/C93l2R+ VSBj6bylMfY3hjHae3Mqn18v6kutZKE3SH7O7WcGarxL6a6TyexfQs4Pzp5uG5rjImiL c/LQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=jh6sbOuwU0MqHsqFT+wQyRqE/wEOtzA2RSh0iGXmPU8=; b=JIqAfsSO3gMtjGSWCW3rB+PTMU9dmy6BlQl/w/ms6fiefrLdIug6OrUvSPkPy665gT l44GoNqUBK9xACI27v5yiNgSveQaoU5mHLFFJP70+G8koZ6kLWTETPjTwJrzYwDahofY 2/gnTFYrj5BLoevZwao1o69st09h7aZbNZV3MxGANKUFG8muqpI9CUic39lUYBHwMCso aAKpEwACpXHCkvlNAbKqZN8ZmoOAN8T/k42uWj+OoFYwRebCFo2rxiUkT+lB/opyjIIc JvixCrsvBTa6HXpI0cCV9CH92Mi7wziI/F2JbYzGnWSG3e3zV/QIN6HSg+qQCQHvfhEW 4Yyg== X-Gm-Message-State: AOAM530Aw/gG53rsZNgd0StJiWJpwqtk/HI50wqO3bq50m1Vy1VCs0RS 1vkukmV8Gq/nNWk49DOBHhCbUGN+v7E9Ugodv+W7MBul+WZPNw== X-Google-Smtp-Source: ABdhPJyJ0a3EXlg5dfhF/lvR3uCqc50vKkmL4RuINULi42jnDdx03cw6JozqpNoquBGuetVfCG1/BvLJOWe3GEDQumc= X-Received: by 2002:a17:906:378f:: with SMTP id n15mr6638025ejc.263.1610241890821; Sat, 09 Jan 2021 17:24:50 -0800 (PST) MIME-Version: 1.0 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> In-Reply-To: Date: Sun, 10 Jan 2021 01:24:38 +0000 Message-ID: To: Larry Garfield Cc: php internals Content-Type: multipart/alternative; boundary="000000000000e7ac7505b881a711" Subject: Re: [PHP-DEV] Analysis of property visibility, immutability, and cloning proposals From: george.banyard@gmail.com ("G. P. B.") --000000000000e7ac7505b881a711 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sun, 10 Jan 2021 at 00:33, Larry Garfield wrote= : > On Sun, Jan 3, 2021, at 11:29 AM, Olle H=C3=A4rstedt wrote: > > > > I'll disagree slightly. A language feature should introduce more > power than > > > it does complexity. Not everything *can* be made absolutely simple, > but the > > > power it offers is worth it. I'd say it should minimize introduced > > > complexity, relative to the power offered. Complexity ideally is > super low, > > > but it's never zero simply by virtue of being "one more thing" that > > > developers need to know how to read. > > > > > > So in this case, we need to compare the power/complexity of asymmetri= c > > > visibility vs the power/complexity of "immutable... except in these > > > situations." I would argue that asymmetric visibility is more > > > self-documenting, because it states explicitly what those situations > are. > > > > > > The other point is that, as noted, "initonly" creates a gap if you ha= ve > > > properties that are inter-dependent. Those then cannot be made > public-read, > > > because that would also mean public-clone-with, and thus allow caller= s > to > > > violate property relationships. Asymmetric visibility does not have > that > > > problem. > > > > Can you perhaps be a bit more clear on why initonly/readonly would be > > a deal breaker? Seems to me like readonly would cover 80% of > > use-cases? Which is to make data-value objects humane (and fast, since > > you don't need getters anymore) to work with. Seems like you're > > focusing too much on an edge case here. Maybe we should list the > > possibly use-cases? Or at least the main target use-case. > > > > If an object has invariants that need to hold, just throw an exception > > in __clone to force use with withX() instead? Or, as you suggested, > > improve __clone by giving it arguments? > > > > Olle > > 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. Moreover, asymmetric visibility does not prevent mutating an object by calling the constructor once again as follows: $obj->__construct(...$args); 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. 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. 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. Best regards, George P. Banyard [1] https://www.php.net/manual/en/reserved.variables.httpresponseheader.php --000000000000e7ac7505b881a711--