Re: [Pre-RFC Discussion] User Defined Operator Overloads (again)
| From: | Alexandru Pătrănescu | Date: | Wed, 18 Sep 2024 15:46:51 +0000 |
| Subject: | Re: [Pre-RFC Discussion] User Defined Operator Overloads (again) | ||
| References: | 1 2 3 4 5 6 7 8 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-125623@lists.php.net to get a copy of this message | ||
On Wed, Sep 18, 2024 at 6:11 PM Rowan Tommins [IMSoP] <imsop.php@rwec.co.uk>
wrote:
> On Wed, 18 Sep 2024, at 15:19, Christoph M. Becker wrote:
> >> Maybe it would be "useful enough" to just restrict to left-hand side:
> >
> > In my opinion, this is the only reasonable way to implement operator
> > overloads in PHP. It is easy to understand, and what can easily be
> > understood is easy to explain, document, and to reason about. I do not
> > understand why we're talking about commutative operations; even the
> > inconspicuous plus operator is not commutative in PHP
> > (https://3v4l.org/nQcL5).
>
> There are really three different things we shouldn't confuse:
>
> 1) Commutativity of the operation, as in $a + $b and $b + $a having the
> same result. As you say, this is a non-goal; we already have examples of
> non-commutative operators in PHP, and there are plenty more that have been
> given.
>
> 2) Commutativity of the *resolution*. This is slightly subtler: if $a and
> $b both have implementations of the operator, should $a + $b and $b + $a
> call the same implementation? We can say "no", but it may be surprising to
> some users that if $b is a sub-class of $a, its version of + isn't used by
> preference.
>
> 3) Resolution when *only one side has an implementation*. For instance,
> how do you define an overload for 1 / $object? Or for (new DateTime) + (new
> MySpecialDateOffset)? It's possible to work around this if the custom class
> has to be on the left, but probably not very intuitive.
>
> It's also worth considering that the *resolution* of PHP's operators
> aren't currently determined by their left-hand side, e.g. int + float and
> float + int both return a float, which certainly feels like "preferring the
> float implementation regardless of order", even if PHP doesn't technically
> implement it that way.
>
>
>
How about doing it like in Python, where there is
__add__ and __radd__?
And the engine could call $op1->add($op2) if $op1 is an object and add()
is implemented, or otherwise call $op2->rightAdd($op1) if $op2 is an object
and rightAdd() is implemented, or otherwise fail with an error.
We could have (distinct) interfaces for both add() and rightAdd().
Or use magic methods like __add() and __rightAdd() to allow stricter
types instead of mixed on the other operand. I think there is no extra
complexity for the engine by using magic methods or interfaces.
--
Alex