Oh I can expand on that if you want, though I expect you don't and you'll just handwave it away as is usually done of criticisms of Go.
* Go uses a special syntax for multiple return values, this is a restriction on the more general concept of tuples. Go could simply provide tuples instead of having MRVs be a syntactic special case. This makes the language smaller and simpler: instead of `,` being a magical syntactic feature of the language, it's just an operator for building tuples.
* Go has generic types, but only for blessed types implemented directly in the interpreter (map and channel, for instance). All user-defined types are second-class citizens at best. That's elevating special syntax to new heights.
* Go has two different initializers in `new` and `make`, `new` is garbage as it only allocates and can't be used to initialize and `make` only works with (again) a restricted number of types living directly in the runtime, which get to have special treatment for the only reason that new is insufficient.
* Talking about things only builtin types get, only builtin types get to be indexed via an operator, this is special syntax dedicated solely to builtin types.
* `defer` and `go`. They feature special magical evaluation order (they have to be a complete expression, all inner expressions are evaluated immediately and the outer one and that one only is not evaluated) which leads to weirdness like creating an anonymous function and calling it immediately, and they're not actually needed due to Go having anonymous function in the first place, both could be builtin function taking a callable instead of being special forms and they'd work just as well (better in fact, since their evaluation model would be the same as everywhere else in the language). These special cases are even weirder when you realize that `recover`, which needs to hook deep into the interpreter and do actual strange stuff to stop the stack unwinding in place, is a builtin function rather than a special form.
That should be a good start, 4 clear-cut examples of special syntax (either unnecessary or which could/should be general) and one of a special case.
Here's some kneejerk devil's-advocate responses to some of your points. As an idealist I generally agree with you, but I can see practical arguments against many of your nitpicks:
* Having first-class multiple-return as part of the specification allows compilers to generate stack/register allocated return values. If the comma operator were a tuple-constructor, then every multivariate return would be a heap-allocated structure, which might have significant performance implications. (I don't know if the Go compiler actually takes advantage of this on any architectures, but the possibility is there.)
* Agreed. Go's way is perhaps simpler, but definitely limiting.
* Here I think Go does things entirely wrong. I actually like that `new` only allocates, because it lends itself to designing very minimalistic and elegant data structures, something that I feel gets out of hand in many large programs in other languages. Being a GC'ed language, I'm OK with the idea of just exporting and documenting some static initialization functions along with the type. But that begs the question of why `make` exists, since it is basically a first-class syntax feature for initialization of the magic builtins that need it. Consistency, please.
* This is pretty silly, I agree.
* I can see definite reasons why the evaluation order of `defer` and `go` should be as they are. Here's an example use case: I want to defer a statement to print the current value of a local variable. If defer took a callable, then the only way I can see to do that with Go's current syntax would be to (1) define a function that closes around my variable and returns (2) an anonymous function that calls fmt.Print(myvar), and (3) evaluate the original function with the local I want to close around. If you allow more syntax alterations, I suppose you could properly generalize to something like C++11's lambdas where you explicitly state those variables that you want in the closure so that you only need to write one anonymous function, but that is complicated as all hell. The 90% use-case here is `defer Close(abc)`, so even needing the syntax for one anonymous function feels more crufty than the occasional `defer func() { ... }()`. I much prefer Go's way of just saying "We will close around all of the parameters to the outermost function" because it is wayyyyyy simpler.
Your whole post is unnecessary and unwarrantedly condescending since all you do is state "truths" like:
> Go is chock-full of special syntax and cases, and Go code is full of cruft
just like that, out of thin air.