Thanks for the references. I think Android's versionName / versionCode are closest to what I have in mind. The problem IMHO with CFBundleVersion, CFBundleShortVersionString, et al. is that they need to be parsed before making comparisons, and this is where developers make mistakes or take shortcuts. Whereas with plain integers, direct comparisons are simple and usually correct as well. Take the story in question: I can imagine being lazy and skip over the major version part of the version string. But with integers, I wouldn't go out of the way to mask out the MSBs, no?
Guess what happens with something as simple as versionCode?
Hacks like this, to allow a single "version" of an app to have multiple APKs, but wait, versionCode has to be unique. I know, we'll do this:
> In the following example, the APK for the x86 ABI would get a versionCode of 2004 and the x86_64 ABI would get 3004. Assigning version codes in large increments, such as 1000, allows you to later assign unique version codes if you need to update your app. For example, if defaultConfig.versionCode iterates to 5 in a subsequent update, Gradle would assign a versionCode of 2005 to the x86 APK and 3005 to the x86_64 APK.
Sigh. Nothing is ever easy. We make assumptions when we design our systems without realizing it and then paint ourselves into these silly corners to not break things.