> Rust and Scala are designed for other use cases than yours

This has become a sort-of gotcha for any discussions that involve comparing programming languages, but I think it has been over-extended beyond what is reasonable. It is true that some languages are much better at certain use cases than others, and especially if you consider their ecosystems when making this determination. For example, I don't feel Go makes a very good programming language for desktop applications or games, and there are some use cases where it is either not a good idea or flat-out non-viable due to limitations of its design.

However, I think the complaint of "intellectual masturbation" is definitely not invalid on these grounds. That's a far more general (and vague) complaint about language design. It's one thing to disagree with this assessment, but this counterpoint doesn't really address the assessment, it's just dismissing it.

That said, I do think that complaining of "intellectual masturbation" is still rather shallow. I think that if you were to compare the personalities of people who prefer Go vs people who prefer Rust you would find that the language design choices are not just intellectual masturbation, but they do reflect the priorities and mindsets of the people who design and use the language.

And that said, I think you could also make the argument that Rust has made some very costly decisions in the language design department to uphold its ideals. This does hit me when using Rust: It's not that there's anything wrong with it, but it absolutely 100% makes me appreciate where Go decided to cut the scope. Flat-out ignoring invalid UNICODE filenames may mean that Go is not suitable for programs that simply must deal with bag-o-bytes filenames gracefully, but on the flip side it sure does simplify just about every downstream decision regarding filenames. You can see this pattern repeat throughout the language. In some cases Rust goes through great pains to meet the ideals of those who love the zero-cost abstraction, but it does hit some awkward points. A point that I am always bringing up is the lack of the ability to directly allocate heap memory in safe Rust. With features like const generics, it's tempting to reduce indirections and flatten fixed-size buffers into your structs and so forth, but it's very easy to find yourself in a stack overflow if you do so, depending on the platform's default stack size. OTOH, I appreciate that in Go you don't really need to worry about a stack overflow, but Go's design decisions around the stack and goroutine do add some overhead to making C calls and stack allocations, which is a vastly different trade-off than Rust makes.

I'd say Go programmers can be categorized by the fact that many of them, myself included, actually like this pattern:

if err != nil {
return nil, fmt.Errorf("...: %w", err)
}

In Rust, you'd no doubt prefer to use one of the many error crates that cut down the boilerplate (somewhat, anyway) and let you use strongly-typed enums for your errors. I know I do this when using Rust, but the Go mindset is very different.

I think both mindsets have value, and it's not surprising that people see Rust as intellectual masturbation to some degree, whereas people see Go as mindless boilerplate a la Java. Both assessments are too simple, of course. Rust feels like it will pay as much cost as it takes in the language complexity department to solve the problems they want to solve as fully as they can. Meanwhile, Go feels like it will spend several years trying to decide if adding a single major language feature is really worth the added complexity, and I think there's a zen to that. I don't think the answer is that they're built for different use cases, and their use cases freely overlap plenty; it's more like, they're built for different mindsets, and some of the use cases just wrap around that.