Go is a crap programming language with a good runtime.
- No generics
- No true buy-in on the idea of a structural typesystem
- No sumtypes
- An anti-intellectual fanbase
- Exceptionally painful error handling
- Zero ability to abstract anything out without relying on the reflection package which leads to brittle and slow software.
They didn't do everything wrong though.
- It's great that they have a spec (I wish it came with formal semantics, but still)
- It compiles quickly and is easy to analyze (so tooling w.r.t. LSP is great and exceptionally fast)
Anyway, I never find programming in Go fun, and I find Rob Pike to be obnoxious. OK, that last part might just be me projecting how obnoxious Go is onto him.
A few years of Golang under my belt and I still hate it. Russ Cox and co. seem incredibly arrogant to me in that they can ignore decades of PL research only to reinvent a bizarre way of achieving what other languages do in a more standard way (package management, error handling), or just adopt that standard super late (generics).
Go has some great qualities and you can make great software with it no doubt. But I find the development of the language frustrating to witness, not inspiring.
Go is the worst programming language out there, aside from any other language I've tried so far.
Seriously though, besides being just a good solid balance between speed, ease, safety, etc without anything really exciting - there are a few cool things about Go that make you write cleaner programs: The biggest one for me (well, maybe after the concurrency model) was the whole implicit interface thing, alongside interface composition and avoiding Java-style class hierarchy. It just forces you to think in interfaces and avoid complex hierarchies. This leads to much cleaner elegant code-bases.
I think that's always been my problem with Go, it feels like it makes a set of trade-offs that really benefit nobody. It isn't low level enough to really unseat C (Rust stands a much better chance there), but it isn't high level enough to replace something like Haskell, Java, C#, or Python. Its type system doesn't seem too terrible until you run into the strange hole left by lacking generics, which considering that basically EVERYONE these days supports generics or a similar mechanism is a very strange stance to take.
TL;DR: Go is a language designed for nobody, no matter what niche you try to fit it into it's missing some feature that's desirable in that space.
After a couple of years with Go, I'm neither particularly happy about, not particularly unhappy. It's a decent language. Productivity is high, which trumps many other concerns.
There has been so much controversy about generics, but one related area where Go is consistently annoying is when you want to define a sort of language of data types -- where in a different language such as Haskell would define algebraic data types. For example, an AST of syntax nodes: There's no way define this (simplified):
data Node = Literal | Identifier | And | Or | Not | EQ | NEQ | ...
Instead, you must define a bunch of structs and use a dummy interface that all nodes implement. Even then, Go has no pattern matching, so if you want to handle a node, you need a switch statement on type, then check the data with an if. And even then, there's no way to prove at compile time that the switch statement is exhaustive (you could do some runtime magic with reflection-based lookup tables, but it's still poor). If you want a generic mechanism to traverse and rewrite such deeply nested data structures, there's a lot of exhausting boilerplate in the way of the core logic, because, ahem, no generics.
I'm in the middle of a project that has three sets of such data structures (a low level AST, a high level expression grammar, and a query plan graph), and it's an area where the Go development experience turns from pretty good to pretty dismal. I've considered writing a mini-DSL and using "go generate" to generate Go code, but I've not yet decided on the best design.
yeah but people hate writing Go. It’s like using the dullest possible knife. It doesn’t have objects, it doesn’t have generics (so you can’t really do Functional Programming) and it doesn’t really let you do C-style machine work either. Its basic assumption is that you’ll have an endless supply of human beings to
implement everything, because the computer isn’t going to let you abstract anything
Rob Pike once told me I was a moron (not those exact words) but that intent when I asked a question in some performance Golang slack about how big a Golang map is in memory (as in the total bytes used by it internally).
He went to a previous commit from the one I had linked, saw my stupid attempt at estimating it, and proceeded to go on a rant in which he simultaneously called me an idiot and pointed to the answers in the runtime code. Pretty entertaining.
Of course, the code was stupid because I wrote it knowingly so, just so I could fill the function with compilable code and go debug something else. I guess not writing a comment is on me for not knowing Rob Pike was going to go out of his way to find it the next day.
Fun day at the office, that one. So yeah, I am not the greatest fan of Go or him either. But that was from way before when I had to write a JSON-LD parsing library and cast stuff to `interface{}` everywhere.
I write personal stuff in Rust now, but would happily do it in any other language with a proper toolchain and type system. Go has only one of those, so I don't dislike it. Just don't really enjoy it.
If you are putting Go in the category of languages with a type system that doesn't suck, you probably need to study more languages.
Go has a few nice things going for it but its type system was clearly designed by people who stopped paying attention to type theory and compiler design in the late 90's.
Type system without even basic generics (even though the standard library needed them), never mind higher-level type constructs. Clunky special-casing of error-handling and concurrency, because the type system is not powerful enough to handle these in elegant ways. C-like simplicity but garbage collection makes it unsuitable for systems programming.
I think the popularity comes from a number of googlers using HN and upvoting related stories. A lot of go fans seem to be people for whom it's their second language after python (or possibly their fourth language after python, java and c++ - the only languages that google employees are allowed to use, AIUI). So they see a language that's more expressive than java, less crazy than C++, safer and more performant than python, and think it's the best thing since sliced bread.
There are some good things in go. An opinionated formatter that ships with the language is a great idea. Static duck typing is an interesting idea, though IMO less useful than either alternative - it means you can't do the equivalent of newtype, which is something you use all the time when coding in a properly typesafe language because it lets you catch so many errors. If you look at the scala community, there's a syntax for doing this... and almost everyone's agreed it's a bad idea. The concurrency model is... worth pursuit and I'm glad someone's trying it, though ultimately I think it will prove less practical than e.g. Erlang-style approaches.
It's not the worst language ever. But it utterly fails to live up to the hype. I've yet to find anyone who likes it having previously done a serious project in Haskell/Scala/F#/OCaml.
I personally am not a fan of Go, but I agree that it's a fine language that people are productive in.
Opinions about languages are going to vary a lot, and I don't think it's productive to debate this kind of thing.
I prefer languages with stronger, more expressive type systems, but I'll freely admit that I code slower (though usually more correctly) in languages like that. Some people prefer languages where they can easily hold all the language's syntax and rules and quirks in their head, and fire out code quickly.
All of that is fine. There's no objective truth there. I agree with the GP that Go feels incomplete. Before generics, it felt embarrassingly incomplete. But if you're fine and happy and productive with it as it is, that's great!
Go has absolutely zero interesting properties here. It has a shitty, inexpressive type system, dangerous concurrency, brain-dead error handling. It is a managed language, which provided memory-safety for many many decades now.
I initially really liked it. But the languages designers just skipped over countless years of achievements in language design and implemented a C with garbage collection, with interfaces and a baked in CSP runtime.
If you read a bit in the groups / release notes, they were just too lazy to implement generics. Or it was too hard.
Go's ecosystem is really weak (for example, barely any library does proper versioning or any release procedure at all).
I think that is at least part due to the difficulty of writing clean, generic code. And the lack of proper packaging.
The lack of features is not a selling point, even if they try.
Honestly this is really compelling evidence that Pike doesn't know much about type theory. That isn't terribly surprising, and the other early collaborators on the language that I know of also came from more of a systems background. I think its entirely likely that Go's crippled type system is partly an accident, and not entirely a design choice. It would be helpful if - with the benefit of hindsight - they would admit it, rather than invent post-hoc justifications for the way things are.
Go has some really great features, I've written a few thousand lines in it and enjoyed it, but there are some strange hangups that the go designers have that in the end make me think its going to go nowhere.
1. Rob Pike is immensely proud that the language has no generics, but this means that in the last 2 years, there isnt a proper implementation of a linked list that can hold an arbitrary type, or a min-heap, an ordered map, or a b-tree, or any one of countless data structures that one can take for granted in every other language. And yes, there are implementations that take interfaces, but you have to very odd-looking casts to coerce values in and out of them.
2. Go - or its testing support - doesnt allow a simple assert or EQUALS macro, simply because Rob believes everything should be done with if/then structures. Along with error handling, this makes go tests painful to read.
3. Idiosyncratic handling of pointers and values, leading to confusion everywhere and accidental copies and bugs where people pass by value accidentally because its extremely easy to.
4. Channels aren't really that useful beyond small programs (IMHO, maybe I'm wrong), and by making them synchronous any non-trivial go concurrent program has to reason very carefully to avoid deadlocks.
There are countless similar things. People will put up with these idiosyncracies for a while but move on in the end.
I have written a bit of Go. It strikes me as sort of the Unix of programming languages. It's very opinionated, takes some overarching concepts, mostly channels and interfaces, then proceeds to thoroughly not care what you think about it: refuses to have generics, lambdas and tail-call recursion like a pro. The polar opposite of design by committee. It even enforces a True Brace Style to keep the parser simple!
Technically, it looks good to me. The toolchain is excellent. It looks ready for production. Programming in it is fun. It fixes most issues of compiled languages. Go has mostly replaced Haskell, for me.
Yep. Every now and again I look into contemporary Go and try to give it the benefit of the doubt, but it just looks like intentionally going back to Java 5 [1] and touting the lack of features as a feature. What I find surprising is its apparent popularity among people who also like languages like Typescript and Kotlin, which go in the opposite direction, with high expressibility
To be more controversial, its flaws remind me of COBOL, both in the flawed belief that a lack of expressive power makes your programs easier, rather then harder, to read, and in the sense that both languages seemed completely ignorant of any programming language design ideas outside of their bubble, and just stayed stuck in the past
[1] As of 2022. Prior to that it famously didn't even have generics
Go is interesting because it has a cult like following of advocates who spout the same sound bites all the time, yet seem completely oblivious to the larger world out there.
Go seems to be in this weird space where it is not particularly suited for anything that its proponents say it is. As a systems programming language it gets a lot of flack for being garbage collected. As a web programming language, it is not ergonomic at all. The process of simply formatting a string is ridiculous compared to the string interpolation of Python or Scala. Furthermore,
if I was a web developer, why would I want to deal with the cognitive overhead of Arrays vs. Slices or pointers?
The type system also takes a lot of heat, mainly for generics but that seems like something that is coming soon to the language. Nevertheless, it is sort of telling that Kubernetes decided to implement its own internal type system instead of leveraging the OO paradigm provided by the language.
- No generics
- No true buy-in on the idea of a structural typesystem
- No sumtypes
- An anti-intellectual fanbase
- Exceptionally painful error handling
- Zero ability to abstract anything out without relying on the reflection package which leads to brittle and slow software.
They didn't do everything wrong though.
- It's great that they have a spec (I wish it came with formal semantics, but still)
- It compiles quickly and is easy to analyze (so tooling w.r.t. LSP is great and exceptionally fast)
Anyway, I never find programming in Go fun, and I find Rob Pike to be obnoxious. OK, that last part might just be me projecting how obnoxious Go is onto him.
EDIT: Fixed formatting.
reply