Re: Tests for null coalescing assignment operator

From: Date: Sun, 03 Apr 2016 14:41:36 +0000
Subject: Re: Tests for null coalescing assignment operator
References: 1 2 3 4  Groups: php.internals 
Request: Send a blank email to internals+get-92077@lists.php.net to get a copy of this message
Yes, I think I should too. But still no feedbacks :( > On 03 Apr 2016, at 13:15, Björn Larsson <bjorn.x.larsson@telia.com> wrote: > > 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 >> <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 <nikita.ppv@gmail.com> wrote: >>> >>> On Fri, Mar 25, 2016 at 11:59 AM, Midori Kocak <mtkocak@gmail.com >>> <mailto:mtkocak@gmail.com>> 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 >> >

« previous php.internals (#92077) next »