One thing for sure is that we are in the middle of a paradigm shift. I am seeing more and more codes blending OOP with elements of functional programming. Some OOP purists go as far as avoiding getter/setter and use DTO to allow data editing, which to me it looks like a separation of data and function in procedural programming. Whatever the latest trend is, we shouldn't let Go become another C++ by blindly following trends. Everything must be thought of carefully.
I was one of the generics supporters for Go in this forum, but now I am not so sure.
>> I am not saying that generics is bad, but I am questioning whether generics is necessary.Please, do not panic.If you worry about the following things:- Generated code will grow when used generics- Generated code will be more complex when used generics- Execution performance will slow down when used generics- Memory consumption will grow when used generics
The reason why I am no longer sure about my position in this issue is because -while I agree that generics is useful- I don't think that generics is essential. In fact, all of C++ features are useful and implemented in a very efficient manner, but take a look what happened when you slab that many features together. If you can do away with less, I think you should go for less. The trouble is deprecating language features is a lot harder than deprecating APIs in the standard library, while programming fads come and go.
>> increase in cognitive load to decipher chains of type definitions.Sorry, but who are members of this mail lists?This is a first time when I hear about such loads such as the `cognitive load`.
Also I am possible here a single person who does not know anything about the `cognitive load to decipher chains of type definitions`.
I am mostly business man and a programmer just for my own requirements.I love to implements parsers, code generators, some effective algorithms for solving some problem at the most effective time.Also my work includes a diagnose the failures and locate them.And I want to apologize for my illiteracy (thick-headed), but I do not really was expecting that all members of this mail list worry mostly about the ` increase in cognitive load to decipher chains of type definitions` and don't worry about other things.I am sorry.
--
I totally agree that I always want generics mainly when I am writing a framework. But I do not agree with you on that "go is pretty much a language for writing applications". I don't think go is powerful enough that we do no need any framework. I don't think we can always develop applications from the scratch.
And I do think it is a big help for go if we have a lot of frameworks/libraries right on your hand. I do think it is a waste of engineer time to develop all the tools from scratch. Currently there are many frameworks/libraries have to use a lot of reflections just because generic is missing.
This both makes the framework/library hard to use, slower, and less safe (a lot of runtime type checking which should/could be done at compiling time).
Think about how many people were asking: For the following types, how can I convert []Fool to []Barer, and via verse?type Barer interface { Bar() }type Foo struct{ ... }func (f *Foo) Bar() { ... }func Process([]Barer) { ... }We have to tell them write a helper function to convert it.
While in fact, if we have generic, and declare Process as:func Process<T Barer>([]T) { ... }we do not need this kind of conversions at all. Interface is perfect for abstraction of the direct layer, while it is not good enough for abstractions inside of slice, map, chan, and structure, especially for slices which are used a lot in go code. I think this is a very big requirement by the users who is writing "applications" as well.
The issue is, that a "KeyValuePair<K, V>" (no matter if you implemented it via generics or like you mention via interfaces) is a fundamentally useless type and generics encourage people to add useless types. A "KeyValuePair<K, V>" is a "struct { Key K, Value V }", plain and simple. It's not an interface and it's not a generic type, it's simply a struct.I agree, that generics are useful, but they seem to be mainly useful for people who write "frameworks", not so much for people who write "applications" and so far, go is pretty much a language for the latter. Whenever people try to justify generics, they do it from a "I want to write a framework" POV - and whenever I miss generics, I do because I'm currently writing a framework of some kind.
Generics empower abstractions, but most programmers are very bad at building abstractions, so if you make it easy to build abstractions, you will end up with a lot of bad abstractions (have a look at java). So, to a certain degree, the value of go is, to *not* make building abstractions overly simple. That leads to abstractions being used only where they are essential and being left out where they are superfluous. This is where reduced cognitive overhead comes into play - limiting the levels of abstractions that people need to deal with to the bare essentials. Java is bloated and hard to use, not because the language is bad, but because it has a history of programmers building bad abstractions into it which gets stacked on top of each other. So, yes, if you compare a bad abstraction using interfaces with a bad abstraction using generics, generics will, in general, compare very well. But you just shouldn't build the bad abstraction in the first place.
The second concern with complexity is the spec. The exact behavior and semantics of generics need to be spec'ed and useful generics need a lot specification. For example, the current rules for type inference can be understood completely just by looking at a single expression and it's type and it's correspondingly simple to implement and spec. Generics usually need more powerful type inference methods to not be cumbersome, which will take up a lot of space in the spec. As humans, just like computers, have very little memory, the time it takes to understand the spec will grow superlinear with the length of it, due to frequent cache misses, so a long spec will significantly increase the time needed to learn the language. In the same vein, to understand a language, you need to know about interactions between it's different concepts, not just the concepts itself, so the needed space and time complexity to learn a language also grows quadratic in the number of concepts in the language (in general). All of that contributes to why people are wary of adding new concepts to go - the costs in terms of understanding and learning the language are huge and they grow very much superlinear in the number of concepts added, so each added concept must be carefully examined (I know go for years and I still learn new things about interactions between different concepts all the time).
I sometimes miss generics, yes, but I also believe adding them will make the language significantly harder to learn and will significantly worsen the quality of go code in the wild, so it would likely eliminate the reasons I like go currently (which is that go code is usually of exceptionally high quality, uniform and easy to understand).