I'm new to golang, but i've had bad experiences with it so far compared to other languages.<p>- method declarations are hard to grep for because the related struct appears before the method name (like "grep 'func String'" will not find "func (s <i>Struct) String"), and because a module's types/functions can be declared across several files<p>- many pointer-related footguns, many others have mentioned the nil pointer exception issue, but as a newcomer to golang i found it confusing that i could accept value params in methods/functions and mutate those params... only to have those mutations silently discarded because they were a copy of the original data to start with<p>- do you even concurrency?! i ran into a deadlock by using the stdlib in a very simple way, in a sequential manner, in a single-threaded program. i still have no clue why that is, and the program maintainers don't either. i'm probably doing it all wrong, but it was so easy to shoot myself in the foot. If someone more experienced wants to teach me what i did wrong, here's the code: <a href="https://github.com/ooni/probe-cli/pull/989#discussion_r1032585034" rel="nofollow">https://github.com/ooni/probe-cli/pull/989#discussion_r10325...</a><p>- the module system is entirely broken: i've had the go command </i>panic* on me for simply using "go get"... the problem is old and well-known, and has quite a few tickets open on the golang bug tracker: <a href="https://github.com/golang/go/issues/47979" rel="nofollow">https://github.com/golang/go/issues/47979</a><p>- the attributes exposed by marshaling libraries are different from one library to the next... i mean that's a problem in most languages but after trying out serde.rs briefly i feel like that should be the way in every language to just standardize those fields<p>- golang is not structured for commenting out parts of the code to test something quickly: unused imports/variables is a compilation error, and apart from naming a variable "_" there is no way to ignore its usage (using "_" as a prefix like in rust would be an awesome addition)<p>- struct declaration and instantiation has inconsistent syntax: why would i use comma after a field instantiation but not after a field declaration?<p>- the difference between ":=" and "=" is clunky... as you refactor code you end up having a lot of this variable doesn't exist, or this variable already exists kind of error... i understand the need for proper variable instantiation and type declaration in general, however ":=" does neither as you require an entirely different syntax (var) for explicit types, and golang is very happy with passing around nil/empty values<p>- publicity based on case makes it super hard to decide later whether you want a method/field to be public because you need to change the entire API, instead of simply adding a keyword<p>- no standard way to define default fields for a struct? there may be one but across all libraries i've used so far there was weird NewStruct() or NewDefaultConfigStruct() methods which were hard to grep for in the docs/code<p>All in all, it's not the worst programming language i've used. JavaScript is a lot worse. But from a week of working with it full-time, i feel like go has massively failed at being a better C or a better Python... it feels to me like it combined the failure modes from both ecosystems into a new rather incoherent language.<p>If you're looking for quick scripting, i would still recommend Python or PHP which in my humble opinion have much better developer UX. If you're looking for serious systems programming, i would recommend Ocaml, Rust, or plain old C, all three of which have amazing tooling. It may be weird to recommend C as an alternative to golang, because C is so low-level it's easy to shoot yourself in the foot... but that's the thing, C does not try to pretend to be a safer high-level language, it gives you raw tooling. golang tries to be higher-level but i think it failed at that.<p>Sorry for the rant, i don't mean to be rude. I just don't understand the hype around golang.