The relative lack of "dependency hell" in golang compared to other languages is because of the great standard library. Golang also never had an official/proper (imo) solution for package management until just this past year or so (although people worked around that a bit)
I like the generics proposal, but it seems like a valid concern.
Note that this comment is not advocating for or against this proposal or generics in general; it just took me a few re-reads to understand the concern and I hope to save others some time. :)
IMO I think having a standard library that judiciously used generics would be almost pure upside for most Go programs. Being able to do math.Sin(x) instead of float32(math.Sin(float32(x))) just seems like an improvement in every way.
I also remember reading some one said their Software has increased complexity due to Go's Simplicity. ( Or something similar along the line )
It really is a balancing act. And it seems there is no one size fit all solution.
Which way are you meaning this. The way I read it was that because GO was simple, we were able to build more complex systems. But you seemed to indicate that was a bad thing?
Yes making complex that can be made simple is the way you want to do things, but some things simply are not simple, and thus require complex software.
Every time I have seen complex GO code and investigated how it got that way it was simply the result of one of the following. 1) Writing GO code before fully understanding the language. 2) Trying to write GO code like it was some other language.
I have seen some crazy complex GO in my days, and after spending hours and hours of trying to figure out what the code was doing -- I have always been able to simplify the program to a nice concise bit of code -- and I can assure you there are much better programmers out there than me.
Often the complexity is people trying to implement generics in some crazy round about way, or have prioritized dependency injection, or code coverage test to a extreme.
My favorite example of this is https://github.com/rdadbhawala/dutdip -- and here is a good talk on it https://www.youtube.com/watch?v=HBLJV0cPRBM
The code base that implemented this in production is an amazing mess, I can assure you of that.
Going from assembly language to Go (increasing language complexity) decreases code complexity.
Stated a different way, would removing a feature from Go (say Goroutines) necessarily make a Go codebase simpler? If so, then I have to question why they added it in the first place.
Maybe your statement could be defended given enough context and caveats, but the overall relationship between language and code complexity is clearly more... complex... than you imply.
I predicted at the time that people would take away the wrong conclusion—"dependencies are bad"—from the left-pad incident. Sadly that prediction seems to have come true.
The more dependencies you have, the more likely you are to get one that's going to cause a problem down the line, be it due to conflicts with other libraries, subtle bugs that take years to manifest, or someone deleting something from upstream package manager (as was the case with left-pad).
Take crypto code. Which do you trust: a homebrew implementation of AES-GCM because nobody wanted to add a dependency, or libsodium?
However, I think the reason that people got upset over the left-pad thing was because it was a library that most engineers could write fairly easily, without adding in another failure point.
If you rely on the the language/platform's built-in libraries, typically the amount of wheel-reinventing you are doing boils down to writing simple wrappers, without adding in another external point of failure. These libraries are typically more production-hardened than something you'd find on NPM or Maven or Nuget.
Leftpad was a problem with a particular package management system, not with code reuse. It's true that avoiding code reuse is a way to avoid package management problems, but it's kind of like the way decapitation is a way of avoiding mental health problems.
What I mainly took away from the left-pad incident was that if people will add dependencies for code that is so simple that it takes less than a minute to write(1), then what else will they add dependencies for? I was a bit surprised at the sheer poor engineering judgement involved in adding massive amounts of dependencies so carelessly when they were so fragile as they proved to be in NPM.
Raise your hands those who check all dependencies before every release? Did you look at all the change logs? Did you check for issues, security vulnerabilities, or that it may be time to upgrade to a newer version (or not)? Did you follow all the transitive dependencies and do the same? Do you routinely evaluate each dependency with an eye to replacing it? No? Yes?
Using known good implementations that you know to be maintained, is good. Overdoing creates new problems. Making a culture of it creates a community of fragile, ratty code.
Dependencies are bad if you overdo them because with scale problems tend to morph into new kinds of problems.
(1) You usually do not need to do all of what left-pad does. Usually you need one specific case. And once you have done it a few times (for a few different cases), it becomes like a kata you can write in seconds. It is much faster than adding a dependency. Not least because adding a dependency actually means you should spend enough time reviewing the dependency - in depth the first time, and perhaps just checking the change logs or commit logs on subsequent versions.
As with most things - it is a trade-off.
I’m more worried about eccentricities in the implementation that we’ll get out of the golang team. Then again, maybe we’ll be pleasantly surprised.
I primarily program in Go. While I think often HN makes too big a deal of Go's support for generic types currently being (more or less) limited to slices, maps, and channels (those go pretty far for a lot of programs, especially when combined with interfaces), I don't get the passionate anti-generics attitude this post seems to have attracted either. I'm wary of architecture astronauts just like everyone else, but I think at least the Go team could probably use generics judiciously in the standard library in way that would benefit most programs (like using sync.Map without casting to interface{}, or doing math on float32 without needing to do float32(math.Sin(float32(x))), etc).
In those worlds you're more likely to move data between logical units in JSON or Protobufs (both of which Go is good for) than to need proper generics so I don't understand the push from this subset of the community.
As far as container types and data structures, look at the number of well built storage solutions that don't seem encumbered by the lack of generics at all like: boltdb, bleve, BadgerDB, InfluxDB, etc.
Maybe we could port some of those ideas to other languages so that Go programmers will feel at home :)
Fast compile times, already being enjoyed by many with Turbo Pascal for MS-DOS, or Object Pascal for Mac OS, among other languages with similar support for modules.
Godoc, javadoc did it first.
Gofmt, indent was one of the first and every IDE has done it since ages.
Other languages already have those ideas.
You rarely know all of your requirements up front, and walking back a language change a year or more into your project is almost always prohibitively expensive. At that point, you find yourself with a handful of equally-bad language-hybridization options. One of Go's objectives is scalability--as Go projects mature, they should not find themselves boxed in by the language. In the case of generics specifically, you have a slightly better option than language hybridization or changing languages outright which is generating generic code, but that's only slightly better (because now you need code generation built into your CI/CD pipeline which is inherently worse than a naive generic type system implementation and it also imposes a high cost on all clients of your generic code, since they will also have to adopt your same generic build system as the standard Go toolchain isn't your-generic-build-system-aware).
The generics proposal hints that the design is reminiscent from Ada generics. Well its first standard was released in 1983.
So, people switch to new simpler languages. The way you remove things from a language is to create a new one.
Then these new simpler languages become popular, and then people want their critical favorite bit added. And eventually the language is no longer simpler. And people switch to another new language, and the cycle repeats.
Because we couldn't convince people to just use the existing complex language if they want that. Because, really, this is all a struggle to influence other developers. These days it's not enough to work the way that is best for you, you need to find ways to harness a critical mass of other developers, and at the same time contain the mess and damage that a huge number of miscellaneous developers out in the world can do to your ecosystem.
It kinda sucks. Where possible, I like to use older, less popular, more minimal: libraries, frameworks, tools.
One of Go's core strengths is simplicity. I've personally witnessed both C and Python programmers jump right into Go projects with minimal assistance. Learning new packages is absurdly easy because the code is so simple and documentation practically generates itself. I worry that widespread use of this feature would negatively impact the language in that regard.
Lacking a true "generics" feature has had an influence that people tend to overlook, which is that the Go community is less reliant on dependencies. One of Go's proverbs is "A little copying is better than a little dependency" [0]. The ecosystem is better documented and healthier because of it, avoiding the require("left-pad") world of the dependency abyss.
The language lends itself to being used for smaller, more concise code bases where things are written with specific and narrowly-defined purpose. It implicitly discourages "Architecture Astronauts" [1] and that strength shouldn't be overlooked or sacrificed for a few new container options.
[0] https://go-proverbs.github.io/
[1] https://www.joelonsoftware.com/2001/04/21/dont-let-architect...