> What about tools that statically analyze your code and allow you to be more productive? It may be possible to build more sophisticated and useful tools if the language is simple.
This is a thing that's commonly repeated, but it's not that, well, simple. Having a simple syntax doesn't matter that much for tools once you have a reusable parser library.
More important for tools is having a simple semantics. Do all builtins behave the same way? Is nil handled consistently (e.g. does indexing a nil map do the same thing as indexing a nil slice)? Are the coercion rules simple? Is importing a package free of side effects? (The answer to all of these for Go, unfortunately, is no.)
The most important thing, however, for tooling is whether the language provides static guarantees. For instance, if the language controls access to shared mutable state, you can do a lot to detect races statically. As another example, if panics were part of the type system, then you could statically know whether functions panic and, if so, what types of panics can happen. Here, Go provides very few static guarantees: it's very difficult to soundly prove anything interesting about Go programs.
Unfortunately, you can't really have it both ways: you can have a more dynamic type system that doesn't put many constraints on on programs, or you can have interesting static tooling. Go chose the former in nearly every instance.
But given the reality I observe, Go has already the top-tier tooling regarding IDE support and we are still waiting for the first production-ready RLS. Not that Go has the fanciest IDE products in the market or those tools have been invested heavily for Go, but it is obvious to me that such tools are abundant in the Go ecosystem that can be readily employed by every editor vendor. To put it in an ironic way, assuming same popularity, I think a quality language tool for Rust has more potential to be monetized (just like those for C++) than those for Go, because the former has much higher barrier to entry and hence less competitors.
We aren't talking about autocompletion. The post upthread describes "the tools to ensure...data integrity": i.e. type system or static analysis features to prevent bugs.
That said, if you're trying to argue that autocompletion is more difficult to implement for Rust compared to Go because Go is simpler by some metric, then I disagree there too. Any static language (well, one that doesn't intertwine parsing and semantics like C++ does) can support autocompletion with comparable levels of implementation effort.
Then I am curious about what makes RLS or the alike so hard to onboard? Common IDE features like reliable and responsive "jump to definition", "Find all references" and "Renaming symbols" are 90% of all I would ask for. Do Rust devs have less attention to the area?
I don't know. I have a hunch that lots of macros still will be better with the new macro system, but we'll see.
Anyway, regardless, there's certainly more work to do! And it's being actively developed quite heavily. For example, it will be on stable Rust very soon.
This is a thing that's commonly repeated, but it's not that, well, simple. Having a simple syntax doesn't matter that much for tools once you have a reusable parser library.
More important for tools is having a simple semantics. Do all builtins behave the same way? Is nil handled consistently (e.g. does indexing a nil map do the same thing as indexing a nil slice)? Are the coercion rules simple? Is importing a package free of side effects? (The answer to all of these for Go, unfortunately, is no.)
The most important thing, however, for tooling is whether the language provides static guarantees. For instance, if the language controls access to shared mutable state, you can do a lot to detect races statically. As another example, if panics were part of the type system, then you could statically know whether functions panic and, if so, what types of panics can happen. Here, Go provides very few static guarantees: it's very difficult to soundly prove anything interesting about Go programs.
Unfortunately, you can't really have it both ways: you can have a more dynamic type system that doesn't put many constraints on on programs, or you can have interesting static tooling. Go chose the former in nearly every instance.