I cannot speak to the implementation details. From a design perspective,
I am tentatively positive on operator overloading, with separate method for
each operator, BUT, the big question for me is the rules around type
compatibility.Can you only compare 2 of the same type? What about subclasses? Can that
differ if a subclass overrides that method? What happens to commutativity
then? Can you compare based on an interface?
I do not think the types should be restricted at all. For a numeric-like
object like an money value, adding an scalar like an integer or float is
quite useful (e.g. $a + 2.5), for things like vectors this would be not
resolvable (you can only add between vectors, while multiplication with an
scalar is valid). In my opinion the object should determine the operands
types and decide if it can handle it or not (and then throwing an
exception). As long as PHP does not allow function overloading with
different types (like C# does), I see no other possibility except deciding
on runtime if the type is supported.
For sub classes this is more difficult. I guess in the most use cases
defining a good operation handler in a sub class is sufficient, so maybe the
operation handlers could be required to be final. Another possibility would
be to let the user handle this situation completely, even if this could lead
to undesired behavior.
In my opinion the most elegant solution, would be if an operator handler
could somehow signal that it does not support the type passed (maybe by
returning null, or throwing a special OperandTypeNotSupportedException), so
that PHP can try to call the operation handler on the right operand (that is
one of the reasons I like passing both operands to a static handler).
Also, I want to reiterate: Any of these operations MUST be designed to
return a new value, never modify in place. These operators only make sense
on value objects, not service objects, and value objects should be
immutable.
I agree with that. The best solution here would be an integrated support
for immutable value objects (which could become quite complex on its own),
but I wonder if it would be sufficient if copies of the objects instances
are passed to the operator handler. The user could then change the scalar
properties of the object like he wants, without changing the operands
objects.
Frankly I'd avoid bitwise operators entirely for now. I'm not even sure
how you'd use those...
They could be maybe useful for mathematical objects, that define more than
the four basic arithmetic operators (like the cross vs dot on vectors, or
tensor product) or four things like length-safe binary number objects. Also
I would say they are not used very often in normal PHP, so redefining them
as custom operators would be less confusing, then using other operators for
that.
But I can understand everyone who dislike the idea of overloading them, for
the reason that their used could become too confusing. If there is to be an
voting on an RFC, maybe it should be split into a voting on the arithmetic
operators/concatenation and a voting on the bitwise operators.
Greetings,
Jan Böhmer