4 ms·
For context: Go has been my primary language both at work and for personal use for over two years now. > It is worth pointing out that if the Go community sett
by chimeracoder 12y ago
For context: Go has been my primary language both at work and for personal use for over two years now.
> It is worth pointing out that if the Go community settles on something like this as the solution, it negates one of the underlying arguments that the Go designers have against generics in the language.
It wouldn't really negate the underlying arguments; it would just mean that the community had grown and attracted developers who may not necessarily share that part of the language creators' original vision of the language.
> But all the other solutions that are headed into that gap are just one level or another of convenience wrapper around exactly that.
Well, focusing on "the other solutions" misses two things:
First, many (I dare say most) Go developers[0] don't really use any "solution" for this other than the features built into the language itself. In other words, they're not out there writing alternative solutions because they genuinely don't perceive a lack of generics to be as big of a problem as other things, which they do write tools for.
Secondly, there is a way to use interface{} to accomplish some (not all) of the same things that generics do, while still preserving type safety. Look at the functions in this Twitter client library I wrote: https://github.com/ChimeraCoder/anaconda/blob/master/users.go https://github.com/ChimeraCoder/anaconda/blob/master/users.g...
All the endpoints use the same apiGet() function ("generic"), but they all return concrete types, and they are all typesafe - you will never get a runtime panic from any of those functions. This is more than Java's generics guarantee, due to the quirks of the way type erasure works there[1].
No, this isn't "generics", but it provides an alternative way of solving the problem most of the time (in practice), and isn't that what matters? And yes, this is not quite as clean as some languages which focus on having a very expressive and precise type system (ML, Haskell, etc.), but it provides enough type safety for me without requiring me to think consciously about the types that I am using (which I have to do when writing ML or Scala).
[0] I mean people who write primarily Go at least 4-5 days a week, for work, as opposed to people who dabble with it for side projects but primarily use other languages.
[1] TL;DR: Java's generics are converted to "Object" after compilation, which means that you can actually end up with runtime type errors that are detectable at compiletime, due to inheritance. (It's been a while since I used Java, so I won't provide an example, but they're easy to find online).
- jerf 12y agoI write a reasonable amount professionally (not full time), and while in my personal code I don't feel the lack of "generics" all that often, I do frequently feel the lack of data structures, which I'd note is what the web page uses as its example. As I've been thinking about this issue, it occurs to me that there are a few problems that get wrapped up into "generics", and "generics" aren't always the only solution, and people tend to conflate all the subproblems in their head when they say "Go doesn't have generics". For instance, one aspect of "generics" is to write "general algorithms" that don't care about the underlying data structure. Interfaces basically solve that problem. You write the "general algorithm" to a specified interface, and provide things that match that interface. It's pretty much "concepts" in C++. This is what the Go community correctly refers to when it says that we don't always need "generics" and that interfaces can be used instead... there is a specific and important use case for "generics" that is indeed covered by the interfaces. The community is correct when it points out the problems are not as large as some external people are supposing, and the external critics are also correct when they observe that not all useful use cases are covered by interfaces in Go. And I'd say the biggest uncovered useful use case is type-safe containers that aren't slices, arrays, or maps. What's more, Go's core target, network servers, is also precisely where the runtime characteristics of many of these more exotic data structures are important in the first place. Entire scripting languages are perfectly happy with arrays and hash tables as the only two effective data structures (or even just hash tables with arrays emulated on top of them!), but they pay a level of speed a Go programmer is not necessarily willing or able to pay, because network servers very often become performance sensitive. So my opinion is that whether or not that solution is "generics", Go badly needs some solution to the type-safe container problem. (And I consider the "you can do it with interface{}" argument to be a dodge. It's a very convenient moment to suddenly decide you don't need static typing in an otherwise statically-typed language. Why stop there with that argument?) Cover that one use case, and what's remaining isn't worth worrying about... it's not like the world is full of languages with perfect, quirk-free generics implementations either, once you start studying them they all have issues of their own. There is a reason the Go designers are resisting them, after all. And I can't resist generalizing a bit... what's important is not the how of a solution, but the what. If you have a problem than in some other language you'd hit with generics, then try to pick up Go, then scream because Go doesn't have generics, that's not interesting if in fact interfaces would work. The problem with "Go lacking generics" isn't, well, Go lacking generics... the correct question is, what set of problems are there than Go lacks good solutions to? And, as I show above, I'm not saying that because there are no answers to that question... I named one, after all, and there's a couple of more I could at least argue sensibly about. The point is that the conversation ought to be focused on solutions to the specific problems rather than insisting that "the stick I know from another language" has to be ported in. And, it shouldn't be focused on things that Go does indeed have perfectly cromulent solutions to, because interfaces really do cover a lot of the use cases of generics, in much the same way that in C++ templated generics can be used to implement "concepts". There's definitely some overlap here which careful thinkers should be careful to keep separate in their heads as they think about the problem. That said, I have to admit I haven't been able to sketch a solution to my type-safe data structure problem that doesn't look an awful lot like generics. But the solution space to this problem isn't bounded by my imagination. (There's some possibility that one could restrict the "genericity" to the point where it could only be used for type-safe data structures and dodge the other issues, but I haven't had enough time to noodle that over.)