Re: [RFC] Differentiate op from assign-op in operator overloading

From: Date: Thu, 07 Jan 2016 14:04:04 +0000
Subject: Re: [RFC] Differentiate op from assign-op in operator overloading
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-90250@lists.php.net to get a copy of this message
> Am 04.01.2016 um 01:37 schrieb Sara Golemon <pollita@php.net>: > > 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 Hey, I think this RFC is attempting to solve the wrong problem... Let me explain why: a) What do you do in cases like: $a = gmp_init(125); $b = $a; $b += 10; $a and $b hold the same object reference, so we'd need to do an implicit clone (separation) before passing it to the assign ops, or we are going to break the immutable-value-object assumption. That risks to be be problematic. As long as it is internal, we could deal with it internally. When we leak operator overloading to userland, not so much. b) The main goal is to not needing copies when unnecessary. This could then as well apply to simple cases like: $a = gmp_init(125); $b = $a + 10; /* $a isn't used anymore later */ or just explicit: $a = $a + 10; # instead of $a += 10; // under some circumstances that may be more readable... With opcache analysis we'll probably be able to determine when we won't use the symtable directly (via varvars, get_defined_variables() etc.), where this will present another valuable optimization possibly. At that point you would possibly rather explicitly check: "are we at the end of a variable range (if CV) and the refcount of the object == 1?" and eventually forward that information to userland as optional third param. Which would give you the most optimization possible; and even applicable in the example Nikita provided with sets. Example: function or($a, $b, $mutable = OVERLOAD::NO_REUSE) { switch ($mutable) { case OVERLOAD::REUSE_OP1_OP2: case OVERLOAD::REUSE_OP1: $a->add($b); return $a; case OVERLOAD::REUSE_OP2: $b->add($a); return $b; default: $a = clone $a; $a->add($b); return $a; } } Bob

« previous php.internals (#90250) next »