Apologies. I think I saw this, but then was distracted by other matters and
lost track of it.


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.
>>
>
This is something covered by the future scope Polymorphic Handler
Resolution. Essentially, to resolve this issue the types need to be checked
for inheritance during the opline evaluation. That's something that would
be a fairly easy to do in a very unperformant way, so I wanted to do that
as a follow-up RFC in order to put real effort into making it something
that would slow such oplines down too much.


> 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.
>>
>
Yes, for implementations only hinted against themselves, this would be
true. The main other strategy would be to use a static implementation that
takes both operands. This has a few downsides:

1. While it is still possible to access private and protected properties in
such a case, doing so is awkward and not at all intuitive.
2. The boiler-plate code for checking types in order to figure out which
side (left or right) is the called instance would be required for nearly
every implementation. So some code was saved for some situations, but more
code was added for all situations.
3. There is no situation in which these will *actually* be called
statically. They are *only* called when an object instance exists, because
an object instance is required in order to use with the operands.

Such static implementations would only reduce code (in my opinion) if this
was combined with method overloading, but that's a totally separate bag of
controversy and difficulty.


> 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.
>>
>
No, these can be added to interfaces and abstract classes and final
classes. They can even be added to enums actually. What that part is saying
is that this RFC doesn't provide interfaces such as 'Stringable' for each
of the operators.


> 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?
>>
>
The in_array() function unfortunately uses its own comparison internally.
This is something that I would want to add as part of the implementation
step, yes, but it's not currently in the PR that's linked.


> Which of these internal functions use == and which use ===, which is not
>> overloadable?
>>
>
Internally, these functions use neither, because they don't generate an
opcode. They do the comparison on the ZVALs themselves. So each of them
needs to be special cased.


> Does implementing operator <=> allows sorting of arrays containing my
>> objects?
>>
>
The same as above applies. It doesn't actually generate an opcode, so it
needs to be special cased.

The good news is that this special casing would actually be pretty
straightforward, since I also wrote helpers for things such as extensions
to more easily handle these sorts of things.

Jordan

Reply via email to