1) It's performant. The language itself is very fast, the GC is very fast and go routines make concurrency fast.
2) The tooling is great. Once you have the Go CLI installed, everything else "just works." Cross-compilation is super easy. Install dependencies is easy. Generating code is easy. Embedding files is easy. The ecosystem is really mature. Modules are easy to create, export, and import. Compilation time is fast. The list goes on...
3) The generics system is amazing. It beats any system that implements generics with type erasure.
4) The language itself is very easy to read and write.
5) The language is relatively new, which means less outdated cruft. The language also puts an emphasis on having only one way to do things.
So comparing it to other languages:
- Python: Terrible tooling. Not performant
- C# Bad tooling (do I need .NET, .NET Core, Mono? How do I create a project? What is this crazy project xml file? How do I export my project to be consumed by others? How do I import a dependency?). Also, as an older language, it has a bit of cruft, e.g. it has optional types, but they also aren't required? Maybe if I knew more about C#, I would find it better. But using it with Unity didn't leave a great taste in my mouth.
- JavaScript: not performant, especially in multi-core environments.
- Rust: Rust is too hard to write. It's not worth the overhead if you can afford a GC.
- C++: Same as rust, + more foot guns and unsafe memory management.
- Zig: Don't have much experience with Zig, but I'd like to.
- Ruby: Not performant, not typed.
- Swift: Tooling is bad. Compilation is slow. Cross-platform is not a priority. Swift Package Manager is buggy. Using Xcode sucks.
- JVM languages: bad tooling (maven, sbt, gradle are all a pain), generics have type erasure.
Of course, there are reasons to use other languages. If you’re writing an iOS app, the tooling for Swift is best-in-class. Or if you’re doing ML, the ML-specific ecosystem in Python outweighs all other considerations.
addresses := persons.map(func(p Person) Address {p.address})
Actually what I really want is
addresses := persons.map(p => p.address)
But I understand Go doesn't allow that level of readability.
Say you have a list of classes and want to pull out certain fields. With immutability as default and easy map functions many people write something like this:
a = my list.map(e => e.foo)
b = mylist.map(e => e.bar)
This may or may not matter performance wise but I think Go has a strong culture of of making something like this easy vs writing a for loop that does everything in one go.
3) Besides C#, which languages doesn’t have typed erases generics? Most languages implement it through erasure. Also, Go’s generics are basic as hell..
4) Not sure about write, read.. deeply nested for loops, error handling taking up place everywhere, literally more verbose than even Java
5) it has plenty of hard-coded shit already, due to missing generics for a huge time (e.g. built-in data types)
Javascript is quite performant, but I have to agree on concurrency.
JVM languages: I don’t think it has bad tooling at all, and it is fucking performant (with much better GCs).