Go puzzles me. It's slower than C/C++/Rust and GCed, so not really suited for performance critical stuff. No OO so not really suited for larger complex applications. So for smaller not-performance-critical programs, why not Python, Typescript etc? It seems that its popularity exceeds its scope, or am I missing something?
The same can be said about Rust: its popularity exceeds its scope, because 99% of applications I see that are written in Rust are better off written in a GCed language.
As fast as C but with correctness, Rust kind-of owns that space (not a big fan personally).
> Rust kind-of owns that space

True. But it's a pretty small space to be in. And there are good reasons for that:

a) The only correctness Rust can, mostly, guarantee, is that there won't be unexpected data races or memory bugs. While this is proudly announced often and loudly, it also isn't the most common problem in code...logic bugs...against which the rust compiler can do as little as any other language.

b) Rust can only give these guarantees because it is ALOT more complex than C. That means harder to read, harder to write, harder to learn. And developer time matters. Alot. If I can already ship features, while my competition is still stuck in onboarding, it won't matter if my code has the odd memory bugs...those can be fixed...I will already have the market to myself.

> a) The only correctness Rust can, mostly, guarantee, is that there won't be unexpected data races or memory bugs. While this is proudly announced often and loudly, it also isn't the most common problem in code...logic bugs...against which the rust compiler can do as little as any other language.

A powerful type system helps quite a lot with logic bugs actually.

> A strong type system helps quite a lot with logic bugs actually.

A static type system does, and all the languages that Rust has to compete with in its space, have one.

Go's type system is much less expressive and it has null pointers. An entire giant class of bugs.
> Go's type system is much less expressive

Please, do explain: what does "much less expressive" mean, in technical terms? What specific data modeling can I not do in Go, and what specific bugs can be caused by that?

> and it has null pointers

Yes, so? De-Referencing a null pointer in Go crashes the program, making the bug very obvious. Go made the choice to have null pointers (which do exist in silica), and avoid the complexity of languages who pretend that null pointers don't exist.

It's a tradeoff, and a very good one at that.

> What specific data modeling can I not do in Go

You're getting into the Turing tar-pit. There's nothing you can do in Rust you can't also do in Go, technically. Hell, you can do it all in Brainfuck too, if you so desire.

The big thing, though, is ADTs. Being able to say "the value is one of 3 possible values" is a lot easier than saying "here are three values, you should use the non-zero one".

> You're getting into the Turing tar-pit.

I am fully aware of that. My question is, what specific technical problems are caused by Go not having {feature_goes_here}.

> The big thing, though, is ADTs

Except it isn't a big thing, because for the few use cases where an ADT is actually, really, really, REALLY required, they can be expressed in Go using existing language features.

https://go.dev/doc/faq#variant_types

https://eli.thegreenplace.net/2018/go-and-algebraic-data-typ...

Quote: "It seems that Go can do just fine without adding variant types, due to the challenges mentioned in the beginning of the post and the ease with which the major use-cases can be implemented using existing language features." End Quote

On the one hand, yes, this is more verbose. On the other hand, these use cases are simply not frequent enough to justify making the languages syntax and type system more complex.

Again: Yes, Go lacks many features of other languages. That is on purpose. The language is made to be simple, as in "easy to learn, easy to read, easy to refactor, easy to generate, easy to maintain large bodies of code".

That link shows the Go type system's lack of expressiveness. You have to manually include things like the default case. Rust's compiler will do exhaustiveness checking for you, and you can't just forget about it.

Also, it's not about ADT's being required. They're preferred, and Go's type system suffers for their lack. Go is a living, breathing example of the blub paradox in action.

> That link shows the Go type system's lack of expressiveness.

And I ask again what that is supposed to mean in technical terms, and what specific problems would be prevented if Go's type system was "more expressive".

> They're preferred

I am fully aware that for every given language feature, there are people who prefer that feature. And many languages reacted to that by including everything and the kitchen sink. That made many languages very "expressive", but that expressiveness comes at a cost: It also made the languages themselves become bigger and more complex.

Go isn't about having as many features as possible though. Quite the opposite, it's about having as many features as necessary, and as few as possible. Why? Because it keeps the language small and easy to learn and the code easy to read and maintain.

And to me (and judging by the sucess of Go I am not alone in this), that is a lot more important than a bit more "expressiveness" in things that one may come across every now and then.

What it means in technical terms is what I just told you: Rust's compiler will not let you forget to handle an enum variant. Go's compiler can't do that because the type system can't handle it.
> Go's compiler can't do that because the type system can't handle it

Correct. And that isn't a disdvantage.

The fact that Go's type system "cannot handle that" directly in it's type system (functionally, the language itself can handle that easily enough, as shown by the article I linked above) is a choice, which results in a simpler language.

And I still haven't seen any specific problems that would be prevented if Go included this feature directly in the type system. I have, however, seen a lot of extra syntax that Go doesn't need to support in its compiler, Go students don't have to learn, and Go devs don't have to worry about.

> specific problems that would be prevented if Go included this feature directly in the type system

I keep telling you the specific problem that would be prevented. You can't forget to handle an enum variant. That is a specific problem that is prevented in Rust, but not Go. And no, the language doesn't "handle that easily enough".

Update an enum in Rust with a new variant? Your code won't compile until you've updated everywhere that matches against it. Do something similar using the technique you linked in Go? Good luck, hope you don't introduce any bugs by forgetting to handle it somewhere.

Easily handled by adding a linter. Like you pointed out, that's an easy place to make mistakes, and this regularly catches them for us https://github.com/nishanths/exhaustive