6 ms·
Getting specific about generics
- guscost 8y agoThis is the best outline of the Go generics issue I've seen. As an outsider to the language (for now), thanks for writing this. What's the current conversation on sharing binary code? Unless I'm missing something, this is fundamentally incompatible with generic functions that are optimized at compile time. Either the compiled version has to have implementations for "every valid type" or the shared code must be recompiled at the time it is consumed, right? It looks like the Go ecosystem tends to discourage distributing precompiled binary packages, so maybe this is not a real issue.
- kbsletten 8y agoIf I remember correctly, Go was only allows source packages and does whole-program optimizations. They designed their compiler to be fast to enable this.
- thefounder 8y agoWhy would you use binary code when Go compiles so fast?
- nimrody 8y agoPlugins. Go programs typically use RPC to communicate with plugins instead of loading dynamic libraries and calling functions in these libraries.
- grok2 8y agoGoing meta regarding tech articles, I find that it is easy to read some text-heavy articles (this being one of them) while my eyes glaze over other text-heavy articles (I couldn't easily follow Dave Cheney's article on the same topic of Go generics a few days back, though with a slightly different focus and much shorter). I've wondered what is it about specific pages/articles/writing that make them flow nicely and make it easy to read -- is it the layout of the page (font/font-size/other styling) or is it how the writing flows together or is it a factor of how much thought the author put into presenting what they are thinking or is it me (time of day, interests, etc). Maybe it is just everything!
- guscost 8y agoWhile the typesetting helps here, I think a lot is due to the writing style. Writing easy-to-read content is difficult, and it’s usually not that obvious when you’re reading it, because you’re absorbing the concepts rather than struggling with the language.
- coldtea 8y agoObviously it's the writing. You can use "reader" mode on your browser (or with an extension) to verify this.
- knocte 8y agoShe mentions the C approach, C++ approach and Java approach. But I think she should have added the C# approach: taking all the advantages of the Java approach, without the slowness of casting.
- owenjonesuk 8y agoI think the author is a woman, from the name Emily.
- knocte 8y agofixed, thanks
- marmaduke 8y agoDoesn’t that work because C# has a compiler to JIT stuff at runtime? In principle it could work in te JVM as well right?
- magicalhippo 8y agoYes, the C# approach relies on JIT. IIRC for Java they decided backwards compatibility in the JVM was more important than doing it the C# way.
- int_19h 8y agoConversely, once you remove the JIT, a bunch of stuff stops working. Look at the restrictions on generics for .NET Native.
- magicalhippo 8y agoCasting isn't slow, it's the boxing. A generics List<T> isn't much slower than the non-generic List if T is some class. But if T is say an integer, then you're paying for the implicit boxing and unboxing.
- 8y ago
- atombender 8y agoThe author promotes code generation as a practical solution to some problems — but doesn't mention the huge drawbacks for generics, which is why it's generally not used. The reason is that while you can generate a specific implementation when you need it, all the client code will still be using non-generic code. You can't write a function that takes a Set(T) as argument, returns Set(T) as a return value, or receives a Set(T) from a called function — unless you make that part of your code generation pipeline. So the code generation becomes viral, infecting each piece of code that wants to be generic. The entire language needs to be transpiled. You could lower the barrier considerably by supporting some kind of pluggable preprocessing ("//go:preprocess my_generics_syntax_plugin"), but you'd still run into the problem with combining packages from multiple sources that all wanted to share the same generic types. They would all have to be transpiled the same way.
- hinkley 8y agoI spent a bit of time thinking about this when I was younger, and got as far as thinking about the compiler or runtime relying on some sort of code reuse to improve the space complexity of generics. Each use would have to have its own metadata but should be able to share many function bodies. It won’t work for primitives but I find myself using arrays of primitives less and less.
- mikeash 8y agoSwift does this. A generic function compiled to a single actual function, which accepts metadata about the types passed in which allow it to do the things it needs. The optimizer may, of it decides it’s worthwhile, generate specialized versions of the function, but it’s never necessary.
- jasonwatkinspdx 8y agoI'm guessing the final golang solution will be like this, but with both runtime/boxed and static/typeswitch implementations generated by default, and some heuristic specializations between composing them.
- 8y ago
- skybrian 8y agoPointing to inlining and saying "problem solved" isn't really a solution because inlining can lead to code bloat just like templates can. They amount to generating the same thing at runtime. For this to be an implementation detail, the compiler needs to be able to choose not to inline sometimes.