Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:123104 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id 4EBC61A009C for ; Wed, 10 Apr 2024 22:08:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1712786923; bh=UoS4HAIAJ8e/WS+mQPAic+PihUkPXctqN0AEZ6pE5qE=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=mBGFE89aWSfTLM5e2LAcPqJYfBd5hixmO1vwFMA7a/2masLsB0WxpjX61HIwVzako DGbJ/z1jzg/XXfeIG7ZpXELAP2ZEaB7TAYjvtvhLh7hU53c9lJN1sTP+F5soTfwC41 PuQ+UoGIW8FhhEVxS17OZMXBx4DGTxPL49Ssqjeu8M5m39IzJvJ2UJ43xglUIA/cHf 5LgzxZhGCRdNdMLrIQjrVv0NAuh7SeZARyl7z6PrslBcbWDqM6orCthxlc8c8iTnrM GcaY3rJCDpkzRawx4MlGF8lBq9WIV79n5yO/mayEfR3FlCbppYz7OvsEYc2RIIILY/ VNdUOU5dcprPw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id AE62F18007B for ; Wed, 10 Apr 2024 22:08:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-vk1-f170.google.com (mail-vk1-f170.google.com [209.85.221.170]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 10 Apr 2024 22:08:39 +0000 (UTC) Received: by mail-vk1-f170.google.com with SMTP id 71dfb90a1353d-4dabc6f141bso1556607e0c.2 for ; Wed, 10 Apr 2024 15:08:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1712786885; x=1713391685; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=cbt9RAhTaGzI/EPWwQaVX5qMClBV0CHNgRZ41tHqoRE=; b=c0zDmS78YohctD4VU6YTw5Eul37HPbUZnQe4E67aqSEZldSl/EEIAPIprYSeVH5Yln N75v4906WtBA9dFZl4XQkvBChUtLCx9A4O6gGrc64Cism6Pb7quwCiFNn5LrF9xMIvbO D9msls2MaiMdP5ZJq9rbNXjRobyG8wCnD+Cm2zx5JAW/LUZ+sqtdjSGLpiVeS6UDntx0 knP1HZL0fPCipr99C7URxpNz1EPYHNfCtulohxOtVTDpmGkYGGD01mMQhfDusJapd6Qs S6pdSBWM2PNZo5ouKuS9UIEVALBl/7It6CjI3PbPl8DNs9vzuQUq1y5RTrz894UrElDl wVZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712786885; x=1713391685; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=cbt9RAhTaGzI/EPWwQaVX5qMClBV0CHNgRZ41tHqoRE=; b=w0aaZ18932fRew++2hIO0PFjs4qCAx/eygJScm5BH4QCSe1Upbaj0RyavQdhSf2Onx N7vpWhmLEXnWZto+/WVFI8jQUqIAyEZk9OtDXdn3Ub5/ptRFkdZc0Akc7Vwit4w541sI AD2T2xpJwMN+ofBQB+JPnESiu+Cx7ShHRr+D3QleZz7Zj/pR2tdri45udqKFu5aNmLUU 6UAiP+RQZjXvPqHzvlNClduGkxRWZchb2jhB208yK1vj7sFHGKJFAHlOlfLOw6xd6N42 kkmr8N6bdYmtop7wc2SPtNIBiuexMps5VkU85kXVMTud7x2dkZLqlPefuiASRS31uDbq AxiA== X-Gm-Message-State: AOJu0YznUGGg4E7QSGzlAuq04YtUO7c2+AQpubvZc7ZfoMaqtMAIKjmS 1eBjyxC7+l6aO2/u+bY6K8J7csOq+DFowS6YB2PhENrAeOxnJ8Ht9LKmSxOfpjY1I75kxL5AIgV I9eIOkSOAF9ykiEHhH0/dquJRI+0= X-Google-Smtp-Source: AGHT+IH2hS+C7ycrb1/euuRtO78wxInE2v201JvzINE8+pMY+mtJzS/JtWEyslUXfq+KleJvj4q0EiXf7n8+LlmM+C8= X-Received: by 2002:a05:6122:2a0c:b0:4db:1b9d:c70a with SMTP id fw12-20020a0561222a0c00b004db1b9dc70amr1208802vkb.0.1712786885426; Wed, 10 Apr 2024 15:08:05 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 References: In-Reply-To: Date: Wed, 10 Apr 2024 17:07:53 -0500 Message-ID: Subject: Re: [PHP-DEV] [RFC][Vote announcement] Property hooks To: Ilija Tovilo Cc: PHP internals Content-Type: multipart/alternative; boundary="000000000000e1c8240615c545f0" From: mweierophinney@gmail.com ("Matthew Weier O'Phinney") --000000000000e1c8240615c545f0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Mon, Apr 8, 2024 at 4:41=E2=80=AFPM Ilija Tovilo wrote: > Hi everyone > > Heads-up: Larry and I would like to start the vote of the property > hooks RFC tomorrow: > https://wiki.php.net/rfc/property-hooks > > We have worked long and hard on this RFC, and hope that we have found > some middle-ground that works for the majority. One last concern we > have not officially clarified on the list: > > https://externals.io/message/122445#122667 > > After reading JRF's reply, I found myself nodding along. I feel like while a lot of the _details_ of my original feedback were addressed, the _themes_ largely were not, and many overlap with what Juliette noted. I've taken some time again today to review the proposal, and I think I can boil my main concern down to _consistency_, and _ensuring reviewer comprehension_ when somebody is reviewing code that includes hooks. New features in PHP really should veer away from allowing _implicit_ behavior, and should be internally consistent with existing syntax (unless they are attempting to make an explicit change to existing syntax). On this latest review, I've got fewer concerns, but I still have some. 1. I'm not a fan of _implicit_. I strongly feel that there's no use case for `set` without an argument. Requiring the argument makes explicit that it is _receiving_ a value, and also makes it explicit _at the definition point_ what value _type_ is accepted, and what it is _named_. (I realize I might be in a minority here, though, and the fact that I can require this as a CS rule (eventually) mitigates it to a degree. It feels like an opportunity to reduce errors by requiring it, however.) 2. I'm not a huge fan of the short syntax, but the improvements in the most recent draft are _mostly_ ones I can live with. The part that's still unclear is when and where hooks need a `;` termination, and _why_ the `;` is used, instead of `,`. When using `match()` expressions, you use `,` to separate the expressions, but for some reason, the proposal uses `;` ... but only when using short expressions. And if you have a full-form mixed with a short form, the `;` is only needed for the short-form expression. This feels arbitrary, and it will be easy to get it wrong for people comfortable with `match()` statements. My gut take is that the syntax should use `,` to separate hooks in ALL cases: ``` public string $content { get { $content =3D str_replace(' ', ' ', $this->content); return $this->convert($content); }, set(string $value) =3D> $value, } public string $summary { get =3D> $this->convert($this->summary), set(string $value) { $value =3D str_replace((' ', ' ', $value); $this->summary =3D $value; }, } ``` This more closely matches `match()` expressions (pardon the pun), and provides a template for how we might allow blocks in `match()` expressions in the future. (Larry tells me that it's `match()` being weird here, but considering that for many developers, their only point of reference for this sort of syntax IS `match()`, making it feel like the language is ignoring its own syntax when creating new syntax.) 3. While I'd likely prefer Marco's approach to references (just don't allow them), the fact that they mirror how `__get()` and `__set()` _currently_ work gives a migration path for users who are familiar with that paradigm's gotchas. In other words, it's consistent with the current language, and will make migrating from `__set/__get` to hooks easier. It's a lot of complexity, but the table you created helps with that. That table MUST make it to the docs for the feature! 4. The interaction with serialization has a LOT of different cases, and looks like a great place to observe foot guns in the future. I'd like to see a more consistent, predictable approach here, but knowing how many pitfalls there are in serialization normally, I'm not expecting one; at least it's being consistent with how each of the serialization methods already work. What I DO expect is that you create a table detailing the behavior for the docs, similar to the one you did for references/backed values/virtual. While I definitely feel for QA/CS tool makers (this is a HUGE chunk of new syntax, and non-trivial), I also don't know how this could be done in a way that would be simpler. My only suggestions would be to remove short-form syntax and require type/varname for `set` always, but even with those changes, I think similar levels of complexity will still exist to write parsers/formatters for these anyways. I personally have wanted these features in the language for likely 15 years. Maybe the foundation might be able to sponsor some developer time towards helping the QA/CS tool makers with these features once merged (assuming the RFC passes)? > >> I personally do not feel strongly about whether asymmetric types make > it into the initial implementation. Larry does, however, and I think it i= s > not fair to exclude them without providing any concrete reasons not to. > [snip] > > > > My concern is more about the external impact of what is effectively a > change to the type system of the language: [snip] will tools like PhpStan > and Psalm require complex changes to analyse code using such properties? > > In particular, this paragraph is referencing the ability to widen the > accepted $value parameter type of the set hook, described at the > bottom of https://wiki.php.net/rfc/property-hooks#set. I have talked > to Ond=C5=99ej Mirtes, the maintainer of PHPStan, and he confirmed that > this should not be complex to implement in PHPStan. In fact, PHPStan > already offers the @property-read and @property-write class > annotations, which can be used to describe "virtual" properties > handled within __get/__set, already providing asymmetric types of > sorts. Hence, this concern should be a non-issue. > > Thank you to everybody who has contributed to the discussion! > > Ilija > --=20 Matthew Weier O'Phinney mweierophinney@gmail.com https://mwop.net/ he/him --000000000000e1c8240615c545f0 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


=
On Mon, Apr 8, 2024 at 4:41=E2=80=AFP= M Ilija Tovilo <tovilo.ilija@g= mail.com> wrote:
Hi everyone

Heads-up: Larry and I would like to start the vote of the property
hooks RFC tomorrow:
https://wiki.php.net/rfc/property-hooks

We have worked long and hard on this RFC, and hope that we have found
some middle-ground that works for the majority. One last concern we
have not officially clarified on the list:

https://externals.io/message/122445#122667


After reading JRF's reply, I found= myself nodding along. I feel like while a lot of the _details_ of my origi= nal feedback were addressed, the _themes_ largely were not, and many overla= p with what Juliette noted.

I've taken some ti= me again today to review the proposal, and I think I can boil my main conce= rn down to _consistency_, and _ensuring reviewer comprehension_ when somebo= dy is reviewing code that includes hooks. New features in PHP really should= veer away from allowing _implicit_ behavior, and should be internally cons= istent with existing syntax (unless they are attempting to make an explicit= change to existing syntax).

On this latest review= , I've got fewer concerns, but I still have some.

1. I'm not a fan of _implicit_. I strongly feel that there'= s no use case for `set` without an argument. Requiring the argument makes e= xplicit that it is _receiving_ a value, and also makes it explicit _at the = definition point_ what value _type_ is accepted, and what it is _named_. (I= realize I might be in a minority here, though, and the fact that I can req= uire this as a CS rule (eventually) mitigates it to a degree. It feels like= an opportunity to reduce errors by requiring it, however.)

2. I'= ;m not a huge fan of the short syntax, but the improvements in the most rec= ent draft are _mostly_ ones I can live with. The part that's still uncl= ear is when and where hooks need a `;` termination, and _why_ the `;` is us= ed, instead of `,`. When using `match()` expressions, you use `,` to separa= te the expressions, but for some reason, the proposal uses `;` ... but only= when using short expressions. And if you have a full-form mixed with a sho= rt form, the `;` is only needed for the short-form expression. This feels a= rbitrary, and it will be easy to get it wrong for people comfortable with `= match()` statements.

My gut take is that the syntax should use `,` t= o separate hooks in ALL cases:

```
public string $content {
= =C2=A0 =C2=A0 get {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 $content =3D str_replace= (' =C2=A0', ' ', $this->content);
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 return $this->convert($content);
=C2=A0 =C2=A0 },
=C2= =A0 =C2=A0 set(string $value) =3D> $value,
}

public string $su= mmary {
=C2=A0 =C2=A0 get =3D> $this->convert($this->summary),<= br>=C2=A0 =C2=A0 set(string $value) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 $value= =3D str_replace((' =C2=A0', ' ', $value);
=C2=A0 =C2=A0= =C2=A0 =C2=A0 $this->summary =3D $value;
=C2=A0 =C2=A0 },
}
``= `

This more closely matches `match()` expressions (pardon the pun), = and provides a template for how we might allow blocks in `match()` expressi= ons in the future.

(Larry tells me that it's `= match()` being weird here, but considering that for many developers, their = only point of reference for this sort of syntax IS `match()`, making it fee= l like the language is ignoring its own syntax when creating new syntax.)
=C2=A0
3. While I'd likely prefer Marco's approach= to references (just don't allow them), the fact that they mirror how `= __get()` and `__set()` _currently_ work gives a migration path for users wh= o are familiar with that paradigm's gotchas. In other words, it's c= onsistent with the current language, and will make migrating from `__set/__= get` to hooks easier. It's a lot of complexity, but the table you creat= ed helps with that. That table MUST make it to the docs for the feature!
4. The interaction with serialization has a LOT of different cases, an= d looks like a great place to observe foot guns in the future. I'd like= to see a more consistent, predictable approach here, but knowing how many = pitfalls there are in serialization normally, I'm not expecting one; at= least it's being consistent with how each of the serialization methods= already work. What I DO expect is that you create a table detailing the be= havior for the docs, similar to the one you did for references/backed value= s/virtual.

While I definitely feel for QA/CS t= ool makers (this is a HUGE chunk of new syntax, and non-trivial), I also do= n't know how this could be done in a way that would be simpler. My only= suggestions would be to remove short-form syntax and require type/varname = for `set` always, but even with those changes, I think similar levels of co= mplexity will still exist to write parsers/formatters for these anyways.

I personally have wanted these features in the langu= age for likely 15 years. Maybe the foundation might be able to sponsor some= developer time towards helping the QA/CS tool makers with these features o= nce merged (assuming the RFC passes)?
=C2=A0
>> I personally do not feel strongly about whether asymmetric types m= ake it into the initial implementation. Larry does, however, and I think it= is not fair to exclude them without providing any concrete reasons not to.= [snip]
>
> My concern is more about the external impact of what is effectively a = change to the type system of the language: [snip] will tools like PhpStan a= nd Psalm require complex changes to analyse code using such properties?

In particular, this paragraph is referencing the ability to widen the
accepted $value parameter type of the set hook, described at the
bottom of https://wiki.php.net/rfc/property-hooks#set= . I have talked
to Ond=C5=99ej Mirtes, the maintainer of PHPStan, and he confirmed that
this should not be complex to implement in PHPStan. In fact, PHPStan
already offers the @property-read and @property-write class
annotations, which can be used to describe "virtual" properties handled within __get/__set, already providing asymmetric types of
sorts. Hence, this concern should be a non-issue.

Thank you to everybody who has contributed to the discussion!

Ilija


--
he/him
<= /div>
--000000000000e1c8240615c545f0--