A copy of the comment I posted on the author’s blog

I agree that generics are very useful when writing reusable libraries, but I disagree they are absolutely necessary when writing and maintaining software at large scale. At large scale, at some point, processes communicate with other processes on the same machine or over the network, and you have to marshal/unmarshal and type check at runtime.

Your example with the function isInt64InSlice is a good illustration of why the lack of generics is annoying at small scale, but it hardly shows why this is a problem at large scale.

PostgreSQL is an example of a complex piece of software, written in C, which doesn't use generics and is still very readable and maintainable.

A few other technical points:

- "Cannot add methods to types from a different package": Would you want something like extension methods in C#?

- "Channels are slow": I've read there is some work going on to improve them. That said, you admit yourself that Go is still one the best option among the "concurrent" languages. Are you aware of another language with a similar mechanism builtin in the language or the library and that performs better on this matter?

- "Accidental implementation of an interface": I agree this a problem in theory, but in practice it's very rarely an issue. Have you been beaten by that often? Do you think the benefits of implicit implementation are not worth it?

- "Cannot implement your own exceptions": Yes you can. You can pass some value to panic and retrieve it upper in the call stack with recover and decide what to do depending on the value. It's not something Go developers do often, but there is some use of this technique in the standard library for example. It's explained in "Effective Go".

- "Map returns a bool instead of an error": I don't see the issue here. A lot of other languages do the same and return a default value and/or a boolean at false when you probe a map with a missing value.

- "Adding an item to a closed channel panics": This is a programming error, like a division by zero or an out of bounds array access.

- "Channels as iterators": Goroutines and channels are not designed to build iterators. They offer a general low-level mechanism for concurrency. How would you expect the goroutine to know that nobody is listening anymore and shutdown?

About the community, I would not call it "stubborn". In my experience, it is generally helpful and very professional. But I agree that the topic of generics has become a taboo, which I regret. It looks like the core team wants to focus on improving the compiler, the runtime, the library, the tooling and the garbage collector, and because of that wants to keep the language stable in the meantime. I understand the frustration, but don't you think their decision makes sense and is the best way to use the limited resources of the core team?

You wrote that "a language can have considerable depth while still retaining its simplicity". What languages would you recommend that solve the flaws of Go while preserving its simplicity (in terms of user experience)? It's a sincere question. I'd like to use such a language.

More generally, you ask how can we make developers more productive and how can we enable them to solve problems? That's interesting because this is precisely the question Go tries to answer. Are you sure the answer lies in a more powerful programming language? What about the runtime, the tooling, the libraries?

The Go team thinks the answer lies in simplicity (light syntax, garbage collection, interfaces, composition over inheritance, builtin arrays/slices/maps), builtin concurrency (goroutines, channels), great tooling (speed of compilation, go test, gofmt, godoc), easy deployment (no virtual machine, static binary).

Do you think the answer lies in having type parametricity, algebraic data types, pattern matching, immutability, Hindley-Milner type inference, higher kinder types, etc.? I'm not saying they are not useful or desirable. I'm just saying that the low hanging fruits in terms of developer productivity may be elsewhere.