people: ask their dependencies to follow semver, for fuck's sake already
also people: make a surprised pikachu face when the major version is incremented with every release

(i have been both, at times. this is about me. this is also about others who i've seen be a lot more militant about this issue)

the thing is, if you have a sufficiently complicated application it is not feasible to determine what is a "breaking change" or not. this complexity limit kicks in long before you get to a "browser" or a "JIT compiler" but it is definitely well applicable by that point

i think what people mean when they do both of those things are a mix of "please stop adding features entirely. only fix bugs" and "please only make changes i like, but not the changes i dislike" depending on maturity level. that's not really how open source software works though

@whitequark

I absolutely detest SemVer because it has no way of doing graceful deprecation, which arises because it conflates implementation and interface.

A library that wants to do graceful deprecation will have three releases, A, B, and C, where B introduces a new API and C removes the old one. C is a breaking change for anything coming from A. C is a breaking change for anything using B and not moving to the new interfaces.

You really want a set of SemVers, for each interface you support. So you actually have something like:

  • A: {1.0}
  • B: {1.1, 2.0}
  • C: {2.1}

I have never seen a system using SemVer that supports this. You can kind-of do it with UNIX SONAME and symlinks, where A has symlinks names libfoo.so.1, libfoo.so.1.1, and then B has symlinks named libfoo.so.2, libfoo.so.2.0, libfoo.so.1, libfoo.so.1.1 and libfoo.so.1.0, but I’ve never seen it done.

@david_chisnall yeah you're on point

@whitequark

One of the few things I like about Windows is that COM doesn’t let you change interfaces. You can create a new interface, with a different name or version, but once you’ve shipped an interface it’s stable forever. Windows DLLs can export many different versions of interfaces. And COM has an IDL so you can surface these in many different languages without needing to go via C.

EDIT: COM is far from perfect, but it’s also over 30 years old at this point. There’s no excuse for having things that are worse than COM.

@david_chisnall yeah, COM is an improvement on many of its successors.

what I do in Amaranth is I split it into pieces small enough that each, individually, can be maybe reasonably approximated with SemVer, but it's far from perfect

I think the closest approximation in mainstream PLs for what you're proposing is Rust, where you could have e.g. rand 0.9 depend on rand 1.0 (and reexport some types from the latter) so you can have both of them used in the same project and you don't end up with horrible diamond dependency issues. but it's far from intuitive or convenient.