Re: [VOTE] Userspace operator overloading

From: Date: Thu, 09 Apr 2020 15:05:28 +0000
Subject: Re: [VOTE] Userspace operator overloading
References: 1 2 3 4 5 6 7 8 9 10 11  Groups: php.internals 
Request: Send a blank email to internals+get-109584@lists.php.net to get a copy of this message
On Thu, 9 Apr 2020 at 13:18 (and subsequent correction), Dan Ackroyd < Danack@basereality.com> wrote: > > $a = new A; > > $b = new B; > > var_dump($b + $a); # calls B::__add($b, $a); OK > > var_dump($a + $b); # calls A::__add($a, $b), which is a TypeError > > > ... that code does have a TypeError. It is > calling '__add' and passing a parameter to the method that the code > can't handle. > > It appears to be the same error case as: > > ``` > class A { > public function add(A $rhs) {...} > } > > class B { > public function add(A|B $rhs) {...} > } > > $a = new A; > $b = new B; > > $b->add($a); // Ok > $a->add($b); // TypeError > ``` > As with so much else on this topic, it depends how you think about operator overloading - and I think that's why it's so hard to agree on an implementation. It seems that you're picturing the overloaded + as like a normal method but with special syntax, so that $a + $b means the same as $a->add($b) and only that. In that interpretation, it's perfectly reasonable to have the operation succeed or fail based only on the left-hand operand, because that's how we're used to method dispatch working. But if you look at how "normal" operators work, it's far less obvious that the order of operands should play any role in that decision. For instance, when mixing float and int, the result is a float if *either* of the operands is a float: var_dump(1 + 1); # int(2) var_dump(1 + 1.0); # float(2) var_dump(1.0 + 1); # float(2) var_dump(1.0 + 1.0); # float(2) Substitute 1 for $a and 1.0 for $b, and you're back to the example I originally wrote. Note that this is true even for non-commutative operators like exponentiation: var_dump(2 ** 3); # int(8) var_dump(2 ** 3.0); # float(8) var_dump(2.0 ** 3); # float(8) var_dump(2.0 ** 3.0); # float(8) My impression is what people consider "good" use of operator overloading is much closer to "make things act like built in numerics" than "make operators with fancy syntax", so some form of symmetry is necessary I think. Regards, -- Rowan Tommins [IMSoP]

« previous php.internals (#109584) next »