Hacker News new | past | comments | ask | show | jobs | submit login

The list of languages that permit that in a principled way is short, and the list of languages where it's a good idea is even shorter. I've come to the conclusion that it's generally not a good idea. (And it's not Go making me say that, it's more Haskell.) Keeping dependencies flowing in one direction seems to be a good plan.



I totally disagree. It's not only a good idea, it's essential for certain core functionality to work at all. Take serialization, for example: without this feature it's impossible to write a good serializer as a library without code generation (messy and brittle) or reflection (very slow). 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). The only way I can think of to make it work is to make callers explictly box their numbers into wrapper types you create, which is really ugly and causes various other problems.

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.


> 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.




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: