Re: [VOTE] User Defined Operator Overloads
| From: | Guilliam Xavier | Date: | Mon, 10 Jan 2022 17:48:55 +0000 |
| Subject: | Re: [VOTE] User Defined Operator Overloads | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-116855@lists.php.net to get a copy of this message | ||
Hi Jordan,
Many thanks for all your replies. But did you miss Côme's mail (maybe
because you weren't direct recipient)? Anyway, here it is again:
On Tue, Jan 4, 2022 at 10:02 AM Côme Chilliet <come@chilliet.eu> wrote:
> Hello,
>
> From the RFC:
>
> > If the left operand produces a TypeError due to the parameter types
> listed in the implementation, the operation is not retried with the right
> operand and the error is instead returned immediately. This is to help
> developers encounter errors in their program logic as early as possible.
>
> This feels wrong if I understand correctly.
>
> Let’s say I create a class A and I want to add support for "2 / new A()",
> which by default does not work.
>
> I can do
> class A
> {
> operator /(int $other, OperandPosition $operandPos): mixed
> {
> return "example";
> }
> }
>
> Now someone wants to build on my work, and add a class B that supports
> "new A() / new B()".
>
> class B
> {
> operator /(A $other, OperandPosition $operandPos): mixed
> {
> return "example";
> }
> }
>
> This will not work because it will first try A->{'/'}(B) that throws a
> TypeError? So it means what I was able to do for floats, cannot be done for
> my new classes afterwards? This is inconsistent I think. It also means it
> is not possible to extend any existing class with operators interacting
> with a new class, meaning you can only use operators among classes aware of
> each other, most likely from the same package/library.
>
> Also, this was stated already I think but I did not see an answer, from
> RFC example:
> > class Matrix {
> > public function __construct(readonly public array $value) {}
> >
> > public operator *(Matrix $other, OperandPosition $operandPos): Number
> > {
> > if ($operandPos == OperandPosition::LeftSide) {
> > // Count of my columns needs to match
> > // count of $other rows
> > } else {
> > // Count of my rows needs to match
> > // count of $other columns
> > }
> > }
> > }
>
> The second branch of the if is dead code, as $matrix1 * $matrix2 will
> always call $matrix1->{'*'}($matrix2, LeftSide) and never the other way
> around.
> This means that $operandPos is useless in all cases where operators are
> only typed againts the same type, and points to this design solution being
> wrong.
>
> There is «Why not interfaces?» in the FAQ, does that mean that operators
> cannot be added in interfaces? This is not stated clearly in the RFC.
>
> Also, it is not clear if operator overload will affect comparison
> operations used in core functions such as in_array, sort and so on.
> Does implementing operator == allows using in_array to find an object in
> an array?
> Which of these internal functions use == and which use ===, which is not
> overloadable?
> Does implementing operator <=> allows sorting of arrays containing my
> objects?
>
> Côme
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>
I too would be interested in your answers to those.
Best regards,
--
Guilliam Xavier