
The Case Against Third Party Libraries (2014) - adrianmacneil
http://blog.gopheracademy.com/advent-2014/case-against-3pl/
======
veeti
The Stockholm syndrome shown by Go users in things like this is just
incredible.

~~~
zeveb
I think I agree. There are a _lot_ of great things about Go, but (currently)
library versioning is not one of them.

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.

~~~
dradtke
Honestly, with the release of Go 1.5, I've taken to using "go get" once to
download the library, copy it over into the vendor folder, remove its .git
folder, and commit the whole thing to source control. It's easier than messing
with version numbers or commit hashes, and more stable than always using the
latest master.

~~~
cakeface
I really like this approach and it reminds me of the approach that Google
takes with their versioning. Everything in one giant source repository.

It has a nice effect where every change to a library requires a commit which
can trigger a build. There are no hidden updates.

~~~
vinceguidry
It puts you in the driver's seat of dependency managing, but now you have to
be a lot more careful to actually update them when the time comes. If you tend
to put something into production and leave it there for months / years, coming
back to do maintenance will be a real chore.

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.

------
infinity0
> That’s when I realized that a library with 30 versions is actually 30
> separate libraries.

Should be output to the screen in BLINKING ALL CAPS on every invocation of
rubygems and npm.

~~~
brightball
As somebody who spends a lot of time on a 100,000 line of Ruby monolith with
upwards of 50 dependencies...I support this.

~~~
aikah
the thing is it doesn't matter since a gem file and lock file will tell you
what is the version of the library you are currently using.

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.

~~~
brightball
It matters because of inter-dependencies between all those gems. I'm not
saying it's "the way" but Go's popularity is almost entirely due to solving
problems that people experience in other modern languages.

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.

~~~
aikah
Go doesn't solve that, at all , in fact Go doesn't solve anything at all ,
thus the need for a proper package management solution in Go.

------
nulltype
StableLib [https://stablelib.com/](https://stablelib.com/) seems to be taking
an interesting approach to libraries. Go guarantees backwards compatibility
and it's awesome for developers. Why shouldn't libraries have the same
guarantees?

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.

~~~
acveilleux
It's pretty much a given that the first few libraries solving problem X will
have a sub-optimal API, especially if they aim to be both general (say read
and display JPEG) and full-featured (support all the optional bits of the
format or work efficiently in low-memory embedded situations, etc.) at the
same time.

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.

~~~
nulltype
Perfect is the enemy of good I guess. If I'm building a product now, I want a
library that works well now and never breaks when I upgrade to the latest
version. If someone gets a great idea for a better library, make it a separate
library. So backwards compatibility is definitely a feature I want.

------
alexcasalboni
"Ctrl-C, Ctrl-V"? This is so wrong...

~~~
pbreit
Wrong as in unethical or prohibited by common licensing? Or just your opinion
of the tactic?

~~~
alexcasalboni
It's just against every software engineering best practices. You find a
library which implements what you want/need? You don't copy&paste 10% of it
into your repository just to make sure it won't ever brake. What if it's
broken already? They will fix it and your version won't be updated. This logic
is not even ok with your own code, why should it be promoted with somebody
else's code?

