No immutability. Nullability by default, and weird corner cases like nil slices and interfaces. Language semantics requiring weird stack discipline that is incompatible with normal ABIs, and causes overhead when you need to interop.
But frankly, just the design of append() alone should be a warning sign. If it were a low-level facility, fine, it's only needed to be understood by whoever's writing a library to wrap it for general consumption. But it's the idiomatic Go way of maintaining a sequential mutable collection! How is such a basic operation is so non-obvious that people still write articles to explain it, and so verbose that you must reference the collection twice to make it work right?
(Indeed, the language itself kinda acknowledges how clumsy it is, by making it an error to ignore the return value of append(). But, as usual with Go, it's hardcoded - i.e. you can't do the same for your own function. And IIRC, it wasn't there from the get go, but got added somewhere along the line.)
But frankly, just the design of append() alone should be a warning sign. If it were a low-level facility, fine, it's only needed to be understood by whoever's writing a library to wrap it for general consumption. But it's the idiomatic Go way of maintaining a sequential mutable collection! How is such a basic operation is so non-obvious that people still write articles to explain it, and so verbose that you must reference the collection twice to make it work right?
(Indeed, the language itself kinda acknowledges how clumsy it is, by making it an error to ignore the return value of append(). But, as usual with Go, it's hardcoded - i.e. you can't do the same for your own function. And IIRC, it wasn't there from the get go, but got added somewhere along the line.)