> It's true that having value types in addition to reference types (while other GC languages often only have reference types) adds some complexity to the language, it's not much and it's still much less complex and error prone than other GC languages. Also, C# has value types and Java desperately wants them, so I think it's pretty clear that they're worth the extra bit of complexity.

My point was
not about value types, but about taking the address of some thing; neither C# (except the extremely rarely used `unsafe` subset) nor planned versions of Java have this ability. To be fair though, C# does have something somewhat equivalent - lambdas may capture a local variable such as a loop variable, in which case you do need to know if each iteration creates a new variable or changes the value of the same variable. Java doesn't allow this at all. Even in C#, you can't capture a part of a structure, so the complexity is more limited.

There are other aspects to Go's complexity as a language - multiple syntaxes for declaring a variable, multiple other ways of declaring constants, iota, named return variables, function scope VS local scope, the limits of what can constitute a map key, what kind of structs can be compared for equality,special syntax that looks like multiple assignment but isn't, and probably others. My point is that Go is not a very simple or consistent language. Java for example is still simpler. C# is more complex, but more consistent.

> I don't see why every language should have a build tool that can build it + small bits of other languages. A build tool should build that language well, and extend it for bigger projects using a wrapper tool like Make or Bazel depending on use case. Unix philosophy and all that.

The reason is tracking dependencies. If I have a pure Go project, I can rely entirely on modules to manage my dependencies. If I need one python package, I now need to find a new tool to declare my dependency and orchestrate things. With Maven, for example, I can just export the python package as a Maven module and keep using Maven for my entire build.

To me, a dependency management system that is strictly language specific is only useful as a starter tool - almost certainly, once you are working on a real project, you will drop that tool entirely and have to use soemthing else, as dependencies are a cross-language problem.

That said, it is nice to have a dependency tool available as you're getting your feet wet, so I shouldn't really be complaining that Go offers this.

> Every language (even C++) needs another compiler to compile C code before it can be called into. And once it's compiled, it's no more difficult to call into it from Go than from Java or C# or Python or etc.

First of all, I must admit that I was wrong about how Go handles CFFI. I was under the wrong impression that cgo is an alternative to the standard go compiler, and that you have to build your program with cgo instead of go build in order to be able to link to C code. Since I now understand that cgo is simply a tool to generate the necessary boilerplate to interoperate C and Go, you're right, it's actually much nicer than what Java or Pyhton offer. Note, I am aware that you need a C compiler to build your C code; I just thought that there are 2 Go compilers, one for pure Go, and a different one for Go plus dynamic linking to C.

C# is still simpler, since it doesn't need any external tool or C compiler - you simply declare the C# headers for the C functions you want to invoke, and annotate them to declare the shared library they should be searched in, and the CLR handles the glue for you.

---

There were a few other points, like gofmt where we simply have different experiences and I don't think it's productive to argue. There are others where I had misunderstood you as claiming Go is especially good at, and I understand your point was simply that it checks those boxes, which I agree with.