It can be easier to maintain a small amount of code that you duplicate and check in and is purpose-built to your use case and treat as your own, compared to a general library imported for one routine that you have to think about (licensing, upgrading, auditing). Or sometimes libraries break backwards compatibility to add features you aren't interested in, and it makes busy work to stay up to date.
> Is there no package pinning solution?
Multiple dependency managers have supported pinning since at least 5 years ago e.g. glock, dep, glide. Go Modules supports pinning.
> Pinning is the solution for avoiding breakage due to dependencies
Related to the first point, in general you have to do work to upgrade your dependencies. If not because you care about bug / security fixes that happen, then because you use ANOTHER library that has the same dependency, and that other library uses a feature only present in a newer version. Any time you upgrade a library it takes work to verify nothing has broken, and potentially work to fix things that do break.
> It can be easier to maintain a small amount of code that you duplicate and check in and is purpose-built to your use case and treat as your own, compared to a general library imported for one routine that you have to think about (licensing, upgrading, auditing). Or sometimes libraries break backwards compatibility to add features you aren't interested in, and it makes busy work to stay up to date.
The overhead you're talking about isn't a real problem in my experience, as long as your dependency manager has semver support (all of those I know).
When writing (or copying from SO) a simple snippet that's supposed to do just what I want, almost 80% of the time there will be a bug in it (typically edge cases are not covered)…
For instance, before Go 1.10, there was no rounding function in Go's std lib, and 99% of the code you could find on the internet to do this (simple) task was buggy: some failed with negative numbers, and others due to bad handling of floating point numbers…
> It can be easier to maintain a small amount of code that you duplicate and check in
> compared to a general library imported for one routine that you have to think about
IMHO, that's why small, one-utility-function libraries in the JS ecosystem([0], [1], [2]) are useful. (Unlike the general tone in HN where npm and left-pad gets a lot of hate.)
Look at Quickutil[3] for examples of other languages. (In this case, Common Lisp.)
My current mayhem is containerizing an object detector pipeline/system with dozens of gigabytes of dependencies. The main dev has pulled in a library that makes opencv look like small potatoes, just to be able to use a whopping two functions. Apart from the misery that is a 4 hour container build every time something breaks, someone upstream broke my implementation (python 2, because ROS, ugh) with a casual '@' for matrix multiplication.
Yeah I love DRY and code reuse as much as the next guy, but sometimes copypasta makes sense.
I will say go's nature and/or culture make grafting in functions a lot easier.
One thing I omitted in the response which might be relevant is that usually you can only use one version of a package in any given build[1], so you have to use a version that works for everything that depends on it.
I think that might be a difference for folks coming from other ecosystems.
[1] The asterisk is that you can have multiple major versions coexist using Go modules, or you can use gopkg.in import paths, or some other workarounds, but in my experience that is not common and typically you do have to find a single version that works for your whole program.
It can be easier to maintain a small amount of code that you duplicate and check in and is purpose-built to your use case and treat as your own, compared to a general library imported for one routine that you have to think about (licensing, upgrading, auditing). Or sometimes libraries break backwards compatibility to add features you aren't interested in, and it makes busy work to stay up to date.
> Is there no package pinning solution?
Multiple dependency managers have supported pinning since at least 5 years ago e.g. glock, dep, glide. Go Modules supports pinning.
> Pinning is the solution for avoiding breakage due to dependencies
Related to the first point, in general you have to do work to upgrade your dependencies. If not because you care about bug / security fixes that happen, then because you use ANOTHER library that has the same dependency, and that other library uses a feature only present in a newer version. Any time you upgrade a library it takes work to verify nothing has broken, and potentially work to fix things that do break.