On Mon, Jan 4, 2016 at 1:37 AM, Sara Golemon <poll...@php.net> wrote:
> This is a separate proposal from the userspace operator overloading I > put up for Patricio yesterday and aims to fix what I see as a bug in > our operator overloading implementation (though some may disagree). > > It specifically only seeks to differentiate const operations which > produce a new value from mutations which alter an existing overloaded > object. > > https://wiki.php.net/rfc/assignment-overloading I'd like to provide some context as to why the current implementation works as it does. The basic idea is that, prior to the introduction of operator overloading, primitive operators only worked on types with by-value semantics (or rather: only returned types with by-value semantics). For such types it holds, that $a op= $b is equivalent to $a = $a op $b. We actually transform the latter operation into the former in pass3 optimization. Operator overloading was implemented in such a way that this invariant still holds. To illustrate why keeping this invariant *might* be beneficial, consider this example from the GMP overloading RFC: function powm($base, $exponent, $modulus) { $result = 1; while ($exponent > 0) { if ($exponent % 2 == 1) { $result = $result * $base % $modulus; $exponent--; } $exponent /= 2; $base = ($base * $base) % $modulus; } return $result; } The example appeared in the context that, with operator overloading supported, the above function could be transparently used either with ordinary integers or with overloaded GMP objects. However this would not be true if compound assignment operators would modify the object instead of creating a new one. In this case the argument passed to $exponent would always be GMP(0) after the function finishes running. I expect that this would be somewhat unexpected. Basically the lack of distinction between assign-op and op-and-assign enforces that the object behaves as an immutable value object (at least as far as overloading is concerned). Nikita