5 ms·
What makes Go's type system poor?
by omginternets 10y ago
What makes Go's type system poor?
- jerf 10y agoOne of the worst places lack of generics hits is numeric code, because you really want to be able to write Vector<int> or Vector<byte> or Vector<complex> without having to write all that over and over, multiplied across a significant number of such structures you might want templated (matrices of several types, several types of math-vectors, several types of arrays, etc.), multiplied across a large number of operations on those types. Datastructures times types in them times operations on them comes out to a big number in numeric code. I've often thought that the utility of templates in numeric code is part of the reason people tend to overestimate its utility in other places. Seeing something really nail a solution in one domain and assuming it must be equally useful everywhere is a common programming community failure I've seen over the years, and I've been putting together a sort of list in my head of such things. (It currently includes "inheritance based OO is awesome because it nails writing GUIs", even though it's not so great for most other tasks, "FP is great because it nails writing compilers" which is getting more popular but it took more than just that, "data binding is great because it nails simple CRUD forms" but inevitably explodes in complexity beyond that, that sort of thing. Beware the techonology that is always demoed on the same use case every time, in every video and essay written about it.) (And I'm not saying templating is useless, any more than any of the other things I mentioned are useless. I'm just saying it's very easy to overestimate the importance and utility of the given technology if you only look at where it is at its absolute best. You really need to look at the whole picture.)
- omginternets 10y agoSo this is a very interesting way of describing language niches, because I've often felt that Go nails one thing very well: routing streams of bytes. Any time you have to deal with "plumbing" (for lack of a better term), Go makes the job absolutely trivial. In a sense, I think it's a shame that Go has made it's name as "a language for concurrency" because I think that the concurrency features are in fact supporting features of the aforementioned usage: streaming dumb bytes left and right. Otherwise stated, Go is concurrent because concurrency helps ship bytes; it's not concurrent for the sake of solving general concurrency problems. With that in mind, I'm still not clear on what makes Go's type system sub-par. I keep hearing this meme repeated, and although I know next to nothing about type theory, I have always found Go's type system to provide just enough scaffolding for byte-delivery pipework. Beyond that it just gets out of the way. Consider this: Go is formally a static language, but it behaves (in the sense of how it's used in a workflow) in a manner closer to a dynamic language (compile time is equivalent to ipython's warm-up time, go playground makes testing snippets interactively very simple, etc). I think it's an error to compare Go with C. Go feels more like Python with concurrency and type safety. So again: I understand the use-case for generics, but viewed through the lens of "nailing" the problem of shipping bytes (which again, I contend is Go's purpose), I fail to understand why Go's type system is repeatedly labeled as lacking. Go isn't Rust. It's not solving the same problems as Rust. From there, what is it that makes Go's type system shitty? I would describe it as "just enough type system". Other than generics, what is it that people are expecting this damn thing to do? I'm very much open to being wrong (especially since this would inevitably introduce me to some interesting languages), but I can't quite conceptualize what people have in mind when they complain about Go's type system.
- jerf 10y agoMy reply is intrinsically in the domain of scientific code. It is not intended to make sense in the general context. In that global context... Go's type system is about as simple as they come. It's actually hard to come up with a statically-typed language that, in practice, is simpler. The type system in C itself is technically simpler, but with preprocessor macros I'm not sure if it's simpler in practice. I'd say that's why it's generally labeled as "lacking"; on the scale of type system complexity, it's near the bottom before you get into dynamic languages. If you'd like to learn why that might be a problem for people, I recommend jumping in the deep end and learning Haskell for what strong type systems can guarantee. There are certainly times I find myself unable to say things in the type system that I would like to be able to say in Go's type system, even given that I am in fact writing network servers with it. I take the tradeoff because in the context I'm working, the simplicity of code tends to win out even so. Also: https://news.ycombinator.com/item?id=10208075#10208636 https://news.ycombinator.com/item?id=10208075#10208636 And I would fully agree that a non-trivial amount of Go hatred (but not all) occurs from people picking it up and trying to use it in a context they should never have even picked it up for. (That said, I tend to consider scientific programming one of those, and a burgeoning community seems intent on proving me wrong, so shrug.)
- omginternets 10y ago>My reply is intrinsically in the domain of scientific code. It is not intended to make sense in the general context. If I'm being honest with myself, I too have serious reservations about the extent to which Go is suited for scientific computation. > I recommend jumping in the deep end and learning Haskell for what strong type systems can guarantee. I'm superficially familiar with Haskell's typeclass system, but respectfully, this misses my point. What use is such a system in the context of scientific computing, or in the context of Go's mission? I understand that there are type systems with stronger guarantees, but again, Go is not Haskell. Go is not Rust. Go is not solving these problems. My question is, in practice, what features of a type system are "these people" (the ones complaining about Go's type system -- I don't presume to label you, jerf, as one of them) pining for? My (respectful) exasperation stems from the fact that these arguments usually compile down to something roughly equivalent to "Rust exists so why is Go not Rust? (Or Haskell)". >I take the tradeoff because in the context I'm working, the simplicity of code tends to win out even so. But this is exactly my point. At some point, adding features to the type-system is going to reduce the simplicity you enjoy in the context of problems for which Go was engineered. I appreciate that (to quote your linked comment) "the further away from a 'network server' you get, the less appealing Go gets", and that every success story you encounter with Go involves network servers. Moreover, I agree. Go nails this particular problem space, and I contend that this is in part because of the fast-and-loose design of its type system. We are in agreement with respect to Go's problem domain, and we are in agreement with respect to the fact that Go should not be viewed as a general-purpose concurrency language. These points, however, do not address the question of its type system. So again: what more do you want this type system to do in the context of writing network servers? Which specific features from Haskell do you find yourself wanting, and what guarantee do we have that this would not undermine the simplicity and dynamic-i-ness that has made Go successful as a plumbing language? >That said, I tend to consider scientific programming one of those, and a burgeoning community seems intent on proving me wrong, so shrug. I'm inclined to agree with the caveat that certain disciplines (molecular bio and genetics for instance) increasingly rely on high-throughput streams of data. Perhaps Go is well-suited to the pipework, and perhaps it's advantageous to perform simple data transforms natively prior to doing the heavy lifting in Python or Julia ... I nevertheless remain unconvinced.