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....@gmail.com> wrote: > > On Fri, Mar 25, 2016 at 11:59 AM, Midori Kocak <mtko...@gmail.com > <mailto:mtko...@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