> 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.