After looking over some of the Go 2 generics proposals, I kept thinking about the primary utility of generics. For the most part it lies in collections, algorithms, and math code. For the latter however generics really don't help a whole lot without operator overloading. The versatility of C++ operator overloading combined with low or zero cost generics is what makes C++ really shine for reusable math libraries and number crunching.
However I also love love love Go's simple parsimonious nature. This is the most true thing I have ever read about programming. Some people see Go as a language for entry level programmers, but I disagree. I'm 40 and have been programming since I was between 5 and 8 years old (Commodore VIC-20 baby!) and I love it. To me it's a language for people who are past their fascination with overdone high cognitive load abstractions.
I don't want to see anything added to Go that damages that. Operator overloading misused -- meaning use outside areas where it really matters -- is one of the things that over-complicates C++ code.
So here's my idea:
Add operator overloading to Go, but make it only apply to generic/template variables.
If only generic templated variables can override operators, this limits operator overloading to only where it actually provides value and keeps it from polluting the rest of the language.
An alternative to this idea that is slightly more verbose but maybe better is to require explicit declaration of where operator overloading is to be applied. This would look something like this:
type Something struct {
x int
}
// only works if explicitly enabled in a function
func (s *Something) Operator+=(s2 *Something) {
s.x += s2.x
}
// only works if explicitly enabled in a function
func (s *Something) Operator+(s2 *Something) *Something {
var tmp Something
tmp.x = s.x + s2.x
return &tmp
}
func(foo *Something, bar *Something) {
var foo func operators {+=, +} // list of operators overloaded
//type Something func operators {+=, +} // alternative version that does it to all Somethings
//var foo func operators {...} // alternative that allows any/all operators to be overriden
foo += bar // only works with the above line, otherwise the overloaded ops are ignored
}
This shows it being done in a regular function, but it would be most useful in generic functions. This again limits the "damage" of operator overloading misuse by requiring that it be explicitly lampshaded. That way when I am reading the code and I see this I know "+" in this function can be a function invocation and not just plus.
I must also add that this would make big.Int and big.Rat a lot nicer to work with. As it stands they're a bit painful.