Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:122634 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 0FD721AD8F6 for ; Wed, 13 Mar 2024 22:27:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1710368846; bh=QL0+Jx9YYhg8p+XQG4k8GkSuo+r0024exxMjdG2EZ1k=; h=Date:Subject:To:References:From:In-Reply-To:From; b=nAbZOCAc7Xxxa7Bez1bo8tUdavI7borBHqB/kg+3JbKWTf+BDqJAoJRYNPIGEt2Mz OyF2ikSEX5Cfvw7mXJ0unFcGFjOW23WbLxzrojkcm8dzaVJpS9L/12vwQtHZpcLLPT zpSATamxZKTOWlN8kPMKGqWZ8D6SICpPzC9r8uiMrLjj2fOS/Mlq9b54rspR3FKzoT mi9aJwqkPaSvLKFyTCp6Oj4+2qVOeVh9OdAmDzh3oWbcIoh++w8zQHyOpsFM3lRyOc CrMgXdasAXdxG9/Gf6NdmpaCjvbHxzi/R3HrtiyM0aNEKF+I6lHb/9/A/YZ7YwtEYb U+nwXlwVYjaiQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 9317218005F for ; Wed, 13 Mar 2024 22:27:24 +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.1 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS, 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 out4-smtp.messagingengine.com (out4-smtp.messagingengine.com [66.111.4.28]) (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, 13 Mar 2024 22:27:23 +0000 (UTC) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id 84B285C0055 for ; Wed, 13 Mar 2024 18:27:05 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Wed, 13 Mar 2024 18:27:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rwec.co.uk; h=cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1710368825; x=1710455225; bh=vAct9A3Sfz rGEw2UMrIoy/dCp5YbaBZb5fMPVCmeVU4=; b=JzlUFCMvbaCsfds0zMCQie18qE cGfiOVdzPLkhA5HEKCs0eWXnedVjXDQmtJCs9AOFgZwv1CArvmzKzdmQ7Ej7wH3A hIF/Ug5bonrI5K9XfI+h6cKkMyPBtZLou7I1MZ5tRC6CYK/dmuAGVJa3BUMeAkqq XQxQHW/lLBDPqZFy+SzznUO0NOFLmWxFvFfPhyUPw9C6u5H+YqJhk8m96+2cy0dr DGlfHsYBl3zS4N3KkwP9pKdj863LqxcEZpAnHtfA0AgOPx7VZE55yhA4zYd7iMh9 Zdh6/qtkbZa+AqGx0fRG6IA/LlZ/kn4aN3SBWQ5pxSbygK92lNJtGRWvctwQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1710368825; x=1710455225; bh=vAct9A3SfzrGEw2UMrIoy/dCp5Yb aBZb5fMPVCmeVU4=; b=j4oFvYvZORgbLZepGdkV9P5aESlTZE0EqZBIEmb7f/dJ Bx9IoC0s7kbJUf93VwZer5B5tJfysNjXGEOKuH+RoHCb2RCk/P6YpQqMEpyNHWI4 7P3gm5drDVczTNsjLLRj8Y9WRiG/41dxq19JsSbTGP7iEIANWCtCXsC5fZoWY/0O NzVqQKb1L9hFk/LQ/p/q22TpPbe6iVRLki3VxoSjiONTyKdn+OjLKxOYNOCgjCSG 6ZVj2u4JmLVIR+5pKpct8jh74mWX3IBT5x/GzlspEaTMDhXvXHSX+c25yYRQdToK V21K8ikeKJEI/TMgQpQDtHQwRQaaUb3e9sstt0jjKw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrjeehgdduiedtucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpegtkfffgggfuffvfhfhjgesrgdtre ertddvjeenucfhrhhomhepfdftohifrghnucfvohhmmhhinhhsucglkffoufhorfgnfdcu oehimhhsohhprdhphhhpsehrfigvtgdrtghordhukheqnecuggftrfgrthhtvghrnhephe fftedvhfevffffueeuvdetvdeftdeigfeuvedttdehvefhueegkedvtdefheevnecuffho mhgrihhnpehgihhthhhusgdrtghomhdpfehvgehlrdhorhhgnecuvehluhhsthgvrhfuih iivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepihhmshhophdrphhhphesrhifvggt rdgtohdruhhk X-ME-Proxy: Feedback-ID: id5114917:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA for ; Wed, 13 Mar 2024 18:27:04 -0400 (EDT) Content-Type: multipart/alternative; boundary="------------liBxEoKcdAgx01dfJMDENmAz" Message-ID: <1698692e-8eb1-4bfc-a743-375696cd8f1c@rwec.co.uk> Date: Wed, 13 Mar 2024 22:26:59 +0000 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PHP-DEV] [RFC[ Property accessor hooks, take 2 To: internals@lists.php.net References: <7eada0fd-39c5-4a89-8c74-80c671801a2d@app.fastmail.com> Content-Language: en-GB In-Reply-To: <7eada0fd-39c5-4a89-8c74-80c671801a2d@app.fastmail.com> From: imsop.php@rwec.co.uk ("Rowan Tommins [IMSoP]") This is a multi-part message in MIME format. --------------liBxEoKcdAgx01dfJMDENmAz Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit On 12/03/2024 22:43, Larry Garfield wrote: > It's slightly different, yes. The point is that the special behavior of a hook is disabled if you are within the call stack of a hook, just like the special behavior of __get/__set is disabled if you are within the call stack of __get/__set. What happens when you hit an operation that would otherwise go into an infinite loop is a bit different, but the "disable to avoid an infinite loop" logic is the same. I guess I'm looking at it more from the user's point of view: it's very rare with __get and __set to have a method that sometimes accesses the "real" property, and sometimes goes through the "hook". Either there is no real property, or the property has private/protected scope, so any method on the classes sees the "real" property *regardless* of access via the hook. I think it would be more helpful to justify this design on its own merits, particularly because it's a significant difference from other languages (which either don't have a "real property" behind the hooks, or in Kotlin's case allow access to it only *directly* inside the hook definitions, via the "field" keyword). > The point is to give the user the option for full backwards compatibility when it makes sense. This requires jumping through some hoops, which is the point. This is essentially equivalent to creating a by-ref getter + a setter, exposing the underlying property. By creating a virtual property, we are "accepting" that the two are detached. While we could disallow this, we recognize that there may be valid use-cases that we'd like to enable. It also parallels __get/__set, where using &__get means you can write to something without going through __set. I get the impression that to you, it's a given that a "virtual property" is something clearly distinct from a "property with hooks", and that users will consciously decide between one and the other. This isn't my expectation; based on what people are used to from existing features, and other languages, I expect users to see this as an obvious starting point for defining a hooked property: private int $_foo; public int $foo { get => $this->_foo; set { $this->_foo = $value; } { And this as a convenient short-hand for exactly the same thing: public int $foo { get => $this->foo; set { $this->foo = $value; } } Choosing one or the other won't feel like "jumping through a hoop", and the ability to use an &get hook with one and not the other will simply seem like a weird oddity. > In practice I expect it virtual properties with both hooks to be very rare. Most virtual properties will, I expect, be lazy-computed get-only values. I don't think this is true. Both of these are, in the terms of the RFC, "virtual properties": public Something $proxied { get => $this->otherObject->thing; set { $this->otherObject->thing = $value; } }; public Money $price; public int $pricePence { get => $this->price->asPence(); set { $this->price = Money::fromPence($value); } } I can also imagine generated classes with "virtual" properties which call out to generic "getCached" and "setAndClearCache" methods doing the job of this pair of __get and __set methods: https://github.com/yiisoft/yii2/blob/master/framework/db/BaseActiveRecord.php#L274 > With the change to allow &get in the absence of set, I believe that would already work. > > cf:https://3v4l.org/3Gnti/rfc#vrfc.property-hooks Awesome! The RFC should probably highlight this, as it gives a significant extra option for array properties. (Also, good to know 3v4l has a copy of the branch; I hadn't thought to check.) Regards, -- Rowan Tommins [IMSoP] --------------liBxEoKcdAgx01dfJMDENmAz Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit
On 12/03/2024 22:43, Larry Garfield wrote:
It's slightly different, yes.  The point is that the special behavior of a hook is disabled if you are within the call stack of a hook, just like the special behavior of __get/__set is disabled if you are within the call stack of __get/__set.  What happens when you hit an operation that would otherwise go into an infinite loop is a bit different, but the "disable to avoid an infinite loop" logic is the same.


I guess I'm looking at it more from the user's point of view: it's very rare with __get and __set to have a method that sometimes accesses the "real" property, and sometimes goes through the "hook". Either there is no real property, or the property has private/protected scope, so any method on the classes sees the "real" property *regardless* of access via the hook.

I think it would be more helpful to justify this design on its own merits, particularly because it's a significant difference from other languages (which either don't have a "real property" behind the hooks, or in Kotlin's case allow access to it only *directly* inside the hook definitions, via the "field" keyword).



The point is to give the user the option for full backwards compatibility when it makes sense. This requires jumping through some hoops, which is the point. This is essentially equivalent to creating a by-ref getter + a setter, exposing the underlying property. By creating a virtual property, we are "accepting" that the two are detached. While we could disallow this, we recognize that there may be valid use-cases that we'd like to enable.  It also parallels __get/__set, where using &__get means you can write to something without going through __set.


I get the impression that to you, it's a given that a "virtual property" is something clearly distinct from a "property with hooks", and that users will consciously decide between one and the other. 

This isn't my expectation; based on what people are used to from existing features, and other languages, I expect users to see this as an obvious starting point for defining a hooked property:

private int $_foo;
public int $foo { get => $this->_foo; set { $this->_foo = $value; } {

And this as a convenient short-hand for exactly the same thing:

public int $foo { get => $this->foo; set { $this->foo = $value; } }

Choosing one or the other won't feel like "jumping through a hoop", and the ability to use an &get hook with one and not the other will simply seem like a weird oddity.



In practice I expect it virtual properties with both hooks to be very rare.  Most virtual properties will, I expect, be lazy-computed get-only values.


I don't think this is true. Both of these are, in the terms of the RFC, "virtual properties":

public Something $proxied { get => $this->otherObject->thing; set { $this->otherObject->thing = $value; } };

public Money $price;
public int $pricePence { get => $this->price->asPence(); set { $this->price = Money::fromPence($value); } }

I can also imagine generated classes with "virtual" properties which call out to generic "getCached" and "setAndClearCache" methods doing the job of this pair of __get and __set methods: https://github.com/yiisoft/yii2/blob/master/framework/db/BaseActiveRecord.php#L274





With the change to allow &get in the absence of set, I believe that would already work.  

cf: https://3v4l.org/3Gnti/rfc#vrfc.property-hooks


Awesome! The RFC should probably highlight this, as it gives a significant extra option for array properties.

(Also, good to know 3v4l has a copy of the branch; I hadn't thought to check.)


Regards,

-- 
Rowan Tommins
[IMSoP]
--------------liBxEoKcdAgx01dfJMDENmAz--