[Haskell-cafe] Platform Versioning Policy: upper bounds are not our friends
wren ng thornton
wren at freegeek.org
Fri Aug 24 03:50:17 CEST 2012
On 8/22/12 12:35 PM, David Menendez wrote:
> As I see it, there are four possibilities for a given version of dependency:
> 1. The version DOES work. The author (or some delegate) has compiled
> the package against this version and the resulting code is considered
> 2. The version SHOULD work. No one has tested against this version,
> but the versioning policy promises not to break anything.
> 3. The version MIGHT NOT work. No one has tested against this version,
> and the versioning policy allows breaking changes.
> 4. The version DOES NOT work. This has been tested and the resulting
> code (if any) is considered not good.
> Obviously, cases 1 and 4 can only apply to previously released
> versions. The PVP requires setting upper bounds in order to
> distinguish cases 2 and 3 for the sake of future compatibility.
> Leaving off upper bounds except when incompatibility is known
> essentially combines cases 2 and 3.
> So there are two failure modes:
> I. A version which DOES work is outside the bounds (that is, in case
> 3). I think eliminating case 3 is too extreme. I like the idea of
> temporarily overriding upper bounds with a command-line option. The
> danger here is that we might actually be in case 4, in which case we
> don't want to override the bounds, but requiring an explicit override
> gives users a chance to determine if a particular version is
> disallowed because it is untested or because it is known to be
There are two failure modes with overriding stated bounds, however. On
the one hand, the code could fail to compile. Okay, we know we're in
case 4; all is well. On the other hand the code could successfully
compile in ways the package designer knows to be buggy/wrong; we're
actually in case 4, but the user does not know this. This is why it's
problematic to simply allow overriding constraints. The package
developer has some special knowledge that the compiler lacks, but if all
constraints are considered equal then the developer has no way to convey
that knowledge to the user (i.e., in an automated machine-checkable
way). Consequently, the user can end up in a bad place because they
thought this second failure mode was actually the success mode.
This is why I advocate distinguishing hard constraints from soft
constraints. By making this distinction, the developer has a means of
conveying their knowledge to users. A soft bound defines an explicit
boundary between case 1 and cases 2--4, which can be automatically (per
PVP) extended to an implicit boundary between cases 1--2 and cases 3--4;
a boundary which, as you say, can only be truly discovered after the
code has been published. Extending soft boundaries in this way should be
safe; at least it's as safe as possible with the foresight available to
us. On the other hand, a hard bound defines an explicit boundary between
case 4 and cases 1--3. If these are overridable, things may break
silently as discussed above--- but the important thing is, in virtue of
distinguishing hard and soft bounds, the user is made aware of this
fact. By distinguishing hard and soft bounds, the developer can convey
their special knowledge to the user. The user can ignore this
information, but at least they'll do so in an informed way.
More information about the Haskell-Cafe