Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:122513 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 CF5D81AD8F6 for ; Tue, 27 Feb 2024 10:01:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1709028091; bh=0W0Su+o1aRZGH/phpo3P0D2LAfPQRxsh3n6EN/q4E6E=; h=Date:Subject:To:References:From:In-Reply-To:From; b=CxjgorlDSsvQlYz821ZaK58Ee/MMQN0ubz/mQEghWmFArzjK5JF9x3qrDFP3Q1BUw /Gxn46q1+doUT/jA5GOUCq5ZwAPz7aGcdzG1dtafOp4gQp44uB/ovM1gszMz69sL96 /1exJlOEUfW9kaHpBxUMQ0DzkWVpNoOPEjyuxOa0QqhwKsxNoo40y/uK+2qTbe6cDe 3eayY95prPpk5YsT4bUpAg7ASgYg9jvMQIFSo4VBRMVbVjvCXrG4Q1rR/2RvRg3mJA U/v1X1g9L9Gbc6wsKKc5s0VTMv0eVFaNvYRH39ZRtWgbNmwok+pQyTmfiwquwo5WP7 A7ijoaG6OPVqA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 55942180071 for ; Tue, 27 Feb 2024 10:01:29 +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,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from mta3.mail.genkgo.net (mta3.mail.genkgo.net [2.58.165.21]) (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 ; Tue, 27 Feb 2024 02:01:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=genkgo.nl; s=ge-k1; h=Content-Transfer-Encoding:Content-Type:In-Reply-To:From:References :To:Subject:MIME-Version:Date:Message-ID:Sender:Reply-To:Cc:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=6HJED4gjtyZ5fGsE3e2wWvSBvQaid+zMQPLXC8zlJW4=; b=C+2wiNyyHDhxPOyx7TM3cQ8aL0 90GU98hHO/LHT++oa0COpREuRkyPmkXuYmqwqQTSNZYfeHg+rA7pcAKWhpi/Ql/6V9U+wjtzA7uRs 8bXLA0rtGwgfGoW+qIfzhokMCE4xqIqI4Ax98FTfBhTyw3yxOw13eJ0r6GW9B8ZsEZCCPjKbiepIg 7IVFE2Wb9DKU0mXuMWdIEWKplfypf+bdDYgJoj+YxJsMW4UI/2jG7MiT+d0r17EkfOv/CydYYclGn 66w+fKuhozxAYxZa9XOm1te4KYJq+awzvDwvjexNDg/yxh22JGPDCkx53jMfrw7MWm1EFYVnej13w uBCFhGrw==; Received: from [185.184.111.39] (helo=[192.168.16.249]) by mta3.mail.genkgo.net with esmtpsa (TLS1.3) tls TLS_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1reuH0-000Idh-0T; Tue, 27 Feb 2024 10:01:18 +0000 Message-ID: Date: Tue, 27 Feb 2024 11:01:17 +0100 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-US, nl-NL To: "Rowan Tommins [IMSoP]" , internals@lists.php.net References: <790b5b4e-f51b-4050-a12a-5fa903d0568f@app.fastmail.com> <52C6F501-8E23-42D7-8541-88A22AD79375@koalephant.com> <36e90d8d-d275-4ce9-9dd9-1e2422c6d3a9@app.fastmail.com> <2fdf1933-b51c-40cc-8d02-31899b96c71c@genkgo.nl> <95e93cb9-3ab0-4cf3-8ec5-83e74c9dd607@genkgo.nl> <876aff9f-3eae-4d2d-8e3f-30dfbbeed49c@rwec.co.uk> <963f5cc5-cdb1-4384-b519-5cb15640654e@genkgo.nl> <58B82A81-8A89-4F17-B982-7FC36404032E@rwec.co.uk> In-Reply-To: <58B82A81-8A89-4F17-B982-7FC36404032E@rwec.co.uk> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit From: f.bosch@genkgo.nl (Frederik Bosch) On 27-02-2024 10:49, Rowan Tommins [IMSoP] wrote: > On 26 February 2024 23:11:16 GMT, Frederik Bosch > wrote: > > >And what happens in the following situation, how are multiple get > calls working together? > > > >public string $fullName { > >    get => $this->first . ' ' . $this->last; // is this accessing the > backed value, or is it accessing via get > >    set($value) => $this->fullName = $value; > >} > > > >public string $first { > >    get => explode(' ', $this->fullName)[0], // is this accessing the > backed value, or is it accessing via get > >    set($value) => $value; > >} > > I don't think it's *that* confusing - the rule is not "hooks vs > methods", it's "special access inside the property's own hook". But as > I say, I'm coming around to the idea that using a different name for > that "backing field" / "raw value" might be sensible. > > > >> What would happen if a setter contained both "return 42;" and > "return;"? The latter is explicitly allowed in "void" functions, but > is also allowed in a non-void function as meaning "return null;" > >return 42; // returns (int)42 > >return; // early return, void, same as no return > >return null; // returns null > > I'm not sure if you misunderstood my question, or just the context of > why I asked it. I'm talking about a hook like this: > > set($value) { if ($value) { return 42; } else { return; } } > > Currently, the only definition of "void" in the language is that a > void function must not contain an explicit return value. We could turn > that check around, and deduce that a certain hook is void. This hook > would not pass that check, so we would compile it to have an > assignment, and the false case would assign null to the property. To > avoid that, we would need some additional analysis to prove that in > all possible paths, a return statement with a value is reached. > > The alternative would be to run the code, and somehow observe that it > "returned void". But "void" isn't a value we can represent at > run-time; we would need to set the return value to some special value > just for this specific case. We would have to turn that on just for > hook bodies, as returning it from normal functions would be a huge BC > break, and also not very useful - with union types, there would be > plenty of better options for a function to indicate a return value > that needs special handling. > > > > >$generator = setCall($class, 'first', $value); > >foreach ($generator as $value) { > >   writeProperty($class, 'first', $value); > >} > >if ($generator->hasReturn()) { > >writeProperty($class, 'first', $generator->getReturn()); > >} > > > That's already an order of magnitude more complicated than "the return > value is used on the right-hand side of an assignment", and it's > missing at least one case: set($value) { return $value; } will not > compile to a generator, so needs to skip and assign the value directly. > > By "magic", what I meant was "hidden logic underneath that makes it > work". Assign-by-return has a small amount of magic - you can express > it in half a line of code; assign-by-yield has much more magic - a > whole bunch of loops and conditionals to operate your coroutine. > > > > > The yield is much more intuitive than magic fields > > I think we'll just have to differ in opinion on that one. Maybe you're > just more used to working with coroutines than I am. > > Note that yield also doesn't solve how to read the current backing > value in a get hook (or a set hook that wants to compare before and > after), so we still need some way to refer to it. > > Regards, > Rowan Tommins > [IMSoP] Hi Rowan, Our discussion sums up the pros and cons. Whether yield is complicated/confusing or not, is maybe personal. The same applies to getting $this->prop resulting in different calls. Larry has removed $field from the RFC completely now, while I think it was a sensible approach to read the current backing value. I think I have laid out another alternative to writing with the yield/return suggestion. It's up to the authors of the RFC to do something with it, or not. Thanks for taking the suggestion seriously. Regards, Frederik