> On Oct 14, 2016, at 09:43, Alexis via swift-evolution
> <firstname.lastname@example.org> wrote:
> A library shouldn’t pin its dependencies, while an application should.
Not only “shouldn’t” but can’t: Rust’s cargo (I don’t know for sure about
Bundler and Yarn, but they’re all in the same vein, and pretty much from the
same person) will just ignore any non-top-level lock files, i.e. the package
that user is working on has a record of the exact versions of everything in
their dependency graph, and the user can update all or just parts of that graph
fairly precisely, as desired.
My impression is that other ecosystems without pinning-by-default have
seriously suffered from the lack of reliable reproducible builds. For instance,
a major complaint I have seen about "go get” is that one can come back to some
code after a few months to fix a minor bug and have no chance of getting the
code to compile, basically just requiring a full rewrite, because dependencies'
code has changed (or disappeared entirely) and there’s no record of what the
original was, despite your code being completely untouched in all that time. Of
course, a hard push towards API-level semantic versioning may allay the worst
of the code-changing problems, but unless there’s going to be some seriously
fancy static analysis (something something halting problem), there will be a
lot of breaking changes that can’t be picked up.
To reframe the discussion slightly, not pinning dependencies effectively means
that the tools are making “random" changes to your code outside your control.
Sure, those changes were transitively made by possibly-computer-assisted humans
and may fix bugs, but those pesky meat-bags can still make mistakes, and, they
don’t see the interactions between all the different packages in your specific
IME having the predictability of “never changing code under my feet” combined
with pervasive semantic versioning hits an empowering middle ground of being
able to depend on many & varied packages and update them to the latest versions
without fear (for one, it’s easy to revert the lock file if something breaks
during an update). Feedback from others about cargo is the same, often along
the lines of “it’s the best package manager I’ve ever used”.
Also, more on the side of implementation details, having a lock file by default
probably mean one can (get closer to) never hitting the network unless the user
asks for it, making working offline or on a low-speed/high-latency connection
easier, i.e. no need to check for new versions of the whole dependency graph on
O(every) build, which aggressively keeping everything up to date would
seemingly have to do? (I don’t know swift-pm’s current behavior here, so maybe
there’s some tricks that avoid it.)
swift-evolution mailing list