The Go community freely acknowledges that generics are a nice feature, and that lacking them is a pain point of Go sometimes. Although many Go developers will tell you that sometimes turns out to be not that often in reality, which has also been my experience.
The bottom line is it's not a feature that comes for free, and if most of the time you don't really need it, maybe the costs aren't worth it. That's a bold statement for a programming language these days, since generics is a central feature of every popular, modern, statically typed language. Whether they are right or wrong I won't attempt to say. The language may well get generics one day, but it's early days still and the team is rightly focusing on more important features for the moment.
That really depends on what you mean by "most of the time". After all, you only write a generics based library once, and you reuse it many times - therefore on the outside it appears that you don't really use generics all that much.
In my opinion, depriving a "normal" language user of generics is like depriving a Lisp user of macros. Whatever it is, its definitely not just "bold".
I've done most of my Go programming on library code. A sync library for relational databases to sqlite (for mobile devices) and an embedded database. Lack of generics has bothered me a little, but copy and paste with a multiple-cursor editor really makes short work of it. I think the worst part is really our natural aversion to code duplication and the ugliness of it. e.g. having to write min/max for integers is pretty ugly (although not as ugly as converting your ints to float64 and using the stdlib min/max.) However, I spent more time thinking that it was ugly than writing min and max. Sure it's ugly, but programming is not art, it's engineering, and Go is a language for engineers.
> I think the worst part is really our natural aversion to code duplication and the ugliness of it. e.g. having to write min/max for integers is pretty ugly
Sometimes ugliness is a sign that something is designed incorrectly, especially if the language aids in making that more visually evident.
> (although not as ugly as converting your ints to float64 and using the stdlib min/max.)
Not to mention incorrect.
> it's ugly, but programming is not art, it's engineering
Not mutually exclusive. A good language would make incorrect or inefficient code "ugly" or "uglier" than correct code.
> and Go is a language for engineers.
So are languages with generics like C++, Java, Rust, Haskell, etc.
Plus all those dynamically typed languages which are intrinsically built on the concept of generics (JavaScript, Perl, PHP, Python, Ruby). /sarcasm Nobody uses them because nobody needs generics.
They are intrinsically built atop generics. Duck typing is row polymorphism. Dynamic languages often depend upon that flexibility to operate—and they enable it by allowing everything. Static languages without polymorphism are at a low point in that trade-off space since they restrict useful operations and provide no way to express the invariances needed to recover that flexibility.
I never thought people will actually come up and defend code duplication. It's definitely more than ugliness. The need to fix all the copies when they need to be updated is a bigger problem.
It's fine that you don't agree with our tastes, but it would be nice if you could stop coming into every Go thread and being condescending about it.
Like PostgreSQL and OpenBSD, I've been permanently turned off Rust because I never want to be left at the mercy of a community that invests so much time in harassing and insulting others.
Please tell me where you've been harrassed and insulted by the Postgres community? Sometimes people come into the IRC channel and say something that doesn't make sense and are told it doesn't make sense, and sometimes those people get very upset, but I wouldn't classify that as harrassment. And that's basically the strongest reaction you'll ever get from anyone in the community.
Any active comments thread related to MySQL attracts a derailing holier-than-thou invasion telling us how dumb we are for not using PostgreSQL. PostgreSQL's advocates haven't quite reached the arrogance level of Oracle DBAs, granted, but they're a lot more active.
I basically stopped using (public) IRC somewhere around 2000. I have little idea what goes on in PostgreSQL's IRC channel(s). I expect it's toxic, but I'd expect that for any project's IRC presence. Public IRC is an inherently toxic medium.
That doesn't sound like anyone I know of who actually works on PostgreSQL, and certainly not anyone I'd consider part of the PostgreSQL "community." The mailing lists, IRC channel and other forms of community communication are much more hostile to Oracle than any other RDBMS, and anyone who tries to start a flamewar there (particularly one about MySQL) is instantly shut down. I'm really sorry that you've been turned off from great technology by the actions of some overzealous Postgres users.
Except, I also talk good about Go in what concerns using it to replace C, specially in possible uses for real systems programming in a GC enabled language.
After all, when compared with the first Oberon version, Go only needs a few more primitives in runtime and unsafe, Kernel and SYSTEM in Oberon respectively.
This is what attracted me to the language in first place.
Agreed! But what this means is that when you decide not to apply DRY, you need to have a reasonable justification. Code duplication in general is a bad thing.
Now you are shifting to a editing dilemma. Code duplication is not machine code duplication which is what really matters at execution time. Reading is also easier (even for non-Go programmers at least familiar with C) without templating-like syntax.
Machine code duplication is spending a few extra megabytes on perfectly valid, if duplicate, machine code.
Source code duplication is a risk of spending an hour, or maybe a day, of developer's time to detect the duplication, change it in concert in several places, with an occasional need of detecting and fixing a subtle discrepancy between the copies.
RAM is $0.015 per megabyte. Developer time is $50 per hour.
You could also spend that developer time trying to untangle code reuse between various components, or the more subtle breakages caused by changes that don't account for the expectations of all callers. Code reuse is still a tradeoff.
It should be noted that generic code is harder to break. It is, by definition, less entangled with its callers. There are also fewer operations you can do with generic parameters, so there are fewer ways to screw up.
Code duplication is definitely a programmer problem, not a machine problem. It's also a major problem. Code duplication increases the probability of programming errors, and makes maintenance harder. Any modern language with poor tools for keeping duplication at bay is suspect.
"My editor makes it really easy to do this terrible thing, so it's okay!"
I'm sorry, I quite enjoy many aspects of Go - but the argument that committing one of the cardinal sins of programming is okay because your editor makes it easy is worse than the actual language shortcoming itself.
Code duplication is not a cardinal sin of programming. In fact, the attitude that it _is_ has probably done more harm to [modern] programming than duplication ever did :)
Sorry, I meant to say that the language's shortcomings, even if temporary, start to attract a wrong attitude, which is sad (and you, golang team, should feel sad).
Correct me if I'm wrong but doesn't the current state of affairs (using Interface{}) have all the downsides of Java's boxing but without any of the type safety?
It reminds me of the wonderful fun days of Java 1.2 - anybody remember how proud Sun was of how everything derived from object so you could use the untyped containers for everything?
The main difference with casting to Object is that you can use type switches or safe casts which return an additional success boolean, to restore type safety quickly after taking the item out of its container. Yes, you can type-test in Java before you type-cast, but it isn't idiomatic, and it isn't syntax.
Which leads to writing the same code repeatedly--because trying to wedge in reusability via insufficiently expressive structural typing is entertaining but often fruitless--and making the user wonder why they didn't just use something modern (setting aside stuff like Scala, even C++ can do channels, and past that the reasons for Go start vanishing real quick).
I write go 40 hours a week and have been for over a year. There's been only a couple times I wanted generics and those are structures I haven't actually needed to reuse yet. I'm not guessing about not being generics much.
Edit
That being said, go is not for all projects. Some projects need a lot of generics. Don't use go for that.
Um, I've written Go. Nontrivial amounts, as it happens. In doing so, I recognized that I was regularly forced to write worse code in the pursuit of doing things idiomatically because I lacked the semantic richness of C++, let alone Scala. And this worse-is-better attitude of the Go community gives me a dim view of its future--and between its junk GC and its completely pedestrian semantic and syntactic propositions I already had a dim view of its present.
If you write reusable, future-facing code, generic types without the erasure of interface upcasting is required. There are no two ways around it.
It sounds like you were forced to write/maintain some Go code and are basing your opinion on that, an opinion heavily colored by the quality of the original code and your annoyance at your employer for making you work in something other than your preferred language(s).
It's even possible the software you were tasked with writing/maintaining was a bad fit for Go. I tried to mention that in my previous response. Such things certainly exist, and most Go enthusiasts will be more than willing to admit it.
However, saying you can't write reusable, future-facing code without generics is preposterous. To refute you, all I have to do is point you at the Go standard library. A huge body of code whose purpose is purely reuse, and not a generic to be found.
Or perhaps we could look at the thousands of reusable go packages found on godoc.org.
You don't like Go. That's a perfectly acceptable stance to take. But I don't think you've really given it a fair shake, either.
> If you write reusable, future-facing code, generic types without the erasure of interface upcasting is required.
You're entitled to your opinions, but this is a patently false statement. There is plenty of C code currently running on my machine that was written decades ago and is still actively maintained.
> And this worse-is-better attitude of the Go community gives me a dim view of its future
The Go community actively embraces Worse-Is-Better. If your opinions are well formed enough that you know you want nothing to do with it, then what is your point exactly? Yeah, you hate Go because you hate Worst-Is-Better. So what?
> You're entitled to your opinions, but this is a patently false statement. There is plenty of C code currently running on my machine that was written decades ago and is still actively maintained.
You're right. Sorry. You can do it by enacting a fair approximation of stapling your eyelids to your hairline. I apologize for not being exhaustive.
> The Go community actively embraces Worse-Is-Better. If your opinions are well formed enough that you know you want nothing to do with it, then what is your point exactly?
That I've had more than one long night dealing with an inherited Go application and it sucks and its developers should feel bad.
(OK, the last is mostly facetious. If they can't be bothered to use modern tooling, though, they should be tasked with maintaining their own crap...)
Go is a language for people who write servers. It is really really good for those uses. Look at Docker, etcd, Kubernetes, Juju, Cloudflare, Soundcloud ...
And probably a ton that are internal to a company and not really exposed as a user-facing "Go Application™" (like the stuff behind google's downloads service, some of youtube's metadata processes, etc etc).
I think the fact that early on in Go's life someone called it a "systems language" really confused a lot of people. It's not a systems language. It's just a language. The channels, goroutines, and standard library happen to be really useful when writing networked servers.
Second, it already has been discussed multiple times that it only focus on C++, C#, Java approaches while cleverly forgetting generics implementations exist in multiple forms since CLU (1974) introduced them.
But Go advocates take that page as dogma and toss it around every time a generics discussion comes up.
The problem is that the code that needs generics is reusable abstractions in libraries. Thats probably 1-3% of code but it is also critically important and there is no convincing workaround.
The Go community freely acknowledges that generics are a nice feature, and that lacking them is a pain point of Go sometimes. Although many Go developers will tell you that sometimes turns out to be not that often in reality, which has also been my experience.
Rob Pike has outlined the tradeoffs inherent with generics here: http://research.swtch.com/2009/12/generic-dilemma.html
The bottom line is it's not a feature that comes for free, and if most of the time you don't really need it, maybe the costs aren't worth it. That's a bold statement for a programming language these days, since generics is a central feature of every popular, modern, statically typed language. Whether they are right or wrong I won't attempt to say. The language may well get generics one day, but it's early days still and the team is rightly focusing on more important features for the moment.