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

Reply via email to