On Tue, Sep 17, 2024 at 6:49 PM Larry Garfield <la...@garfieldtech.com> wrote:
> On Tue, Sep 17, 2024, at 3:14 PM, Jordan LeDoux wrote: > > >> I think it's absolutely possible - and desirable - to choose a > philosophical position on that spectrum, and use it to drive design > decisions. The choice of "__add" vs "operator+" is one such decision. > >> > > > > Ah, I see. I suppose I never really entertained an idea like this > > because in my mind it can't even handle non-trivial math, let alone the > > sorts of things that people might want to use overloads for. Once you > > get past arithmetic with real numbers into almost any other kind of > > math, which operators are meaningful, and what they mean exactly, > > begins to depend a lot on context. This is why I felt like even if we > > were limiting the use cases to math projects, things like commutativity > > should not necessarily be enforced. > > > > The line `$a + $b` and `$b + $a` are SUPPOSED to give different results > > for certain types of math objects, for instance. The line `$a - $b` and > > `$b - $a` more obviously give different results to most people, because > > subtraction is not commutative even for real numbers. > > > > My personal opinion is that the RFC should not assume the overloads are > > used in a particular domain (like real number arithmetic), and thus > > should not attempt to enforce these kinds of behaviors. But, opinions > > like this are actually what I was hoping to receive from this thread. > > This could be the way forward that voters are more interested in, even > > if it wouldn't be my own first preference as it will be highly limiting > > to the applicable domains. > > I'm not sure where exactly in this thread to put this, so I'm putting it > here... > > Rowan makes an interesting point regarding operators vs operations. In > particular, the way the <=> logic is defined, it is defining an operation: > comparison. Using it for anything other than ordering comparison is simply > not viable, nor useful. It's defining a custom implementation if a > specific pre-existing action. > > For all the other operators, the logic seems to be defined for an > operator, the behavior of which is "whatever makes sense in your use case, > idk." That is, to use Rowan's distinction, a philosophically different > approach. Not a bad one, necessarily. In fact, I think it's a very good > one. > > But, as they are different, perhaps that suggests that comparison should > instead not be implemented as an operator overload per se, but as a named > magic method. The existing logic for it is, I think, fine, but it's a fair > criticism that you're not defining "what happens for a method-ish named > <=>", you're defining "how do objects compare." So I think it would make > sense to replace the <=> override with a `__compare(mixed $other): int`, > which any class could implement to opt-in to ordering comparisons, and thus > work with <, >, ==, <=>, etc. (And, importantly, still keep the "specify > the type(s) you want to be able to compare against" logic, already defined.) > > A similar argument could probably be made for ==, though I've not fully > thought through if I agree or not. Again, I think the previously defined > logic is fine. It would be just changing the spelling from `operator > ==(mixed $other): bool` to `public function __equals(mixed $other): bool`. > But that again better communicates that it is a core language behavior that > is being overridden, rather than an arbitrarily defined > symbol-function-thing with domain-specific meaning. > > There was an RFC for a Comparable interface back in the stone age (2010), > but it looks like it never went to a vote: > https://wiki.php.net/rfc/comparable > > Arguably, this would then make more sense as a stand-alone RFC that > happens to reuse a lot of the existing code and logic defined for operator > overloads, which are all still just as valid. > > That does not apply to the arithmetic, bitwise, or logic operators. > Overriding + or / for a specific domain is not the same, as you're not > hooking into engine behavior the way <=> or == are. For those, I'd prefer > to stick to the current/previous implementation, with the `operator` > keyword, for reasons I explained before. > > Jordan, does that distinction make sense to you? > > --Larry Garfield > Yes, I certainly understand the distinction. The RFC does not treat all operators equally. For many of them, the only opinion it holds is whether or not the operator is unary or binary, which is something enforced by the compiler anyway. But for comparisons, the RFC went out of its way to ensure that the overloads cannot repurpose any comparisons for non-comparison, non-ordering tasks usefully (as far as return value goes). In that sense, yes, I see how that feels more like an operation instead of an operator. The only hesitation I would have about that is the clunky/ugly feeling I get of having some of them be symbols and some of them be names for a reason that will be totally inscrutable to 95% of developers and just be "one of those PHP quirks". In principle though, I do get what you're saying here. Jordan