> Go - in my opinion - fails to carve out a novel niche of the PL scene, that would have some legitimacy of existing.

People love to bash C++ and try to replace it day and night. Go is not trying to be "the next step" in programming. Its promise is simple. C, reimagined, for relatively simple tasks. Plus it adds some batteries: green threads, a GC, modern utilities like JSON, HTTP, flag support, better portability out of the box, integrated testing, etc.

In short, it's a better C, written in the spirit of UNIX/Plan9. I didn't expect a cutting edge, exciting, "knocks my pants off" language when I started using Go. It's a mundane tool to be honest, and I prefer boring technology for myriad of reasons.

It's designed to be boring, to get the job done. Not to excite people with cutting edge stuff, and this is the novelty of Go. A collection of mundane ideas combined with care, resulting in a superior experience with no surprises (for the most part).

> In what way? Please don’t come with the usual marketing that “every line is easy to understand...

No, not in a line by line basis, but in project scope. See, Go is a simplistic language. You can't do "interesting" things with it much (e.g.: I love auto-tokenization tricks in C++ iostreams, but it needs an innate understanding how "<<" works in C++ universe). This means there's no hidden "magick" under the code to unpack. As a result, the written code is shallow, transparent and boring. When you open a Go project you don't know, reading it is easy. Because there are no tricks. As a consequence, when you don't think of tricks, but of simple utilities and function calls, the state you keep in your mind becomes smaller.

This results in two things. 1) You can see the whole picture with less energy, resulting in better architectural awareness, 2) You can resume a project much faster, because there's less context to load from memory and code structure. I resume my paused Go projects under 10 minutes. Which is fast.

> Most AOT languages do that

Compilers eliminate dead code, correct, but it lives in your codebase nonetheless. "No unused variables and no unused imports" make you remove the dead code from the codebase too, resulting in a leaner codebase with less head scratches. Less complex codebases means less bugs, more understanding, and faster work. See my previous point.

> It’s literally C’s errno forced on you by the compiler. I hope we can agree that C’s solution is very far from what one would mean by good error handling.

Personally I have no qualms with errno based error handling (and no qualms with exception handling (try/catch and friends)), plus Go's errors provide more context, because error is an object carrying much more information w.r.t. an integer. Also, it makes error handling a must, and skipping over error handling voluntary. If you use "_" instead of error and do not handle it, it's on you now. You had the chance and you skipped it. I think it's a pretty neat mechanism: "You knowingly opt out handling a possible error, and it's your responsibility now. Roll with it". Everybody says that "safety must be on by default". It's Go's safety, and it's on by default. Accepting risks is programmer's own choice.

> That’s only a problem in C and C++.

No. I can leave dead assignments in every language I know, and while it might be eliminated by the compiler itself, it's again cognitive load on the codebase maintainer. See my previous points.

> Also, I don’t even agree it does a good job at it, it basically has multiple nulls for example for no sane reason.

Every language has its peculiarities for "no sane reason" for some people. OTOH, some other people think the reasons for these peculiarities are sane and well justified.