3 ms·
> If a package manager only permits installing or depending on one version of each of package then ... So just allow installing more than one version of a give
by Diggsey 4y ago
> If a package manager only permits installing or depending on one version of each of package then ...
So just allow installing more than one version of a given package? Problem solved :)
> A locally coherent package manager requires a globally coherent software distribution.
Ah, so the implication is that "local incoherency" is bad? There are certainly some specific packages where you don't want multiple versions in use at the same time, but for most packages it's fine. For the sake of discussion, let's call those packages where having multiple versions is a problem "key" packages.
The problem with the solution in the article is that it requires some third party (ie. Stackage maintainers) to do a ton of extra curation work, plus every package that might depend on a "key" package needs to do work to make sure they're using the same version as everyone else if they want their package to be included in the next curated set.
An ideal solution would only require extra work for the maintainers of those "key" packages. This can be achieved by splitting the "key" package into two parts:
1) The "key" part of the package - only one of these can be in use, but has no public API.
2) The adapter package - depends on the "key" package and exposes a public API.
Since the adapter package is not a "key" package, it is fine to have multiple versions, and since no other packages will directly depend on the "key" package, there's no extra work for anyone else.
The maintainers of the "key" package will continue to release patches to older versions of the adapter package to ensure that all adapter versions are compatible with the latest version of the "key" package.
- marcosdumay 4y agoHum... Let's say I install the package A, that has the type X, so I can use A.X in my code. But I'm using it's version 1, so let's call it A1.X. Now, all of my dependencies expect values of A1.X. Except for one, that upgraded recently and expects A2.X. Now I have no way at all of taking a value from one library and sending it to that new one. It's only useful it it's some stand-alone functionality that I must call directly from my code (like the vast majority of libraries in OOP, so, maybe you are biased?) and not integrate with anything.
- Diggsey 4y agoThat's certainly an interesting case. A "UUID" package is a good example of this, since UUIDs are often not in the standard library, but are often passed around between other packages. There are two approaches to solve this that I know of: 1) When releasing UUID 2.0, also release a new UUID 1.X which adds a dependency on the new UUID 2.0 package. Then either: a) Re-export the UUID 2.0 type from the UUID 1.X package. b) Add conversion functions/operators to the UUID 1.X package. This approach is nice because there is no extra overhead for the 2.0 dependency, all of the extra compatibility code only exists in the 1.X package. 2) Discourage passing around UUIDs directly. Instead have a trait/interface/etc. called "UuidLike" or similar, that is implemented for UUID-like things, and have downstream code be generic. This trait would allow converting to/from any version of the UUID type. A similar approach as in (1) can be used to share this trait across multiple versions of the package. For this example of a UUID, approach (1) makes more sense to me, but in practice there may be cases where approach (2) makes more sense. There may also be cases where it is preferable to just break compatibility. An example of this would be if the UUID 1.0 package had a sufficiently serious design flaw (eg. always assumed type 1 UUIDs or something). In that case the ecosystem churn may be preferable than trying to support something inherently broken.