operator overloading outside the type

sfp sfp at hush.ai
Fri Mar 28 17:28:10 UTC 2025


On Friday, 28 March 2025 at 08:57:39 UTC, Jonathan M Davis wrote:

Since I'm still fairly fresh to D, I want to try to understand 
which parts of what you wrote are your carefully considered 
opinion and which are hard fact, because it actually isn't very 
clear to me...

> Overloaded operators are not normal functions, and they're not 
> used like normal functions.

Is there any way that they aren't normal functions apart from the 
different, unique syntax?

> Their syntax is fundamentally different, and if there were ever 
> an import conflict because of it, you can't resolve it.

You get to this in the next sentence, but you can of course just 
do `module.opWhatever`.

> At least with UFCS, you can choose to call the function 
> normally instead so that you can give the full import path, but 
> if you do that with an overloaded operator, you might as well 
> not be using an overloaded operator.

I think this is really pretty debatable. Personally, I would very 
gladly accept this limitation, and don't view it as onerous.

> Overloaded operators already have a number of restrictions on 
> them to try to enforce that they behave in a sensible way and 
> aren't abused. They're special and IMHO should be treated as 
> such.

It would be really helpful to have a list of these restrictions, 
other than the main one being discussed (that they must be 
defined as member functions). I'm not aware of any others.

> I don't want to live in a world where operators start behaving 
> differently based on what was or wasn't imported.

C++ is that world. C++ has a lot of faults but this isn't one of 
them. I think the situation in D is actually better considering 
the manner in which modules and overloads interact. More 
restrictive but much more understandable, predictable, and 
debuggable. Less scary magic.

> They're supposed to be a core part of the type, not just a 
> function that accepts the type.

Why? I hear this claimed a lot but because I completely disagree 
with this point it's hard for me to understand what its basis is.

> Imagine the weird side effects that you'd get and hard to track 
> down bugs if something like opCast were overloaded externally.

Sounds scary, but my imagination isn't good enough. Can you 
please provide an example?

> And some operators clearly can't be overloaded externally - 
> such as opEquals - because the compiler generates the code for 
> them if they're not there. Others simply couldn't work in any 
> sane fashion if they were external (e.g. opDispatch).

Are these hard technical restrictions?

> IMHO, if you want to add operators to a type, then wrap it. It 
> doesn't require making the language rules any more weird or 
> confusing, and it's straightforward.

It imposes a large burden on the programmer... One of the selling 
points of D is that it's high leverage (get a lot done while 
writing few lines of code). Enabling free operator definitions is 
in line with this feature. Restricting it is "straightforward" 
but is more in line with a language like Go: bondage and 
discipline in the name of keeping things regular and predictable, 
but at the cost of having to write many more lines of code.

As for "weird or confusing"... it's completely subjective...

> - Jonathan M Davis




More information about the Digitalmars-d mailing list