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