> To give another example, try writing a linear algebra library that's generic over the data type without this feature (and such libraries are essential for high performance graphics programming).
I disagree. My best, fastest to compile code has always focused on just one type. You mention graphics programming: for 99.999% of the cases you want to pick a type. Usually, this will be float, and thus for SIMD a 4 or 8-vector of these, like https://github.com/aktau/threedee-simd/blob/master/include/t.... Despite the support of recent graphics cards for doubles, the fact is that they are usually quite a bit slower. Even when precision bound, there are usually tricks that will let one keep using floats (esp. wrt to Z-buffers).
It's very useful to use different types (for example, fixed point) in VBOs in order to save space and/or reduce CPU side processing.
Are we talking about the same thing? That is the most full-throated defense of orphan instances I've ever heard. The reaction to such things is generally... less positive... to put it lightly.
Orphan instances arise when the implementation of the interface is in neither the same package as the package that defines the type nor the package that defines the interface. I'm defending the latter (which Go's rules rule out), not orphan instances.
I don't understand the idea that not having this feature somehow helps enforce dependency order either. Extension implementations of traits don't give you any more abstraction-breaking power than downcasting interface{} to a concrete type not defined in your package does. In fact, they're pretty much strictly less powerful.