On Thursday, 27 March 2025 at 20:25:52 UTC, Walter Bright wrote:
>On 3/18/2025 11:05 PM, Manu wrote:
>I can't imagine any good reason his experiment should have failed.
My experience with C++ and Koenig lookup heavily influenced this.
It looks nice in simple examples, but nobody stops with simple examples. Impenetrable code is the result.
Operator overloading should be part of the type, not standalone coming from somewhere else.
I'd like to understand what impediment there is to having "free" operator overloading.
It seems like once the code has been parsed/whatever, you should have "canonicalized" the operator syntax into some function call. At that point what difference does it make whether the operator was defined as a free function or member function? Basically, why would "UFCS" not also work for the canonicalized names for overloaded operators?
I write mathematical software for a living and forcing operators to be member functions sucks for me. This feature is important to me, so I'll try to spell this out a little bit. I realize that my opinion on its own doesn't carry a ton of weight; but, on the off chance that the main reason this feature hasn't been implemented is aesthetic rather than technical, I'd like to say my bit. ;-)
Main problem is that in mathematical software you want to be able to implement symmetric operations, and oftentimes doing this correctly requires double or multiple dispatch. The classic example is a small linear algebra with specialized types for different kinds of matrices.
Let's say I have a DenseMatrix
type and a SparseMatrix
type; and, who knows, maybe an IdentityMatrix
type. If I want to implement a binary operation like matrix multiplication, it really is nice to use operator overloading for this. Maybe the best case scenario for the prospecting D user is doing something like what Eigen (a C++ template linear algebra library) does and lean on static polymorphism. But now I need to stick a separate opBinary!"*"
on each type. As the number of types grows this gets significantly less maintainable. If I could define an operator as a free function I could lean on D's amazing metaprogramming capabilities and simplify my code, make it shorter, more maintainable, etc, etc. And, speaking from my own experience at least, this is not an insignificant or imagined benefit.
Actually, whether static polymorphism and the whole Eigen concept makes sense is totally debatable (at least for Eigen, the runtime efficiency gained by expression templates is completely obviated by the insane compile times... but this is a C++ library...). In many cases runtime polymorphism may be preferable. Unfortunately, D's class
is straight out since it doesn't support multiple dispatch. And, anyway, the same issue discussed in the previous paragraph persists. A way to get around this is to use metaprogramming and struct
to build up bespoke "interface" types that do support multiple dispatch (which is what I'm doing... -_-), but... well, I'll just say this also runs into trouble with non-free operator definitions.
A way around this problem that does work but isn't particularly satisfying is to kiss operator overloading goodbye. Just use mul
for matrix multiplication. There's a good chance this is what I'll end up having to do.
And, in fact, I've already done it for other mathematical operations. I have a ccomb(x, y, t)
function which computes the convex combination (1 - t)*x + t*y
for a wide variety of types (standard types, arbitrary precision rationals, intervals, vectors, whatever). Initially, I had this function defined in the module of each type I wanted it defined for, but it ended up being simpler and more natural to just define a new module ccomb.d
containing all those definitions... not unlike what is done in MATLAB! The function ccomb
is symmetric in x
and y
and a good implementation of it also wants to be symmetric. This symmetry would be extremely difficult to obtain if ccomb
were forced to be a member function.
Maybe you can see where I'm going with this... I don't see why the functions defining operators should be treated any differently!