The is more often untrue, than it is true. There are times when the low latency GC is beneficial though.
The is more often untrue, than it is true. There are times when the low latency GC is beneficial though.
Of course “fast” is relative, but I would reserve it for languages that are nearly as fast as competitors in their segment. There are too many languages very similar to Go’s ergonomics that are much faster for us to meaningfully call Go “fast”.
That said, I don’t really think that’s a problem. I think people who use Go are often just happy it’s faster than Python, and that’s okay.
My personal dislike of Go comes simply from their unapologetic[1] embrace of default nullable pointers (the “billion dollar mistake”[2]): There is very strong theoretical (and practical) ground supporting the approach of Rust/Zig/Swift/etc’s (to use algebraic data types instead) as objectively better (yielding inherently more reliable results with virtually no ergonomic compromise[3]).
In other words, in the 21st century, we know how to design statically typed languages that guarantee the impossibility of null dereference exceptions (not counting bugs in external libraries from other languages). And we can do this without any runtime performance or code ergonomics compromise!
Therefore there are no good excuses anymore for any statically typed language in the 21st century to not provide this extremely beneficial guarantee.
[1] There are no plans to fix this, ever: I’ve seen entire articles written by members of the Go team not just defending “all pointers are nillable”, but encouraging this as an idiomatic Go style of coding.
[2] https://www.infoq.com/presentations/Null-References-The-Bill...
[3] The ergonomic difficulties of Rust come from the borrow checker, not from their use of algebraic data types to replace nullable pointers.
I also agree on the problem with null pointers with is really ridiculous. Another complaint that I have about Go is how for some reason Google decided to implement many web protocols in the standard library, but never really cared to get websockets right, to the point that they just sedn you to a third-party library from their own documentation. That + QUIC/HTTP3 make me want to take my tinfoil hat out from the drawer.
Though all dynamic allocation happens by resizing predefined arrays.
It feels like a real step backwards using languages without parametric enums. My litmus test when learning a new language involves porting across some plain text operational transform code. The go code came out about 40% larger than the rust and swift implementations for this reason. It was also much uglier and harder to read. Like, those extra lines were pure overhead.
Eg this rust code is beautiful: https://github.com/josephg/textot.rs/blob/bb14b4b483e7dace67...
And that’s prettier and about as performant as this C implementation of the same function (I think I somehow lost the Go code - but it wasn’t much better than this): https://github.com/ottypes/libot/blob/902470a22d3a99d9b776ce...
The equivalent javascript code (my go-to language!) is larger than the equivalent swift / rust code and, last time I checked, about 8x slower. Most of the gap in readability is this one beautiful feature!
In my experience C# is a great language by nature, but riddled with foot guns, bloated libraries that love doing runtime reflection and other organizational problems that typically surround the development process.