Do you mean, "this feature is required for me to write code in that language"? Or do you mean, "this feature is required for any project in the language to flourish"?
If the former, why do you think your preferences generalize? If the latter, how do you explain the large number of successful Go projects? Are we all stuck in the 1980s? And if so, what does that even mean?
Frankly, yeah, I think Go programmers are kind of stuck in the 1980s in some respects. This isn't something I'm completely clear about, but I feel like Go's developers are biased against anything that smells at all academic. So for instance they didn't want to implement a super fancy, cutting-edge type system. Which is somewhat understandable... but as a result they ignored 30 years of programming langauge research and implemented a primitive type system that basically provides nothing over C. I do not understand this mentality.
Writing that sort of clever, super-concise code scratches an itch that a lot of people have (myself included) but it's not something I want to encounter when I'm trying to debug something. When you're working with other people's code, you want it to be simple and consistent. That's what Go's primary strength is.
btw, I'll take this opportunity to plug my own "Go generics" solution: https://github.com/lukechampine/ply. It's like a Coffeescript for Go that lets you use stream HOFs like map/filter/reduce without any runtime cost.
> but as a result they ignored 30 years of programming langauge research and implemented a primitive type system that basically provides nothing over C
As someone who also has a decent amount of C experience, I don't see how this is a reasonable conclusion to make. The first point in favor of Go is that it's mostly memory safe (sans data races), which is achieved not just with bounds checks, but with a stronger type system. The second point in favor of Go is that Go does have a limited form of polymorphism that is checked by the compiler. In C, the only way you get polymorphism is by subverting the type system entirely. Both of those points are huge, and there's undoubtedly a much longer list that I could craft of smaller benefits if I were so inclined.
As we march toward complex type systems that move more runtime errors to compile time, we must also be vigilant of the trade offs we're making. Moving things from runtime to compile time isn't necessarily free; there's almost always some new cognitive load that is implied. It's important because if that cognitive load is "too high," then people aren't going to switch to it, and no amount of navel gazing is going to fix that. This entire thread is a perfect demonstration of that trade off in action. On the one hand, we have the "clearly superior" Rust approach to error handling that checks a lot more at compile time than Go does, but on the other hand, Go programmers don't ever need to "learn error handling" at all. They have a simple convention with a reasonably low bug rate (IME, anyway).
We can't just judge programming languages by their theoretical strengths. We must also judge them by their practical strengths. And then we must do the impossible: balance them. Snubbing our collective noses isn't going to do any good. Our only hope is to understand why people are attracted to languages like Go (such as myself) and figure out how to reduce the aforementioned cognitive load without giving up those sweet sweet compile time checks. Rust is clearly pushing that boundary, and I'm happier for it.
The lack of generics in Go simply means that you will for common algorithms and functions end up with either of these scenario's:
1. You were forced to duplicate code under a different name with a different type signature (even though the body would be identical)
2. You are forced to use the 'empty interface' which negates the advantages of static type-checking (and seriously: why isn't it the default when you open an accolade?)
Not having generics in a statically typed language means you combine the disadvantage of static typing ('having to specify types and doubling the cognitive complexity of the language with a special type syntax') with ('not having the compiler be able to check the validity and risk run-time type errors, ie. things like cast exceptions').
>If the former, why do you think your preferences generalize?
Generics is not a platonic ideal such as 'object oriented programming'. Type systems are as solid as math itself. And just like Math there are multiple systems with different trade-offs in how expressive they are. This expressivity is not subjective! One type system can be strictly more expressive than another type system. Consider this pseudo-code without any type annotations:
def example(a,n)
return a.something(n)
In a dynamically typed language such as Ruby, Erlang, Python or JS there are programs that would call this method that would make it throw an exception during run-time. For example because it doesn't know how to do '.something' on the provided argument.The challenge: It barfs during run-time and we want it to barf during compile-time.
Now imagine all the possible usages of this method in a dynamically typed language that would be provable correct. All the potential combinations of a's and n's that would not make it barf. How many of them are legal Java, Haskell, C# or Go programs? (some, most, some, few)? The goal of a static system is to barf during compile-time. Not to exclude valid, legal programs just because the language author thinks type systems are hard to implement.
Whenever you can write provable correct code, that a type-system is complaining about: how is that not a bug?
>If the latter, how do you explain the large number of successful Go projects?
1. The projects are successful because of the people who make them
Well for starters by not assuming that people who program in Go are completely incompetent drooling idiots who are only able to deliver working code because Go is so great. As if the same developers wouldn't have successful projects right now, if Go didn't exist.
2. Any language released by a famous language author at Google will get a large minimum cult following by default
Much like with Angular who releases something has a strong impact on the adoption, regardless of the actual quality of the product, language design or implementation. I'm convinced the same set of programmers would be more productive in other languages. I'm also not surprised they themselves aren't aware of it.
3. Go has nice competitive features, the type system just isn't one of them.
Finally, Go isn't all shitty, for example, it has a very nice IO and concurrency model and ever since it finally got a precise garbage collector, one could finally use it long-running processes.
4. Your logic has clear type errors that a strong type system would help you catch
The existence of successful Go projects isn't an indication of _anything_. With the same logic you could argue VHS is superior to Betamax or that that Kanye is a talented musician. It's like the Silicon Valley variant of religious logic of 'moral people don't get sick'. Sometimes people, projects or products are not successful because they did everything the right way! Sometimes they just get lucky. Sometimes they just plain conspire against civilisation and cheat. Sometimes the things they did correctly ended up being more important the the things they did wrong. Sometimes they just get to announce on a bigger stage than somebody else.
> Are we all stuck in the 1980s? And if so, what does that even mean?
It means that there has been a large research initiative since the 1980's in software verification but because science is hard and thinking is hard and we are all getting paid anyway, we rather prefer to cargo-cult, bike-shed and gloat about our own ignorance. Because what you haven't learned yet is hard and what you already know is easy, even if it's all wrong.
It doesn't help that most of the academic researchers don't care enough about engineering to turn their research into actual production tools (with a few exceptions).
But i'm starting to warm up to the common notion that all progress in programming language design comes not from people learning, but from generations of developers eventually dying of old age. There is just too much money to go around for developers to not act like spoiled ignorant little children, and as a result most technology is just fundamentally broken and for no good reason.
Personally, I think a lot of the language you chose to use in that giant wall of text was quite unfortunate. I'm not interested in being a party to your ax grinding.
That said, personally I'd love to have generics on top of that. Consequently, I have been following some of the discussions on the topic, and so far I haven't seen anything suggesting that the language developers have an aversion to it. What they do have, however, is a fear that an improperly designed generics concept could badly screw up the language in a way that can't be reversed by any practical means once it is launched.
They are basically very careful about adding stuff, without fully understanding the consequences at all levels. You (or I) can disagree with that approach, but it's not accurate to say that they have an aversion for generics, or even to say that they don't want it.
The fact is that Go is the only statically typed language, with any claim to being mainstream, that doesn't have generics. And it's not like generics are some kind of a new and radical concept. Java had them for 13 years now; C# had them for 12. There's literally millions of lines of code written in popular languages that utilize generics, which can be used as a guide to proper design, and understand its consequences.
The idea that there needs to be more "baking time" for generics simply doesn't hold water at this point. It amounts to insisting that structured programming (loops etc) should not be adopted "without fully understanding the consequences at all levels", and meanwhile we'll just use if+goto - in 1980.
I don't think their crux is so much that generics "as such" needs more baking, but the specifics of how to implement them with the Go language. Mind you that some of the core goals of Go is to be simple, easy to parse, fast to compile, support good tooling, etc. so the question they're battling with is how to add generics to that mix without sacrificing any of those goals, and without making some mistake you can never go back from once every code base out there starts depending on it.
Now, by all means, we can argue that those priorities are wrong, or that yours would have been different. But I think it is disingenuous to suggest that they are effectively idiots who don't understand how to apply basic concepts, or are unaware of other programming languages.
That's false. Go provides a smattering of blessed polymorphic types (slices, maps, chans, pointers) and functions (len, append, delete, chan send, chan recv) that go a long way. They are horrifying to civilized PL enthusiasts, but they cover a lot ground.
As I said in one of my sibling comments, navel gazing isn't going to get you anywhere. And Go isn't the only statically typed language without generics. C has that designation as well.