Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:120294 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 95051 invoked from network); 15 May 2023 18:34:42 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 15 May 2023 18:34:42 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id AE7EA1804F8 for ; Mon, 15 May 2023 11:34:41 -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=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_NONE, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS19151 66.111.4.0/24 X-Spam-Virus: No X-Envelope-From: Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Mon, 15 May 2023 11:34:41 -0700 (PDT) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 9B3FD5C028D for ; Mon, 15 May 2023 14:34:40 -0400 (EDT) Received: from imap50 ([10.202.2.100]) by compute4.internal (MEProxy); Mon, 15 May 2023 14:34:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= garfieldtech.com; h=cc:content-type:content-type:date:date:from :from:in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm1; t=1684175680; x= 1684262080; bh=CbIhPHNG3+lDHpgQ+m0zaW6MsI55Tpsk9Ypz2/wukSM=; b=h +ehAMAFAcn11WWoUA80apMlMlASwUBEtyq9mrpfxBnxrS/MlLXiBuNMxlwxFm4xd ShIpDUZfo+z6kD6cVWwOW/SDwoCp5G+xH0B+H9MaAFVRDstj+7K4a6jyLa0HE0dw wT/fdMZ7e3Icn7I7R5EoLms6hDgiBekLqrv7K2CCXpTlls9oFwqOl7p7ZIWCdg/3 JL0ySFEH/W5s8B6/4FmX1UoXlpkYAMSgSZemIqoXuiMd8tkZviYg9lc8qY/F2+9o 0oiPnCQL033IfpN7G5IetT73DrWzElwENtAl8EmHcdt66MLvr43sLFY99Ok1SHbu y63sTxyTgVjaji4yEln2g== 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:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm1; t=1684175680; x=1684262080; bh=CbIhPHNG3+lDH pgQ+m0zaW6MsI55Tpsk9Ypz2/wukSM=; b=O4SzUPJXQSrEerp4yTB92UjLNT32R LLqxbN/oEHuxDgJ9T40Gc4GkNmG1yO7oC7ympOqZoZtf+p+glNQr8Y16keq033wE bIQ9vyZn42ZHCLd6omiZzTisKhpJojys6aj+i84DsjqueHUkV1CNUCbya7pSLbhn 6qhMxstR0//GieAaTVuPArNP1vVbwNkXskvVluRsypmhaVAlOBhnUp0tsqHA8+fb Md8xHOfig7uJOaD/a5e6FN180gayqUjNgEU9mdEho+oHg+4cwoWCeBMxLnsfANGM 9nz+ejNBzsNsPw3wkiy51rrCEJ//2aCF3UYUY8s2MIEMboSOjIfCa8NeA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrfeehjedguddvkecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpefofgggkfgjfhffhffvufgtsehttdertderredtnecuhfhrohhmpedfnfgr rhhrhicuifgrrhhfihgvlhgufdcuoehlrghrrhihsehgrghrfhhivghlughtvggthhdrtg homheqnecuggftrfgrthhtvghrnhepgeelgfekudeivddvteffueejffdthfejieevhefg ffekudevkedtvdelvddvffefnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpe hmrghilhhfrhhomheplhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhm X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.nyi.internal (Postfix, from userid 501) id 4AC611700089; Mon, 15 May 2023 14:34:40 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.9.0-alpha0-415-gf2b17fe6c3-fm-20230503.001-gf2b17fe6 Mime-Version: 1.0 Message-ID: In-Reply-To: References: <641b1ca0-d33f-4f38-ae64-81b4abce24da@app.fastmail.com> Date: Mon, 15 May 2023 18:34:19 +0000 To: "php internals" Content-Type: text/plain Subject: Re: [PHP-DEV] [RFC] Property hooks, nee accessors From: larry@garfieldtech.com ("Larry Garfield") Consolidating all replies into a single message. Please try to keep them together so it's easier to respond to. (Also, when replying, please please remove duplicate names from the to/cc line. I just got double copies of everything in this thread this morning. I'm on the list, I don't need to be CCed.) On Sun, May 14, 2023, at 11:41 PM, Hendra Gunawan wrote: > Hi Larry. > > ``` > public string $fullName => $this->first . " " . $this->last; > ``` > 1. Suppose that I forgot to declare ```$this->first```. Based on the > "deprecate dynamic properties" proposal, will I get an error/warning? Correct, it will behave the same as if you had a fullName() method that accessed an undefined $first property. > 2. The shorthand notations supported (the shortest one) creates > impaired syntax, and not pretty to look at for constructor property > promotion. > > ``` > public function __construct( > public string $prop1 => strtoupper($this->_prop1), > public string $prop2 {set => $field = strtolower($value);}, > ){} > ``` Well, the first is not really valid anyway. That creates a virtual property with no set hook, which when you pass a value to it in the constructor call will give an error that you are trying to write to a virtual property. So that's already a non-issue. For the second, the problem with omitting the {} is that it creates yet another syntax variant. That makes it harder for the parser, for static analyzers, for user-space parsing tools like php-parser, etc. That's more work for everyone for fairly little gain. Removing the {} entirely from all forms makes it harder to denote where the list of hooks begins and ends. They would probably have to be comma-separated, like this: public string $foo get { return $this->bar; }, set { $this->bar = $value; }; Which I'd argue is harder to read anyway, because you have to be careful of the very small , and ; marks. The {} is just easier for humans to parse as well as the machine. > Suppose that I just want to cache once and freeze, and I don't want to > create additional hidden property. Please make a judgement on the > validity of this syntax: > ``` > public string $prop1 { > get => $field ??= $this->heavyTask($this->propx, $prop->y); > set => null; > } > ``` > > Explanation: > * Since the ```get``` hook uses ```$field```, the engine will create a > backing store value with name ```$prop1```, and will be filled at the > first call only. The later call will use the already stored value. > * Since no new value is assigned to ```$field``` in the ```set``` > hook, the value stored in ```$prop1``` is still the same as before. > * Since any return statement will be discharged in ```set``` hook, the > assignment chaining is safe to use and the value which is transferred > is alway the rightmost value (not the value returned by the ```set``` > hook). > ``` > $varx = $obj->prop1 = "hello"; // $varx value is "hello", and > $obj->prop1 value is unchanged > ``` An interesting approach. It should work as you describe, but there's two reasons I would discourage it: 1. A "set that doesn't set" creates unexpected behavior for callers. If I call set, I expect something to happen. It would be rather confusing to call set and not set things. 2. It doesn't actually allow a cache clearing option. What we really would need here is asymmetric visibility. No set hook, but make the property private(set) so that trying to write to it gives an error, as it should. For cache clearing, the best way to do that is probably with an unset hook. That's been omitted from the RFC for now for simplicity, but that sounds like it would be an argument to introduce it later. Asymmetric visibility would be the higher priority, though. > But, this statement below is NOT ALWAYS correct for "cache once and freeze": > ``` > public string $prop1 { > set => $field ??= $this->heavyTask($this->propx, $prop->y); > } > ``` > Explanation: > * Since default ```get``` hook can be called before ```set``` hook, > backing store value with name ```$prop1``` will still be empty. > * Otherwise, I have to duplicate the body of the ```set``` hook into > ```get``` hook to prevent an emptiness backing store. > > Please give a comment. > Thanks. Correct; while this syntax would compile, it would result in the value assigned to the property being ignored, and then the other heavyTask() value assigned to it, but that still wouldn't ensure it was available the first time you called `get`. That's probably not what anyone wants. It looks like you answered your own question on the interface point, so I'll leave that be. --Larry Garfield