Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:122667 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 CB8221AD8F6 for ; Sun, 17 Mar 2024 14:41:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1710686511; bh=V8TN8ufIgSp7BnPBtMBqETtiZ8uNHcqWLm8SnCk9jss=; h=Date:Subject:To:References:From:In-Reply-To:From; b=SZ6wcIEPmv5LND3bze5TgYUUg6TtwEbrypcNzWleeWZaHtXR119SQmR6C6GXgAE2Z 3nW082CYCdE/Q7pAptF7uN+XlQAFjnqrJRHt+xU6zPX8yE3GL2Iger6Rf+ajsEHKaw GsajlwP+SJKCs4zP8u8XnEyyAuckb4bySqnXsbbT2S/DHJMBxdTEM4rcKyqXIPX0YR wZ/aqdkW/O7pFTTtK8fa55P7kA0akrlbeLzt8eKIFFupSqQugBJ3EOcR5mcrb6EwSG bumt/6/qHQAJCnu1905nVSQzVJCQGleb5VxZqcMViVnAIltvpnKXmdgbEz3vkuLqCm 19GJwpcBr6xAA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 0E7FD180004 for ; Sun, 17 Mar 2024 14:41:50 +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,RCVD_IN_DNSWL_LOW, 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 wfhigh5-smtp.messagingengine.com (wfhigh5-smtp.messagingengine.com [64.147.123.156]) (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 ; Sun, 17 Mar 2024 14:41:49 +0000 (UTC) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailfhigh.west.internal (Postfix) with ESMTP id 863FA1800073 for ; Sun, 17 Mar 2024 10:41:28 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Sun, 17 Mar 2024 10:41:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rwec.co.uk; h=cc :content-transfer-encoding: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=fm2; t=1710686488; x=1710772888; bh=iLP/0aofLthDUf/r23tMSS1Ojcxf7XfxvNSx/2dpVRM=; b= SQ2wAfubNdX60EfG8h8k0PpRG+W+dh4o70ZP4zhTcBCx1qgv2ecokKe5hK6wjf0U 4TrcMD7Dhex6ZaIVcECkkIg6JpaC9K6OhAdcInnC8FH6l246/pBDZFlt53zCMLZz uNrkPQNrm35dZDpWiloMXV1ooYoYYqm9OeNmzu9VlJR2YYrr+vb1YtK6R7zcEviQ Ep7pZM5rhvGnPvC1arwvMFKCSNyTpsFiacTWbMMkFrWc5DLUS2r/LrOD1z6LSe2u jdJQMLHF6D05eEGgADfZDbKDkZWJ9K7IxiezpH2i3XK4LGrpVBgriBqpBtp9YQYU jevb5NAzrd9jIzni2hA1ug== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding: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=fm2; t=1710686488; x= 1710772888; bh=iLP/0aofLthDUf/r23tMSS1Ojcxf7XfxvNSx/2dpVRM=; b=Z 34NH1Ur4cbJBc3VyOcYEoTyhLCPTkgnwXWtUKLEDjGwKfBwMxz3Gv1ao6CJ9fQ+C Y5gQPhlLZQGJZUddNPrBQ1GeVVUX0W71jci917y7jeVpSdT6i87GHqevt+veAAOX e3Lm4bmS6KDe7kocTkBx5ssYITH6UJo9Hogz2qVNUnouTLb3TY0DFsuO135XFZTn jYY0WLnQFwjlmAv4lBC+Gv/j/akYyapYk2nGkWrfKXqgOCMcOryNQJW5X4SaU79B YvF/x9ZNHjwyfwT7cfXjXQXDrF1gBwdBgk+jOJD7m2s+2+AJQ+0Fn8k0Ww0PzVt4 TmX3j9QM4i/ArWkA5tSgQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrkeehgdeggecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhepkfffgggfuffvfhfhjggtgfesthekre dttddvjeenucfhrhhomhepfdftohifrghnucfvohhmmhhinhhsucglkffoufhorfgnfdcu oehimhhsohhprdhphhhpsehrfigvtgdrtghordhukheqnecuggftrfgrthhtvghrnhepje eggfehjeevkeelhfdugfffteevgeejheetgfetueeiheegvedtheelhffhueeunecuffho mhgrihhnpeefvheglhdrohhrghenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmh epmhgrihhlfhhrohhmpehimhhsohhprdhphhhpsehrfigvtgdrtghordhukh X-ME-Proxy: Feedback-ID: id5114917:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA for ; Sun, 17 Mar 2024 10:41:27 -0400 (EDT) Message-ID: Date: Sun, 17 Mar 2024 14:41:19 +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 Content-Language: en-GB To: internals@lists.php.net References: <7eada0fd-39c5-4a89-8c74-80c671801a2d@app.fastmail.com> <1698692e-8eb1-4bfc-a743-375696cd8f1c@rwec.co.uk> <154481e0-5f62-4026-994a-28a644d71527@app.fastmail.com> <46609F15-DD40-4BD2-A78A-16021C3447C8@rwec.co.uk> In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit From: imsop.php@rwec.co.uk ("Rowan Tommins [IMSoP]") On 17/03/2024 00:01, Ilija Tovilo wrote: > For clarity, you are asking for a way to make the "virtualness" of > properties more explicit, correct? Either more explicit, or less important: the less often the user needs to know whether a property is virtual, the less it matters how easily they can find out. > Please let me know if > you are aware of any other potentially non-intuitive cases. I agree that while they may not be immediately obvious to the user, most of the distinctions do make sense once you think about them. The remaining difference I can see in the current RFC which seems to be unnecessary is that combining &get with set is only allowed on virtual properties. Although it may be "virtual" in the strict sense, any &get hook must actually be referring to some value stored somewhere - that might be a backed property, another field on the current class, a property of some other object, etc: public int $foo { &get => $this->foo; set { $this->foo = $value; } } public int $bar { &get => $this->_bar; set { $this->_bar = $value; } } public int $baz { &get => $this->delegatedObj->baz; set { $this->delegatedObj->baz = $value; } } This sentence from the RFC applies equally to all three of these examples: > That is because any attempted modification of the value by reference would bypass a |set| hook, if one is defined. I suggest that we either trust the user to understand that that will happen, and allow combining &get and set on any property; or we do not trust them, and forbid it on any property. > Apart from the things already mentioned, it's unclear to me whether, > with such `set;` declarations, a `get`-only backed property should > even be legal. With the complete absence of a write operation, the > assignment within the `set` itself would fail. To make this work, the > absence of `set;` would need to mean something like "writable, but > only within another hook", which introduces yet another form of > asymmetric visibility. Any write inside the get hook already by-passes the set hook and refers to the underlying property, so there would be no need for any default set behaviour other than throwing an error. It's not likely to be a common scenario, but the below works with the current implementation https://3v4l.org/t7qhR/rfc#vrfc.property-hooks class Example {     public int $nextNumber {         get {             $this->nextNumber ??= 0;             return $this->nextNumber++;         }         // Mimic the current behaviour of a virtual property: https://3v4l.org/cAfAI/rfc#vrfc.property-hooks         set => throw new Error('Property Example::$nextNumber is read-only');     } } > Fair enough. 1 and 2 are reasons why we added the `$field` macro as an > alternative syntax in the original draft. I don't quite understand > point 3. In Kotlin, `field` is only usable within its associated hook. > Other languages I'm aware of do not provide a way to access the > backing value directly, neither inside nor outside the accessor. We are already allowing more than Kotlin by letting hooks call out to a method, and have that method refer back to the raw value. Hypothetically, we could allow *any* method to access it, using some syntax like $this->foo::raw. As a spectrum from least access to most access: 1) $field - accessible only in the lexical scope of the hook 2) $this->foo - accessible in the dynamic scope of the hook, e.g. a hook calling $this->doSomething(__PROPERTY__); 3) $this->foo::raw - accessible anywhere in the class, e.g. a public clearAll() method by-passing hooks Whichever we provide for backed properties, option 3 is available for virtual properties anyway, and common with __get/__set: store a value in a private property, and have a public hooked property providing access to it. I understand now that option 2 fits most easily with the implementation, and with decisions around inheritance and upgrade of existing code; but the other options do have their advantages from a user's point of view. > I personally do not feel strongly about whether asymmetric types make > 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. I will spend time in the following days cleaning up tests, and > I will try my best to try to break asymmetric types. If I (or anybody > else) can't find a way to do so, I don't see a reason to remove them. My concern is more about the external impact of what is effectively a change to the type system of the language: will IDEs give correct feedback to users about which assignments are legal? will tools like PhpStan and Psalm require complex changes to analyse code using such properties? will we be prevented from adding some optimisation to OpCache because these properties break some otherwise safe assumption? Maybe I'm being over-cautious, but those are the kinds of questions I would expect to come up if this feature had its own RFC. Regards, -- Rowan Tommins [IMSoP]