It seems the root problem is that interfaces and concrete values occupy the same semantic positions. But that's way too hard a problem to fix; if I had a magic wand to update all existing code I'd probably just have `== nil` on an interface check for both kinds and try to rescue transitivity.
The whole "confused about nil interface vs. interface containing nil pointer of some type", while I would contend has a root cause of improperly importing the idea from C++ that nil is automatically invalid when in fact it is perfectly valid in Go to call methods on nil and thus confusing "nil" with "invalid", is at least a cause of real bugs and real misunderstandings.
If you are looking for the perfect language may I suggest Forth on a Z80? Otherwise there's going to be a pile of shit hiding somewhere.
1) The language lacked hindsight in its domain because there wasn't a ton of prior art (C)
2) The language didn't have enough foresight put into it (JavaScript)
3) The language's modern usage has drifted significantly far from its original usage (Java)
Python is an example of a language people use that doesn't suffer from #1 (thanks to Perl and friends), doesn't really suffer from #2 (at least, Python 3) and doesn't (yet) suffer too badly from #3. It has plenty of flaws and limitations, but not in its foundation. The core language primitives are rock-solid.
#1 doesn't apply to Go, and it's not old enough for #3 to apply. So that seems to only leave #2.
(I should add that this doesn't make a language completely invalid or useless. I use (and even like!) JS despite its flaws; in fact I prefer it to Python overall, mostly due to the ecosystem. It's just disappointing to see issues of type #2, because they seem so avoidable.)
Your C example is also not convincing. Lisp and Algol were already strong contenders at the time. People chose C because they needed a fast and close to metal language to create their own operating system for mainframes. It was a hack just like your category 2. Still, it's a great language.
> It's pointless discussing this
I don't see how the first implies the second. This is a programming forum; it's good to discuss and debate the specifics of these things.
C may not have been the best example of the category, but I think the category stands. Rust for example, much as I love it, is exploring uncharted territory. I wouldn't be surprised if 10 years from now we have ownership-based languages that are much easier to use, simply because lessons will have been learned by that point. Arguably Java's OOP fundamentals are not as good as C#'s because Java had to explore that territory first (setting aside technicalities about what the term "OOP" really means). Etc.
I'll recommend Reddit's r/ProgrammingLanguages, as well as Scott's Programming Language Pragmatics as a reading instead. It's not fully up-to-date but I found the comparisons of features and their trade-offs in it fascinating.
So it feels like you're trying to draw some distinction here that is like, "look, nil isn't really that special - there's groups A and B, and the core confusion is people think nil is in group A while the truth is in it's group B." And it's true, Go has both typed and untyped constants.
But as far as I know, nil is the only untyped constant without default type. So "group B" is still just nil, and nil remains a sui generis source of confusion in Go.