Well, for me, the latter would masquerade as a trivial expression seen thousands of times, and which now may or may not have unexpected behavior. Every instance of something like a + b must now carry the slight extra cognitive load of potentially having a sort of "optional type annotation" in one's mind. Usually normal, but might not be.
The former is at least potentially self-documenting. And even if it's a badly named function, at least you know it's a special function, and you know you'll have to go look up its behavior.
Done right, it should masquerade as a trivial expression seen thousands of times. There's a real advantage in being able to have user-defined types that have the same interface as native types.
I want the ability to do 'a == b' regardless of whether it's a built-in or user-defined type. That's abstraction.
That's a good point, and I agree. The situation I'm thinking of is something like, say, you have an object or type called a "Tire". It has width, diameter, weight, price, tread depth, compound, etc. As you work with Tires in your program, you frequently end up having to compare their widths. So you overload the ">" operator to return true if one Tire has greater width than another. Your code ends up festooned with these comparisons.
Flash forward one year, you're long gone, and new developers on your team are left wondering which aspect of a Tire is used in comparisons with ">". Everything works, but it's easy to see how the ambiguity could lead to subtle submarine bugs; incorrect developer assumptions about the behavior of ">" may produce mostly -- coincidentally -- working code.
The former is at least potentially self-documenting. And even if it's a badly named function, at least you know it's a special function, and you know you'll have to go look up its behavior.
[Edit: Clarity]