Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:114747 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 32298 invoked from network); 5 Jun 2021 23:34:58 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 5 Jun 2021 23:34:58 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 6B11E1804BE for ; Sat, 5 Jun 2021 16:49:03 -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=-0.2 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,URIBL_SBL,URIBL_SBL_A autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-qt1-f181.google.com (mail-qt1-f181.google.com [209.85.160.181]) (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, 5 Jun 2021 16:49:02 -0700 (PDT) Received: by mail-qt1-f181.google.com with SMTP id k19so9996583qta.2 for ; Sat, 05 Jun 2021 16:49:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=newclarity-net.20150623.gappssmtp.com; s=20150623; h=from:message-id:mime-version:subject:date:in-reply-to:cc:to :references; bh=mOtK9fPXRgLoCtnnf4+CNlPpkq6BU7Y7aS/jmcwACGA=; b=1HV7X7c4JxrIaRTiwkSz+nXcOsUtsW7++GVfLrqqzsWNV0pFmJhjOe4HdoXRUghb8E zEqlK9PPAbQy/60CQ4aU9L7ghlEHINvccgkLlNTo+tuCBVMiRBxpQXrEJrCAb/N9d8Gd T+g7RFRc1i2Rin8TVuK+CHgnmhGHSU0pFX0INqitS08XFgl49UkFOY4227AZscOkeMmw MRLZbgRNiw2j9E/vw5rV8yqarDJ/o84RCXIn/J/0Q7CEPpYr+XGhsD+zfTEw9Rtl2hsh SxOBMTkCt5GwpomdG4d9E3bdUoTMyl517dpZUXcnH8GX8a48b7E5MHVl9QpWEFzbdypn UQXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:message-id:mime-version:subject:date :in-reply-to:cc:to:references; bh=mOtK9fPXRgLoCtnnf4+CNlPpkq6BU7Y7aS/jmcwACGA=; b=ATG+Rg2K872a/XtFvdIMsBBjSgSY1EhglQdSk8bfgNa1aDX8QP512TZAfxTatElrko 7wAMj2o478/XlYnxG25YqTygArVQb9SBCoGPBuXJVqxgMmrK4QwnOeYvbdpmWl1E2wgx BFtOitR8p5C6Nkq/24KagYydiwV9BxjVmoutoy6vDt4DDDVrGwBpknX1GTE/u+dOOVZF o7nj7LZz1BePlQeWTqX0a1oUJaap35x+1QlJAz1HYbu9XQp3Fwnss8x45DJcoxg61N+U kroDY1B4CCDTviLYiBbwzF4xvEOVu4bjiLYAfrmrL0uElEoWgnhxAFoCr7ULbBAADZ5k FfPg== X-Gm-Message-State: AOAM531RLnKRCV0yrvciEG9Hs2/22SDqoL9RVf62mR1zVKFdilMR6h0L 5zJYMPhI+dOOArY5+Ets4KWhaw== X-Google-Smtp-Source: ABdhPJwtR5E7j6+TfyPHJulvt22iItR1EJETfLypIvARs1aXeUJPl82O1JO/KPfCMt9Uk2N4qGx4yw== X-Received: by 2002:ac8:7282:: with SMTP id v2mr3394192qto.21.1622936938986; Sat, 05 Jun 2021 16:48:58 -0700 (PDT) Received: from [192.168.1.10] (c-24-98-254-8.hsd1.ga.comcast.net. [24.98.254.8]) by smtp.gmail.com with ESMTPSA id g5sm6780668qke.101.2021.06.05.16.48.57 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 05 Jun 2021 16:48:58 -0700 (PDT) Message-ID: <2ABEE784-4188-4CA1-A152-F2934B08B7A2@newclarity.net> Content-Type: multipart/alternative; boundary="Apple-Mail=_F378CBFA-7961-4C33-8806-7A4FEA2D1DC7" Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.6\)) Date: Sat, 5 Jun 2021 19:48:56 -0400 In-Reply-To: <83a9d0ab-60b8-4939-8be9-bdd6ddeb46c5@www.fastmail.com> Cc: php internals To: Larry Garfield References: <83a9d0ab-60b8-4939-8be9-bdd6ddeb46c5@www.fastmail.com> X-Mailer: Apple Mail (2.3608.120.23.2.6) Subject: Re: [PHP-DEV] [RFC] Readonly properties From: mike@newclarity.net (Mike Schinkel) --Apple-Mail=_F378CBFA-7961-4C33-8806-7A4FEA2D1DC7 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii > On Jun 5, 2021, at 12:51 PM, Larry Garfield = wrote: >=20 > On Fri, Jun 4, 2021, at 10:19 AM, Nikita Popov wrote: >> Hi internals, >>=20 >> I'd like to open the discussion on readonly properties: >> https://wiki.php.net/rfc/readonly_properties_v2 >>=20 >> This proposal is similar to the >> https://wiki.php.net/rfc/write_once_properties RFC that has been = declined >> previously. One significant difference is that the new RFC limits the = scope >> of initializing assignments. I think a key mistake of the previous = RFC was >> the confusing "write-once" framing, which is both technically correct = and >> quite irrelevant. >>=20 >> Please see the rationale section ( >> https://wiki.php.net/rfc/readonly_properties_v2#rationale) for how = this >> proposal relates to other RFCs and alternatives. >>=20 >> Regards, >> Nikita >=20 > Thank you for the detailed analysis in the rationale section. I am, = however, still skeptical of this approach, for a couple of reasons. >=20 > 1. This does appear to address the "leakage" problem I noted in my = earlier analysis around the start of the year, when considering the = writeonce proposal[1][2]. That's great to see. >=20 > 2. It doesn't address the larger question of cloning, however. The = answer for now seems "maybe we'll get clone-with at some point", which = would be a way around it, but there is no active RFC for that right now. = I'm obviously very in favor of RFCs that complement each other to give = more than the sum of their parts, but those RFCs need to be at least on = the horizon to actually come together. Right now that looks like it = won't happen this cycle. Absent clone-with, readonly would be = effectively unusable in any evolvable object of any non-trivial = complexity. It also wouldn't work with objects that need properties = that are not constructor arguments, such as PSR-7 type objects. That's = a no in my book. Larry, To address the cloning objection to raise to Nikita's RFC there is one = solution you did not mention in your blog post[1. Rather than your = clone-with using a syntax that does not exist anywhere else[2] in PHP we = could instead use one similar to your preferred "clone-with" approach = where a closure could be run in an internal context. This closure would = give the best of both your clone-with and of __clone() approaches. = Applying this approach to your example in [3] gives us: $r6 =3D clone $r5 with function($obj) { $obj->uri =3D new Uri('https://python.org/'); $obj->headers =3D ['host' =3D> 'http://java.com/']; $obj->version =3D 'the old one'; }; If PHP Internals were to approve the "Auto-capturing multi-statement = closures" RFC[4] we could also have auto-capture in a place where it = would be likely common: $uri =3D new Uri('https://python.org/'); $headers =3D [host =3D> 'http://java.com/']; $version =3D 'the old one'; $r6 =3D clone $r5 with fn($obj) { $obj->uri =3D $uri; $obj->headers =3D $headers; $obj->version =3D $version; }; Another improvement, which I don't know if it is possible or even = advisable, is if the closure could have automatic access to a $this = variable for the instance of the cloned object then it becomes even = simpler: $uri =3D new Uri('https://python.org/'); $headers =3D [host: 'http://java.com/']; $version =3D 'the old one'; $r6 =3D clone $r5 with fn() { $this->uri =3D $uri; $this->headers =3D $headers; $this->version =3D $version; }; Interestingly, using your example[2] again, if we were to adopt the same = syntax for `new` statements we could obviate the need for tedious and = verbose "wither" methods as well as the numerous internal clones and = throwaway variables needed with withers called immediately after = instantiation.=20 For example: $r2 =3D new Request() with fn() { $this->method =3D 'POST'; $this->uri =3D new Uri('https://php.net/'); $this->protocolVersion =3D '2.0'; $this->header =3D [ 'cache' =3D> 'none' ]; }; Lastly, you proposed "with" as your keyword to identify the = initialization values which I assume you picked it because of the = "wither" method pattern, and my examples above followed suit.=20 However, given `with` is not currently a reserved word in PHP and using = a closure inherently provides an existing keyword, PHP could leverage = `function` and/or `fn` to indicate "with." (Note the following example = do not include the two (2) enhancements mentioned above using fn and = $this): $r6 =3D clone $r5 function($obj) {...}; -Mike [1] = https://peakd.com/hive-168588/@crell/object-properties-and-immutability = =20= [2] Even though I would very much like to see that syntax become a = general purpose syntax for object instantiation, I think it would not be = good to use it unless it were fully fleshed out for much greater = utility. [3] = https://peakd.com/hive-168588/@crell/object-properties-part-2-examples = [4] https://wiki.php.net/rfc/auto-capture-closure = --Apple-Mail=_F378CBFA-7961-4C33-8806-7A4FEA2D1DC7--