Hi Jordan, Thanks for the RFC. I have a couple questions:
Suppose I have classes Foo and Bar, and I want to support the following operations: - Foo * Bar (returns Foo) - Bar * Foo (returns Foo) If I understand correctly, there are three possible ways I could implement this: a) Implement the * operator in Foo, accepting a Foo|Bar, and use the OperandPosition to determine if I am doing Foo * Bar or Bar * Foo and implement the necessary logic accordingly. b) Implement the * operator in Bar, accepting a Foo|Bar, and use the OperandPosition to determine if I am doing Foo * Bar or Bar * Foo and implement the necessary logic accordingly. c) Implement the * operator in Foo, accepting a Bar (handles Foo * Bar side); Implement the * operator in Bar, accepting a Foo (handles Bar * Foo side) Is this understanding correct? If so, which is the preferred approach and why? If not, can you clarify the best way to accomplish this? Next, suppose I also want to support int * Foo (returns int). To do this, I must implement * in Foo, which would look like one of the following (depending on which approach above) public operator *(Foo|int $other, OperandPos $pos): Foo|int { ... } public operator *(Foo|Bar|int $other, OperandPos $pos): Foo|int { ... } Now, suppose I have an operation like `42 * $foo`, which as described above, should return int. It seems it is not possible to enforce this via typing, is that correct? i.e. every time I use this, I am forced to do: $result = 42 * $foo; if (is_int($result)) { // can't just assume it's an int because * returns Foo|int } Thanks, --Matt