Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:92076 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 93839 invoked from network); 3 Apr 2016 11:15:16 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 3 Apr 2016 11:15:16 -0000 Authentication-Results: pb1.pair.com header.from=bjorn.x.larsson@telia.com; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=bjorn.x.larsson@telia.com; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain telia.com from 81.236.60.155 cause and error) X-PHP-List-Original-Sender: bjorn.x.larsson@telia.com X-Host-Fingerprint: 81.236.60.155 v-smtpout2.han.skanova.net Received: from [81.236.60.155] ([81.236.60.155:33533] helo=v-smtpout2.han.skanova.net) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 74/B7-29546-C3BF0075 for ; Sun, 03 Apr 2016 07:15:09 -0400 Received: from [192.168.7.7] ([195.198.188.252]) by cmsmtp with SMTP id mfzlavfXuGabYmfzlaVzEJ; Sun, 03 Apr 2016 13:15:05 +0200 To: Midori Kocak References: <9399032E-5BAA-4ABF-81AD-13716790D8DB@gmail.com> <63C58928-255D-41A1-9D6E-4773CF9DB356@gmail.com> Cc: Nikita Popov , PHP internals Message-ID: <5700FB39.2030303@telia.com> Date: Sun, 3 Apr 2016 13:15:05 +0200 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.7.1 MIME-Version: 1.0 In-Reply-To: <63C58928-255D-41A1-9D6E-4773CF9DB356@gmail.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-CMAE-Envelope: MS4wfD0j1cov18ZK8t/TwwB3SoWpIE4//vjmF3yEGg/rxMB2nKrCsb3X5yJJbi3+tWWRUR0MbghJrEWpIX+aI/fuvv8Z+SPiTjMX9V7M+uD+TN3lnxhVNZzm KcZQXeEDweKrQxNRVw7r3rK/HSPAx0j9V/VTPulqVN9BOCfwJoz8Jq1Bcd5s4PlogT42ongCx87ByN9cpUtOTUlVvcp9tazUBgJaMFvcHGx/DJ5u5lc89GKV nVFhICrv5F2dXkmeFA+5Xw== Subject: Re: [PHP-DEV] Tests for null coalescing assignment operator From: bjorn.x.larsson@telia.com (=?UTF-8?Q?Bj=c3=b6rn_Larsson?=) Hi Midori, Will you update the RFC also? Even if it's not the normal way of doing things, one should keep in mind that RFC's are often listed as references in books about PHP, being the first piece of documentation. Two such examples are: - https://daveyshafik.com/archives/book/upgrading-to-php-7 # In Appendix B - http://www.php7book.com # At the end of every chapter Regards //Björn Larsson PS Maybe best to finish implementation and tests first. Den 2016-04-03 kl. 03:17, skrev Midori Kocak: > Dear All, > > Based on the concerns I wrote some tests. Can you check those and give feedback? Also, in ruby, $a ||= $b, the implementation is not equal to $a = $a || $b, but is equal to $a || $a = $b; I am a little bit confused, I am not entirely sure, but I guess this approach would solve our problems. > > https://gist.github.com/midorikocak/abc9fd9b6ca30359d201bc859edba9ee > > We can use these examples as the part of the new documentation and as a guideline for implementation tests. Can you add also any extreme cases that should raise errors to my test? > > Yours, > Midori > >> On 25 Mar 2016, at 13:42, Nikita Popov wrote: >> >> On Fri, Mar 25, 2016 at 11:59 AM, Midori Kocak > wrote: >> Hi Everyone, >> >> I think it's better idea to combine those two assignment operator RFC’s. So I am going to close the current one and open ??= with ?:= >> What do you think? And we have to find better names. >> >> Wishes, >> Midori Kocak >> >> I'd prefer to keep them separate, or at least keep their votes separate. The ??= operator vote is currently unanimous at 24:0, while the ?:= vote was closed at something like 9:2, so there clearly are differences of opinion regarding these two operators. >> >> I'll use this chance for some comments on the proposal. I can see the general usefulness of ??=, but right now the RFC is severely underspecified and I'm uncomfortable voting on it in it's current form as so much will depend on the final implementation. So, what do I mean by underspecified? >> >> The only statement the RFC essentially makes is that $a ??= $b will be the same as $a = $a ?? $b, for variable-expression $a and expression $b. This statement, while a good high-level illustration, does not explain the exact behavior of this operator. >> >> For example, consider the expression $a[print 'X'] ??= $b. A simple desugaring into $a[print 'X'] = $a[print 'X'] ?? $b will result in 'X' being printed twice. However, this is not how all other existing compound assignment operators behave: They will print X only once, as the LHS is only evaluated once. I assume that ??= would behave the same way. >> >> However, with ??= the problem becomes more complicated. Let us assume that $a is an ArrayAccess object and consider the expression $a[0] ??= $b. Let us further assume that $x = $a->offsetGet(0) is non-null. Will $a[0] ??= $b result in a call to $a->offsetSet(0, $x)? This is what would normally happen with a compound assignment operator and what would be implied by the desugaring $a[0] = $a[0] ?? $b. However this assignment is not really necessary, as we're just reassigning the same value. So, does the call happen or not? Is the proper desugaring maybe if (!isset($a[0])) $a[0] = $b? >> >> Let us now assume that $a is a recursive ArrayAccess object with by-reference offsetGet() and consider the expression $a[0][1] ??= expr. For a normal compound assignment operator, this would issue the call sequence >> >> $b = expr; >> $x =& $a->offsetGet(0); >> $y = $x->offsetGet(1); >> $y OP= $b; >> $x->offsetSet(1, $y); >> >> Note that we only issue one offsetSet() at the end. We do not refetch $x via $a->offsetGet(0). How would the same work with the ??= operator? As the RHS is evaluated lazily, it is my opinion that only performing the offsetSet() call without refetching $x beforehand would violate PHP's indirection memory model. Additionally as ??= has to fetch offsets in BP_VAR_IS mode, we likely wouldn't be able to write them without refetching anymore. >> >> So, what would be the desugared call sequence for $a[0][1] ??= expr? Something like this? >> >> if (!$a->offsetHas(0)) { >> goto assign; >> } >> $x = $a->offsetGet(0); >> if (x === null) { >> goto assign; >> } >> if (!$x->offsetHas(0)) { >> goto assign; >> } >> $y = $x->offsetGet(0); >> if ($y === null) { >> goto assign; >> } >> goto done; >> assign: >> $b = expr; >> $x =& $a->offsetGet(0); >> $x->offsetSet(1, $b); >> done: >> >> That would be some first thoughts on the issue, though I'm sure there are more subtleties involved. I'd like to see the exact behavior of ??= (and ?:=) specified. >> >> I'm also pretty sure that writing a patch for this will not be entirely easy. The combination of execute-once LHS side-effects and lazy RHS execution does not translate well to PHP's VM constraints. >> >> Regards, >> Nikita >