8 ms·
Ask HN: Was it worth it for Go to add generics
Adding Generics seemed like a massive effort, but I don’t see any major changes to existing or new Go code since their release. Maybe they weren’t so important?
- deleted 4y ago[deleted]
- anxiously 4y agoThey were not necessary but useful in some contexts. What you are noticing is people not overusing them (which was a major concern). The only time I have used them in the last year was building a generic LRU memory cache and it worked wonderfully.
- tgv 4y agoI feel the same. I'm slow on the uptake, because I didn't want to do any unnecessary rewrites and run the risk that there were bugs in there. Now I'm writing a new module, and it'll be less noisy to type the end-value it stores as a generic, as it avoids needless type casting and checking from interface{}.
- faraaz98 4y agoIf people aren't making too much noise about a language feature then I just assume it was implemented right
- tech_tuna 4y agoAgreed. I've been wanting them and used them just a small amount thus far. There's some rough edges that will likely be smoothed out over time. All in all, they're a welcome addition and quite easy to ignore if you don't need/like them. One other side effect, now that Go has generics, we can all stop talking about them. Use them or don't. :)
- genericone 4y agoThat's the best part about it, at least on HN, no more flamewars. 6 months later, its just professionals and hobbyists going about their normal business, the dreaded apocalypse didn't come to pass.
- Jtsummers 4y agoIt's only been available for 6 months, the language has been around for nearly 13 years (November 2009). Pretty much all learning materials that aren't intended to teach generics (which have been written only in the past few months, or the past couple years about prospective generic mechanisms) will not teach generics. Anyone picking up The Go Programming Language or any other text or watching any video course will not be taught to use generics. And since there has been about 12.5 years worth of code written without generics and that code works, there's little need to massively change anything. So until the learning material catches up and until new libraries are written, or old ones have a reason to be updated, you won't see generics widely used.
- indrora 4y agoSimilarly, the same thing happened in C#. Where Go and C# have differed is where generics are common. In the introduction of generics into C#/.NET, their use was added everywhere. Microsoft made a huge point of including built-in List<T> and ArrayList<T> and other common things that would benefit from generics. Go however has drawn the line in the sand that generics are not allowed into the standard library for now. Rob Pike has been vocal about this [1] and I can almost agree with him. Part of the issue is that the way Go handles the standard library. Part of the issue is how libraries in general are managed. * Go’s standard library is simultaneously “just a git repo in the ether” and “A thing shipped with the Go compiler runtime”. Like any other library. * Libraries in general being “Just another git repo”, many haven’t been updated to use Go modules. Because Go doesn’t have a good central repository for go libraries, I don’t have good numbers on this. [1] https://github.com/golang/go/issues/48918 https://github.com/golang/go/issues/48918
- Jtsummers 4y agoC# also adopted generics earlier in its life. 2.0 was released in 2005 and added generics, the language was first released, announced?, in 2000. It was also around the same time as Java added generics.
- basicallybones 4y agoGenerics in Go are very helpful for my team. They allow us to create reusable functions in common libraries in our monorepo that are simple to reason about and easy to read. For instance, we have an internal library that helps us create and perform common operations on concurrency-safe maps. Being able to pass and return arbitrary structs to/from those functions has made our codebase much cleaner and easier to work with. Please take my response with a grain of salt, as we have not benchmarked or otherwise compared (via escape analysis, etc.) those generic functions against any non-generic equivalents.
- dmitryminkovsky 4y agoI would have to imagine that at runtime there is no difference between a generic and non-generic function. I imagine (emphasis on imagine: no actually knowledge) that generics are used at compile time to check types? I have no idea whether Go erases generics though. Maybe introspection is slower with them?
- gmfawcett 4y agoWorth reading: https://go.dev/blog/when-generics https://go.dev/blog/when-generics
- throwaway894345 4y agoGo's generic implementation (sadly) tries to reduce the amount of code it generates by generating code which dispatches to the concrete methods at runtime. The rules for when this dispatch happens aren't easy to understand, and they're subject to change, so reasoning about performance (already hard) gets strictly harder. In some cases, generics might make code faster, and in others it may make code slower.
- throwawaymaths 4y agoThere is a difference. Most people (who use go for network IO bound services) will not notice.
- Tea418 4y agoThe public Go code I usually read are libraries and I admit I also noticed only a little adoption of generics. My personal hypothesis is that many libraries follow the official Go release policy[1]. Due to the fact that generics were introduced with v1.18 and we now have v1.19, libraries would be bound to the features that were available with v1.17, unless they spend effort on working around this by implementing the respective build flags that make generics available exclusively for >=v1.18. However this is just an assumption. According to the Go Developer Survey 2022 Q2[2], 1 in 4 respondents said they've already started using generics in their Go code and 14% have started using generics in production code. [1] https://go.dev/doc/devel/release https://go.dev/doc/devel/release [2] https://go.dev/blog/survey2022-q2-results https://go.dev/blog/survey2022-q2-results
- Macha 4y agoHonestly, 1 in 4 sounds pretty in line with Java and C# codebases which have a similiar conservative culture (assuming "using" = "writing generic classes/functions", and not consuming, which I think is a pretty safe assumption as Go already had generics for the consumer in the built in map/list/etc)
- evanelias 4y agoThe official Go release policy is to only support the 2 most recent versions, currently Go 1.18 and 1.19. So libraries can strictly follow this policy and use generics without any need for build flags. That said, libraries often want to be friendly to older Go versions, so I agree with your overall hypothesis. Backwards compatibility is another major concern for libraries: I assume you can't safely change the signatures of existing functions from interfaces to generics, for example. (Well, aside from some special cases like interface{} becoming "any".)
- Beltalowda 4y agoAlso: many libraries have little or no use for generics, and even if it's some benefit it's still worth asking if it's enough benefit for the added complexity (e.g. replacing "any" with generics is probably good; replacing "string" or "int" with generics: not always). Also also: in quite a few cases switching to generics is a backwards-incompatible change or an "ugly" change (similar to Foo() and FooContext()), which makes adding them to existing libraries a bit painful.
- lm28469 4y agoI've seen them used in places we could have skipped them more often than in places we needed them.
- davewritescode 4y agoIt takes a while for ecosystems to catch up. Java 8 primitives in library code took a few years to happen, I assume the same thing will happen in Go. Generics are typically very useful in a few very specific contexts but in most applications you can get by fine without them.
- Kukumber 4y agothat's a success if it didn't cause any harm Go is the cloud native language, there is no need to change your production code only just to add the latest shiny feature, that goes against the philosophy of Go people will adopt the new features slowly but surely as they get battle tested
- verdverm 4y agoIs it too early to answer this question?
- latchkey 4y agoYes. https://github.com/cornelk/hashmap https://github.com/cornelk/hashmap
- nvartolomei 4y agoI tried bringing them to a few relatively small codebases and the most frequent feedback is “why introduce this complexity when you can write a for loop in place”. <s>Must be some sort of Stockholm syndrome that affects people “writing go for 13 years”.</s>
- deleted 4y ago[deleted]
- rgoulter 4y agoThere used to be a troll repo on Facebook's GitHub org about Go generics, which is now archived, so ... maybe? https://github.com/facebookarchive/generics https://github.com/facebookarchive/generics
- throwaway894345 4y agoI have pretty mixed feelings about them. My opinion hasn't changed dramatically since they've been released--they make certain things easier, and they lead to people overcomplicating things. I also don't care for the dict-based implementation--it makes it considerably harder to reason about performance tradeoffs. Mostly though, most of the stuff people were complaining about regarding Go's lack of generics were really minor things, like map/filter versus for loops. There are some things you really couldn't do easily in Go without generics, but for the most part Go's critics were just obstinate about not wanting to learn a new style of programming (so much so that many are willing to forsake all of Go's considerable advantages with respect to tooling, deployment model, build times, package management, ecosystem, etc). Moreover, Go's critics were (and still are) unwilling to admit there are benefits to avoiding generics--the code becomes less abstract and more standard as there are fewer ways to express a given solution. If you really want to dunk on Go, the more valid criticism is that it lacks sum types, and unlike converting a map/filter chain to a for loop, there is no good way to emulate sum types in Go (there are some tricks to get close, but they involve far more boilerplate and they don't give exhaustiveness checks (and the performance tradeoffs suck).
- seer-zig 4y agoWhat you mention as considerable advantages might apply for someone coming from Python or Ruby. For many of us in Java or C# land, what they have is already much better.
- kaba0 4y agoOkay, sum types. Let’s say you want to implement an optional type, how would that look like with sum types? `Nothing` is okay, but `Some` needs to somehow mark the wrapped object’s type, so you also need generics here.
- throwaway894345 4y agoYou don’t need to implement a generic option type. It’s easy enough to implement ad hoc like we do/did with linked lists pre-generics.
- dangoor 4y agoYes! I spent some time a few weeks ago redoing some code that relied heavily on reflection into code that is fully statically typed and this only works because of generics. The particulars is that I have a YAML file that defines some validation information for incoming data and the old code used to dynamically compare the expectations from the YAML file with the data. The new code statically defines everything that's allowed in the YAML file and turns that into a small number of function calls to validate the incoming data. It's a very frameworky piece of code, which is exactly the kind of thing that can benefit from generics.
- bugfix-66 4y agoGenerics are useful for some purposes. But mostly they can be avoided in favor of simpler language constructs. Most Go developers understand the importance of using simple code constructs. There are many experienced developers who (through long experience fighting C++) have come to understand that using a simple language (like Go or C) allows you focus on the algorithms and complexity of the problem you're trying to solve. This is part of the Go culture. A junior developer might not understand this yet. He's still having fun finding obscure and convoluted contortions of the language that allow him to save little or no effort... not yet realizing that nobody gives a shit and he's wasting his time and the time of his coworkers.
- Tozen 4y ago> developer might not understand this yet... having fun finding obscure and convoluted contortions of the language... not yet realizing that nobody gives a shit and he's wasting his time... There's a major issue of programmers trying to impress each other, by creating complex convoluted monstrosities, and not realizing what is actually important. It takes them awhile to find out that what they have produced was not impressive, and the people that know better, are also not impressed.
- hakunin 4y agoSometimes this advice is taken the wrong way, and people begin assuming that applying any thought to code design is "being obscure and clever" and "finding contortions". Some of the cleanest, most boring code I've written came out of days of contorting and experimenting to arrive at something that looks entirely boring and obvious. On the other hand, when code is quickly and simply added on, it grows into thousands of lines of messy entangled functions and types that are impossible to follow. We gotta make sure that people don't get the wrong idea with this advice. Simplicity can sometimes take more work and cleverness to achieve than complexity.
- kaba0 4y agoIt’s not simple vs complex, it’s being able to express something often quite important about the types or not. E.g. a simple map is not implementable in a sane manner in a static language without generics, because you likely want to know the type of the object you get from there at compile time. There is a reason C has no sane data structures at all, everyone has their own creation which either brings in a big deal of overhead, or employs copy-pasting mostly the same code (which is pretty much what generics do behind the scenes, at least in an overly simplistic manner).
- mattnewport 4y agoPeople who care about generics already decided not to use Go because it didn't suit them. People who used Go value different things in a language or they wouldn't have been using Go.
- gregwebs 4y agoUnfortunately we have to wait. Generics handle simple cases well, but have issues with more complex edge cases. Every go release is improving Generics. 1.19 has a performance regression that will be fixed in 1.20. Library authors want to support old go versions, and the library usage of Generics might not work on that older version. I just started using generics because I wanted a couple release cycles for issues to be shaken out. I would suggest to most library authors to wait until 1.20 is released before using generics, and if you are doing anything slightly sophisticated to make sure you have a CI that builds with older versions of Go. If you are writing application code, then go ahead and use generics, but generics are usually most useful for libraries. I was recently able to fork a library for better error handling in Go and make a version similar to the try proposal. This library wouldn't have been possible without generics: https://github.com/gregwebs/try https://github.com/gregwebs/try
- PeterCorless 4y agoScyllaDB used Go generics to get a 40% gain for B-Tree performance https://www.scylladb.com/2022/04/27/shaving-40-off-googles-b-tree-implementation-with-go-generics/ https://www.scylladb.com/2022/04/27/shaving-40-off-googles-b...
- mountainriver 4y agoI thought Scylla was written in c++?
- markoman 4y agoThis was for the Scylla Go Driver.
- jeffrallen 4y agoI'm an avid Go user with zero interest in generics. I figured I'd learn then when I had to, i.e. when a dependency breaks and I need to go debug it and it uses generics. I still haven't learned generics.
- wara23arish 4y agoI wrecked my brain last week trying to get generics to work correctly and i think Go just won’t support this. have a function take in an array of T T is generic with type constraint call Constraint problem is calling that function wont work because it has to instantiated with one of the types found in the Constraint which beats the whole purpose. I need this to pass in structs that belong to Constraint. I tried a multitude of different things and nothing seemed to work. I ended up reading the Go library for how it handles SPrintF args and did something similar with a type switch and reflection wizardry. Im still a junior programmer so it could be that I just didnt know how or I underestimate the solution for this. But I figured once we have a type Constraint defined with a function, it should be relatively simple to not have to instantiate it with ONE concrete type and allow the Constraint types as args. if anyone knows a better way to do this please let me know
- markoman 4y agoI think its best to paste some code, i.e, the code (theoretically) meeting your requirements that failed, and code that compiled and got the closest to meeting your requirements. Hopefully someone can bridge that gap for you.
- wara23arish 4y agoI made an example of what Im trying to do. https://goplay.tools/snippet/Vj7uVMi0mWn https://goplay.tools/snippet/Vj7uVMi0mWn Basically have two different types that implement an interface, pass them into a receiver function in a composite type (array,slice). Part of the issue is that you cant have the receiver function without defining instantiating the type on the receiver Spotter in this case.
- markoman 4y agoYou don't actually have to instantiate the type for a receiver function (i.e., method). There's too much missing from your code for me to understand which direction you're going but you'll likely have to use a constraint for structs which is explained here: https://github.com/akutz/go-generics-the-hard-way/blob/main/04-getting-going/04-structural-constraints.md https://github.com/akutz/go-generics-the-hard-way/blob/main/...
- nickcw 4y agoI looked through the rclone code to see if I could use generics. In particular I looked at places where we use code generation and places where we use reflection - both good candidates for generics. Alas I found generics just weren't powerful enough to replace these uses, it would need a more powerful macro system. I think go generics are great for container libraries. I've written and debugged enough of those to be very happy using a library. I doubt Go will ever get macros though. I really like Zig's comptime mechanism - that seems like the right amount of power and it's all just zig code!
- michele 4y agoI have been using go for maybe 6-7 years and couldn't care less about generics. However, I now have to admit I'm quite happy they added them and I used them a bunch of times already to clean up my code and make re-usable types/functions across our stack. So was not having generics a deal-breaker? No! Are they useful? Yes!