Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:112733 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 98891 invoked from network); 3 Jan 2021 17:54:03 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 3 Jan 2021 17:54:03 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 6BCEE1804D4 for ; Sun, 3 Jan 2021 09:29:48 -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, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-lf1-f51.google.com (mail-lf1-f51.google.com [209.85.167.51]) (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 ; Sun, 3 Jan 2021 09:29:47 -0800 (PST) Received: by mail-lf1-f51.google.com with SMTP id b26so59299032lff.9 for ; Sun, 03 Jan 2021 09:29:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=Aa/Jpq8yDLl5ajGRbmwjYwKTxzH8KbVCnFnIduIwb7g=; b=JZ8jXe6ymg6eWfm2nG/NGXLQcjlY63kqaHHbz1rpCT6gaCZpnIIxJsU1ANslc4uWea Hmv/940eo8ZzYhYSVSH26lAJZDN9hxEKXIBbsCmXQg2g3NvdEVyIYZ2xr2fHSn/q4SDP YcxElv+7BBMS2NK9EamNEvOR5SQrFi4avGbX0yil97SZ9+rqrkjnGycHAn5cwIaqq88w 1Bnx06b0aYLTokIGWyCsspD1dyPP+Z/urk+tMi56BDPtzWQlaGnO6C3mbk0LdhDwECpF jBfuMwNbTbzLO8sXTesAUPNFrFIuJLvP7Yar5Ka6+ecYwJJScYy6Y21EAnqxajRKn7ny T/JA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=Aa/Jpq8yDLl5ajGRbmwjYwKTxzH8KbVCnFnIduIwb7g=; b=dh6QS3x87O7IDsXGQxitW15wXSekM0+YzhTDBfqEG803dYocwxjpky3+FQceZCXr35 gnDVoMPN4aUI+1ww0zhHkDFNyLemXuYgweSGit9AWsVi9ZxIO5lVLSFU8FYucMw5jVOs R1XSSvBK7ZSjFvsDzOkVd7YaLqxlcYyfAtfgsBvCCcxsyBxxAyLT7ZQC8lcTIr58PDe5 eCI9q+qTbcou/m7fAK/y/R33AulTfvwVOZ4aFby2xy7FaRAj+W7g/8MpCcblzq8FHTzs SF2xcqlJhtxxfAjFpcBLmK9gqep8VUmccV0gPAHeyjl3gnesCC4R9NqAPxC5z0R1LWBi TBdw== X-Gm-Message-State: AOAM530JHzgtZ+Xa+ZjGycS2WKmsF/PlT23B8+RhdzQest70QDYXHrzE IxWtPBLFdbr6OJnHoZ3frf5zPbGy91tlyhp9aNFLTQiu8Hk= X-Google-Smtp-Source: ABdhPJzLMEqLf8rd6X11lb7Wz/luwG4/VsMecSo/eHZzrtGGEfaMnSqR9QmqRDve58Zv7asJ7PWQ1/q5dZGMZ05j8N4= X-Received: by 2002:ac2:5970:: with SMTP id h16mr33830678lfp.338.1609694983941; Sun, 03 Jan 2021 09:29:43 -0800 (PST) MIME-Version: 1.0 Received: by 2002:ab3:7110:0:0:0:0:0 with HTTP; Sun, 3 Jan 2021 09:29:42 -0800 (PST) In-Reply-To: <12c6939d-14ed-4f7c-b2bc-189307a20f74@www.fastmail.com> 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, 3 Jan 2021 17:29:42 +0000 Message-ID: To: Larry Garfield Cc: php internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Analysis of property visibility, immutability, and cloning proposals From: olleharstedt@gmail.com (=?UTF-8?Q?Olle_H=C3=A4rstedt?=) 2021-01-03 16:55 GMT, Larry Garfield : > On Sun, Jan 3, 2021, at 8:28 AM, Olle H=C3=A4rstedt wrote: > >> >> I like that you connect higher level design patterns with language >> >> design. This is the way to go, IMO. Personally, I'd prefer support fo= r >> >> the Psalm notation `@psalm-readonly`, which is the same as your >> >> initonly. Clone-with makes sense too, as this construct is already >> >> supported in multiple languages. The exact notation doesn't matter >> >> that much - my personal choice is OCaml {record with x =3D 10} over J= S >> >> spread operator, but OCaml is pretty "wordy" in notation in contrast >> >> to the C tradition that PHP is part of. >> >> >> >> Reintroducing "objects that pass by value" is a hard pass from me. Th= e >> >> way forward is immutability and constrained mutability (ownership, >> >> escape analysis, etc). Psalm also supports array shapes - maybe this >> >> can be investigated as an alternative? Since PHP has no tuples. >> >> >> >> I'm not convinced the added complexity of asymmetric visibility is >> >> powerful enough to motivate its existence. Feel free to prove me >> >> wrong. :) My choice here would be namespace "internal" (also supporte= d >> >> by Psalm already), but this requires implementation of namespace >> >> visibility, a PR that was abandoned. >> >> >> >> And also, happy new year! >> > >> > Happy New Year! >> > >> > I agree that "objects, but passing by value" would not be the right >> > solution. I used to think that would be a good part of the solution, >> > but >> > eventually concluded that it would introduce more complexity, not less= . >> > Eventually, everything people wanted to do with objects they'd want to >> > do >> > with "Records" (for lack of a better term), and if they pass by value >> > but >> > are still mutable then you have a weird situation where sometimes >> > changes >> > propagate and some don't (depending on if you have a record or object)= . >> > Making it easier to use objects in a value-esque way will get us close= r >> > to >> > the desired end state. >> > >> > I think the tldr of my post is this: A single "immutable" flag >> > (whatever >> > it's called) on a class or property would require having lots of holes >> > poked >> > in it in order to make it useful in practice (mostly what "initonly" >> > would >> > do), but those holes would introduce other holes we don't want (clonin= g >> > an >> > object from the outside when you shouldn't). >> >> I new language feature needs to be both simple and powerful - it's not >> enough to be only powerful. A second problem I see is how asymmetric >> visibility would affect the readability of a class, putting extra >> strain in understanding it. Thirdly, how does PHP differ from FP >> languages like OCaml and Haskell in this regard, neither who uses >> visibility in this way? What's acceptable in those languages that >> would be unacceptable in PHP? >> >> Olle > > I'll disagree slightly. A language feature should introduce more power t= han > 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 l= ow, > 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 asymmetric > 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 have > properties that are inter-dependent. Those then cannot be made public-re= ad, > because that would also mean public-clone-with, and thus allow callers 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