The Case Against Third Party Libraries (2014)
blog.gopheracademy.com
blog.gopheracademy.com
This doesn't contradict much of what the author writes: it really is true that two different versions of one library are actually two different libraries; it really is true that sometimes copy-and-paste is better than generalising (when the cost of being general obscures the meaning of the code itself); it really is true that many libraries should just specify and implement an API, then stop.
The issue with libraries in versions in Go could probably be resolved with a more flexible import syntax. It'd be sweet to be able to write 'import foo.invalid/bar@94d0ef312881e694ded9ff38e33a2c07fb398eb8' and know that I'd always either get the exact version that I specified. It'd be even cooler to have some way to specify 'I want the latest version of library X which offers the exact API I'm using'; in principal this would be possible by calculating some deterministic ordering of the used, exposed API and hashing that, but the details would be tricky (as an example, consider a case where Foo() and Bar() still exist, with the same signatures, but in version 2.0 Bar() can only run properly if Baz() has been called previously—there's no way in Go to express that sort of contract to the compiler.
It has a nice effect where every change to a library requires a commit which can trigger a build. There are no hidden updates.
With Ruby I can 'bundle update', run the tests, and have reasonable certainty that everything's working. If I took over a Ruby project with vendored gems I'd mark them all for replacement for standard Bundler-managed gems at first opportunity. Vendored code has a bad tendency to become 'unmaintained code' otherwise.
Just because it works and is stable doesn't mean it doesn't have security vulns.
Well, the problem is that Go is a bait/switch . It has enough goodness to make someone enthusiastic about it at first place. And then when one finds out that the language has major issues , one has two way to deal with things : denial or giving up on Go. Go is a niche language , its "community" will always be very protective of what Go is no matter how much flaws it has, because this community isn't really in control of the language anyway. This is a top/down governance, with the Google team at the top, and there is no debate what soever. There used to be but as I said earlier people that are not satisfied with Go have been shut down in the mailing list (or by silly processes imposed by the go team when it comes to contribution or feature suggestion ) and moved on.
Should be output to the screen in BLINKING ALL CAPS on every invocation of rubygems and npm.
The ideal utility would look at a Gemfile.lock and show changelog information to help the developer evaluate which libraries can be updated immediately, which require some code/api review, and which will require refactoring.
What is the version of the library go get has fetched one month ago ? you don't know ? and you will never know.
The problem therefore is not 3rd party libraries that can break. The problem is the tool go use to get dependencies doesn't help you with something like that.
Therefore all this "a version of a lib is a different lib" is a straw-man masking the real issue with go get. In every other modern language ,there is no such issue.
Dependency problems are one of those.
Two gem needing a specific version of a common gem immediately bind their upgrade paths together for the life of your application. Without including version numbers in go get, it forces those 3rd party libraries to be backwards compatible. Some people like that.
We have a node/gulp-driven build with, ultimately, about 500 dependencies. We don't store node_modules with the code, we run npm install with each build. This leads to periodic failures because some sub-sub-sub-dependency bumped number 3 when it should have bumped number 2, causing unwanted build-time behavior. Even if our package.json lists specific versions of top-level dependencies instead of ranges this will happen. It's aggravating.
Projects exist to bundle up known-good node_modules and restore at build time to avoid this. NPM offers the concepts of shrinkwrapping and peer dependencies so you can tell consumers which specific version of each runtime dependency they have to use as well. IMO if SemVer actually worked in practice, none of this would be necessary.
Some of this is an indictment of node/npm - maybe Ruby is just better - but I still think SemVer is overestimated.
The standard library is pretty nice, but one of the reasons for that is that it is a well tested well supported backwards compatible library. It would be nice if there were more of those.
All of that while preserving the feel and idioms of the host language. This is key since it invalidates a lot of prior experience with similar APIs.
So until the "right" API coalesces from collective experience with the problem domain and APIs for similar libraries (read and display {TIFF, GIF, PNG, etc.} in $LANGUAGE) backward compatibility is not a feature you want.
Wait for the second or third wave of libraries where the problem is solved and understood in a nice idiomatic way for the language and its quirks.
If the author is legitimately concerned about code bloat from the unused parts of a library, Go's linker needs to get a lot smarter.