9 ms·
Summary of Go Generics Discussions
- dale-cooper 12y agoFrom the java section: > A vector of bytes uses significantly more than one byte per byte. There is still the option to use an array of bytes (the primitive data type, not the class Byte) if the performance of boxing/unboxing is a problem. In fact, i don't understand how the vector example is relevant to generics at all. Even pre-generics the underlying storage for a Vector in java would be an Object array so the boxing/unboxing would still happen?
- jerf 12y agoAh, this threw me for a while too. So the answer appears to be: Suppose you have a generic function X(Y), where the "Y" is generic. Now suppose you want Y to be truly generic, and not just Java-style generic, which means that Y may be any size. That is, it may be a "byte", it may be "short", a "long", a 184-byte struct, a pointer, etc etc etc. The way most programming languages do functions, functions encode into themselves the sizes of what they are expecting, and the expectation for how they are going to receive parameters. Therefore, a single function can't take all those options, and at the very least you end up needing one per base size, plus one for spilling to the stack... and that's just to deal with the size issue, you still have signedness, various struct properties if you're passing structs, etc. So one option is to "box" everything, which basically amounts to saying "I will take a pointer to everything", and in the case of Go, "I will take the pointer to that thing's type". (That's how interfaces work in Go.) Now everything is the same size (pointer-sized). But now everything's boxed. Alternatively, you can compile lots of functions, but now everything's compiled in separate copies of the function. From the high-level language POV it all seems so simple. When converting it into actual assembly, which has to interact with the rest of the system, it gets more complicated, and the performance implications of even slight slowdowns to a function call can be catastrophic given how many of them we make. Personally I'm still interested in the question of whether it's feasible to create a different calling convention into a generic function that deals with this directly. This might not be possible in C due to its age, or C++ due to its reverse-compatibility heritage, but I'm interested in whether we can write a sufficiently-generic (in the more general sense of the term) function calling system that it can work with Go better. Basically looking at types like a vtable and abstracting out all the calls that are size-dependent into vtable-lookups, which ought to be slower but only slightly slower than a direct call (given that it seems like everything can be resolved at compile time except the actual address). But I don't know. Interested to hear if anybody else has ever tried that or anything similar. (Assembler is a great deal more flexible than the structured programming we have laid on top of it, at least in theory.)
- dale-cooper 12y agoThank you, that was a great explanation. For what i've been using java for it's never really bothered me. When there is need to use primitives it's almost always in the form of a list where you can just use an array instead to avoid the boxing/unboxing. The risk of null pointer exceptions when implicitly unboxing objects are more annoying..
- diakritikal 12y agoPrevious discussion: https://news.ycombinator.com/item?id=8756683 https://news.ycombinator.com/item?id=8756683
- Pxtl 12y agoIt is incorrect to say that the c approach is no generics. C has its precompiler macros which functionally provide a crude form of generics.
- wheaties 12y agoC macros are the worst form of macros. They are string substitution without type checking and can very easily leaf to all sorts of issues. That said I'm in the macros camp instead of generics just because I think go authors would actually do it.
- asb 12y agoHygienic macros for Go (i.e. an equivalent of sweet.js http://sweetjs.org/ http://sweetjs.org/) would be very interesting.
- copsarebastards 12y agoIf you're rooting for language features based on the willingness of your language designers to implement them rather than what will make the language better, your language ecosystem is fundamentally broken and it's time to move on.
- dragonwriter 12y agoPreprocessor-based solutions (and cleaner, IIRC, than C preprocessor macros) for Go generics exist, too. So, "no generics" for C is as accurate as "no generics" for the Go status quo.
- Pxtl 12y ago"exist" is not the same as "is built into the language and compiler".
- dragonwriter 12y agoNeither C nor Go has generics, preprocessor based or otherwise, built into the language and compiler. Both C and Go can have (and, in fact, it has been done in both) some degree of generics implemented in a preprocessor-based way using only features built into the language and compiler. So, again, I would maintain that "no generics" is no more valid of the Go status quo than it is of the C status quo.
- commentzorro 12y agoThis is such a biased document as to be pointless. The authors are so opposed to generics that I don't understand why they bother. Just a few beauties: > The generic dilemma is this: do you want slow programmers, slow compilers and bloated binaries, or slow execution times? I don't think these are the only outcomes, but lets go with it. A slightly slower compiler then. Solved. > The generic structures are less useful than a concrete one. If they weren't more useful then nobody would be arguing for them. > Generic structures can be less optimized than a concrete solution Ridiculous. >Code won’t look idiomatic. Idiomatic is a function of the language syntax and features. If generics are a feature then their use will, by definition, be idiomatic. And on and on. At this point people using Go accept the lack of generics (and, oddly, sometimes wear the omission as a badge of honor). I don't think anyone happily using Go is expecting generics anytime soon, if at all. And I don't think the authors need a paper to show their dislike for them. Who are they trying to convince anyway? EDIT: A few folks have told me I come across too heavy handed in my reply. I apologize to and don't mean to discourage the author(s)! It's a tough document to write. Especially if this was just a starting "brain dump." The document title had just set my expectation towards a neutral tone.
- jpgvm 12y agoI agree. Those using Go without generics will go on using it. I would also posit the following though: Those that don't use Go because it lacks things like generics aren't likely to use it once they are added either. My personal opinion is Go is a simple language with little to no features of significance. This makes it easy to learn and easy to write. However, it leaves programmers used to higher level and more powerful constructs wanting. If you are used to writing Haskell or even something like Ruby then Go is going to feel like a pretty significant step down. God forbid you are looking at a language like Rust which makes Go look skinny in terms of features indeed. At the end of the day it boils down to what you are happy with using. Is a hammer and nails good enough for you? Or do you prefer a variable speed handheld drill with impact mode and keyless chuck, etc etc etc?
- mrcwinn 12y ago"God forbid you are looking at a language like Rust which makes Go look skinny in terms of features indeed." No disrespect meant to Rust, but it's hardly as simple as saying, "Go lacks Generics! Use Rust!" Rust is far --- far --- from production-worthy. It's certainly settling down into a 1.0, but it has had an extremely volatile standard library and design. There are some early contributors who are doing the "brave work" of using it in production with the aim of bringing it forward to a 1.0, but for the rest of us, it's simply not even in the consideration set. There's also a real question about garbage collection. Rust's "feature set" is surely thicker than Go's - but you need some of those things because you're doing much more work at compile-time. We can argue about the runtime cost of a mature GC (and Go isn't even there yet!), but again, it's not as simple as "use Rust." There's a real productivity cost, I would argue, with doing that extra work and adding that complexity. It doesn't boil down only to what you are happy with using. For the weekend project, it really doesn't matter at all. For a large, production application, there are real, important questions to answer and they matter a great deal. It's not "is a hammer good enough?" - A hammer is hardly good enough when you're staring at screws. I'm not saying one is right or one is wrong. I'm saying choosing a language is usually only something that matters at a certain scale, and at that scale, you have to be very knowledgable and careful.
- callesgg 12y agoThat generics would allow for better Type-safety is only true if one compares it to using empty interfaces (or some other type less thing). But it would actually lead to less accurate Type-safety than if one had a different sort method for each sortable type, it would lead to some amount of "duplicated" code but that is a different matter than Type-Safty.
- tel 12y agoIt would lead to less safety but more type safety, actually. http://jspha.com/posts/six_points_about_type_safety/ http://jspha.com/posts/six_points_about_type_safety/
- deleted 12y ago[deleted]
- simias 12y ago> No abstract examples/arguments. These cause the discussion to lose focus and make examples harder to follow. The example/argument must be traceable to a real-world problem - Go is intended to solve real problems not imaginary ones. I find that's a very good rule in those discussions, it's too easy to get bogged down to some obscure use case and miss the forest for the trees. I note however that the authors seemed to have forgotten about that rule just after writing it down since the rest of the document is full of vague assertions and unsubstantiated arguments like: - "I have heard of simple libraries having text segments shrink from megabytes to tens of kilobytes by revising or eliminating the use of templates." - "Generic algorithms can be harder to follow than their non-generic counterparts." - "Fancy algorithms are slow when n is small, and n is usually small. - Rob Pike" - "map/slice suffice for most of the cases encountered in programming. (based on some community opinions https://groups.google.com/d/msg/golang-nuts/smT_0BhHfBs/MWwGlB-n40kJ)" https://groups.google.com/d/msg/golang-nuts/smT_0BhHfBs/MWwG.... The linked thread contains a bunch of posts, not sure what I should be looking for (I thought the whole point of this document was to "go over the relevant points without digging through hundreds of forum posts"?) - "Code won’t look idiomatic." I'm not sure what that even means. I don't know if generics have a place in Go or not but I'm not sure this document is going to help solve that issue. Making a list of concrete use cases for generics and discussing possible alternatives would probably be more constructive.
- jerf 12y ago"I note however that the authors seemed to have forgotten about that rule just after writing it down..." I feel I need to remind you, and a lot of the other commenters here, that this is a top-level summary of all the various arguments. And that it is possible on the Internet to mention arguments without actually advocating for them at the same time. I doubt you could find any individual on the planet that would "agree" with that entire document from top to bottom.
- simias 12y agoThen it should link to the various places where those arguments have been discussed. As it is it's hard to take that as a neutral reference and looks more like an opinion piece against the implementation of generics in Go trying to pass off as a neutral reference. If that was on wikipedia it would be littered with [citation needed].
- datashovel 12y agoSomething that has turned into such a contentious topic one would think someone would fork the project to add generics themselves. Perhaps in an effort to "prove" how it could be done easily or cleanly. How many man-hours have been spent arguing about this?
- jerf 12y agoI've actually considered stabbing at it, but at the moment it's best to wait for the idiomatic Go rewrite of the compiler to get further along. And by "stabbing at it" I mean opening up the compiler to see how difficult it would be, not a commitment. But even for that, the best answer right now is to wait for the in-progress compiler rewrite to get further along.
- datashovel 12y agoI think it will be interesting to see what kinds of things bloom from the rewrite of the compiler.
- bsaul 12y ago/offtopic This kind of discussion is actually something that bothers me even more than generics at the moment : https://groups.google.com/forum/#!topic/golang-nuts/m7k9EpxqK4I https://groups.google.com/forum/#!topic/golang-nuts/m7k9Epxq... Come on... removing an item from a list requires tricks ?? I know go aims at being memory efficient, but delete(list,obj) should be idiomatic.
- ansible 12y agoCome on... removing an item from a list requires tricks ?? That's not a list, it is a slice. Which is a slight abstraction over an array. You the programmer are directly responsible for the size of the slice storage, and how many elements it currently contains. I know go aims at being memory efficient, but delete(list,obj) should be idiomatic. If this ends up being a common operation, I could understand arguments to add it to the language. But in general if you are adding / removing items a lot, you'd be better off using an actual list data structure instead.
- bsaul 12y agoThen i guess we're back to generics. Having to use this interface : http://golang.org/pkg/container/list/ http://golang.org/pkg/container/list/ , with its "Element" wrapping a "Value" property of type interface{} seems really weird for such a basic need. It means that whenever you're storing an object into the list, you need to remember the element in addition to the original object to be able to remove it later...
- NateDad 12y agoExcept that no one ever actually used that package. We just use normal slices which are generic.
- bsaul 12y agoHence my point... People use arrays like they would use ArrayList or Vector or any dynamic container created in the last 25 years and expect to be able to remove an object in one function call.
- robteix 12y agoThe Go team has repeatedly stated they have nothing against generics per se and they see a value for it. They simply have not found an implementation that works with language values (simplicity, fast compilation, etc.) If anyone can come up with an implementation that works, I see no reason why the team would say no to its inclusion.
- dvirsky 12y agoI wonder what a survey of real Go users about generics would show. I'm betting an overwhelming majority would like that.
- bsg75 12y agoWould these be people writing "production" code in Go who need generics, and for some reason have not been instead using a language with the features they need? The whole continued argument is odd. The "whole generics are important" and "Go is too simple" thing seems counterintuitive when all of the comments mention Rust, Haskell, Java, etc., yet the proponents of generics are not using those languages instead. Why if Go does not have the features one needs, would a person be compelled to use it?
- dvirsky 12y agoSimple - it has many other virtues that outweigh this even if you need it. I'm writing a lot of production Go code, and I'm very happy about the language. I wouldn't put generics at the top of my wish list but at times I wish I had them. But not enough that I'm willing to use a 3rd party solution, so I guess not that much :)
- NateDad 12y agoIt's pretty well split down the middle from my experience on these topics. And few people are really ravenous for them. However, you're talking about selection bias. If generics were something you absolutely wanted, you probably wouldn't be using go in production. One of the things you learn when using go is that generics are not the answer to everything. They are certainly the answer to some specific things, like optimal implementations of common algorithms.... But not every application needs to use the A* algorithm, or a left leaning red black tree... Would I like to have generic implementations of those that I could just toss in my application with my own types? Sure. But I've done enough generic programming to remember when you could finally stop writing foo<bar<baz, bat> > And could finally do foo<bar<baz, bat>> .... And I don't really want to have to write that kind of code again.