I dunno, man; I'm not a programmer but I'm on three different closed NDA betas (and four or five open ones) and the process is exactly this: PRO TOOLS 12.8.2x147 Where - "12" is the version Marketing is using for an overarching major paradigm change with major improvements (v12 has track freeze, a new video engine, a rewritten audio engine and robust improvements to the workspace) - ".8" is the version Marketing is using for a bundled suite of improvements over .7, for example (predictive labeling, revised I/O manager, etc) - ".2" is the version Engineering is putting out of assorted bug fixes and minor improvements - "x147" is the internal build number we're all working on to try and break/fix prior to release candidate and gold master for distribution to all users Anything that works with 12.1 will work with 12.7 will work with 12.8, but there will be compatibility issues with 11. Meanwhile, 12.8.2 is going to be an incremental improvement over 12.8.1 and the xVersions nobody external is going to see anyway. And it works just fine. I mean, we all know that the best performance we ever got was 7.4.2 but we also know that it ran on RISC processors and used a plugin structure we abandoned in 2009 and that was back before we were expected to work with 150 tracks on a bloody short film. Again - not a programmer but this stuff makes perfect sense to me.
I am a programmer, and I have to agree. The current scheme of dotted numbers works just fine. Everything mentioned in this post falls into two categories. 1) Package managers should be better at automatically figuring out what version I want. 2) Version strings are should be easier to parse. (1) is a fair complaint. It's certainly possible to build a better package manager, but you don't need to mess with versioning to do it. (2) is really just arguing semantics. I personally disagree with akkartik, but it's a fundamentally subjective argument.
Yes, if you can't relate with the problems mentioned in the talk and article I linked to, I guess you don't need the solution 🙂 Code shared between closely coupled teams tends to be the easier use case. Have you ever had issues upgrading your personal devices? I remember times when I couldn't get some Rails app running on my laptop after upgrading the OS. Anything like that ever happen to you?
Well now hold on a sec there, chief. Again - I'm not a programmer. But the system as it exists is perfectly parseable by me. Windows 3.0 was very different than Windows 2.0, and Windows 3.1 was a major improvement over Windows 3.1. Windows 3.11 was a refinement of Windows 3.1 and then the marketers got ahold of it and gave us 95, 98, ME, XP, Vista, 7, 8, 10. It seems that you're saying Rich Hickey is A-OK with Microsoft's market-versioning scheme (which, by the way, has devolved into nonsense) while the rest of the world totally gets that 3.1.2 build 8 is ahead of 3.1.1 but is not a stable version of 3.1.2. More than that, you're arguing that if the totally logical, totally deducible hierarchy that everyone else changes because it doesn't work in your corner case and I can't agree with that. OS X 10.0: Cheetah OS X 10.1: Puma OS X 10.2: Jaguar OS X 10.3 Panther (Pinot) OS X 10.4 Tiger (Merlot) OS X 10.4.4 Tiger (Chardonnay) OS X 10.5 Leopard (Chablis) OS X 10.6 Snow Leopard OS X 10.7 Lion (Barolo) OS X 10.8 Mountain Lion (Zinfandel) OS X 10.9 Mavericks (Cabernet) OS X 10.10: Yosemite (Syrah) OS X 10.11: El Capitan (Gala) macOS 10.12: Sierra (Fuji) macOS 10.13: High Sierra This is the best(worst) of both worlds - I know beyond a reasonable doubt that 10.13 came out after 10.12 while marketers can trumpet the wonders of "High Sierra." But god help you if your mother asks why she needs to upgrade from a beach to a mountain in order to keep Quicken working. Also, why is 10.6 snow leopard but 10.7 is lion? Is 10.6 actually 10.5.5 but 10.7 is... 10.6? Maybe we should just call it "Gumpy Gnu" or whatever. 17.04, I'm told, is "Zesty Zumpus" or some dumb thing but 17.10 is Artful Aardvark, which anybody with any sense will know is more advanced than Dapper Drake because it's been 10 years. And yeah - I know that if I update the version of anything it's likely to break something. After all, I've got three macs and a PC in the house. And when I know that Path Finder is approved through 10.12, I'm not about to update to 10.13 until I know beyond a reasonable doubt that the software I depend on works with it. It's a lot easier to know that 10.12 is after 10.11 than to know that Sierra is after El Capitan.The correct way to practice semantic versioning is without any version strings at all, just Rich Hickey's directive: if you change behavior, rename.
OS X 10 beta: Kodiak
Sorry, yes you're absolutely right and I'm being unclear. I'm a reasonable programmer but not a good writer. When I say "rename" I don't mean going from "Snow Leopard" to "El Capitan". That's stupid, yes. (And it's also marketing, which I know even less about. So I have no comment on what an improvement would be.) My proposal is going from "Rails-4" to "Rails-5". Which would have the same benefits as 10.11 and 10.12. The comments I've gotten so far are making clear that I failed to set the stage for this post. The scenario I'm concerned about (as are the links I refer to) is this: you have an app you built, and it relies on some versions of other libraries. You'd like to periodically pick up bugfixes and security fixes for those libraries without it turning into a bottomless time-sink (because your libraries failed to adequately distinguish between compatible and incompatible changes). How do we do that? (It's not just about tool design, it's about eco-system design.)
Rails-4 to Rails-5 kicks the crap out of Snow Leopard to El Capitan. So the full name would be Ruby Rails-5? I understand the problem you're grappling with now. Beyond my expertise: If you're compatible with Rails-4, for example, and Rails has been upgraded to Rails-5, is there any way to know whether or not you have an incompatibility issue without diving into the changelog anyway? I can see a few different ways that becomes a bottomless time-sink no matter how clean your versioning nomenclature is.
The convention programmers have long followed is now enshrined as something called Semantic Versioning (which comes with its own version, lol). Basically if a library makes an incompatible change it's supposed to increment the major version. So going from Rails 4.x to Rails 5.0 is a sign that you can't upgrade. Which is great in theory, except that the tools we programmers use to manage versions don't understand SemVer and just pick the latest version by default. Which causes programmers to explicitly ask for the version they want to avoid moving to the next. And all the 'pinning' in turn causes libraries to be less than disciplined about incrementing the major version number when they break something. So it's all a mess.
A package manager has know way of knowing what a breaking change is though because that entirely depends on how your code interacts with other packaged code. Some are easy to pin down and define. Others are almost impossible because people write software and people are inconsistent, they aren't omniscient and they can't understand or foresee every consequence of every aspect of the code they write. Why is version pinning so prevalent? The proximal reason is that modern package managers uniformly fail to provide the sane default of "give me the latest compatible version, excluding breaking changes."
Is your argument that we should give up and use one specific version of each library/package, and manually update the library/package version every so often? I can get behind that for offline software, but for anything exposed to the internet, the possibility of missing security fixes makes me leery of a purely manual update process.
Security vulnerabilities are another topic entirely, although they certainly overlap. Any changes to external packages you use increase the risk to your code - whether you let tools automatically upgrade or do it manually. Exhibit A - left-pad. We're still far from being able to automatically "verify" software - whatever that means in any given situation. Proving / verifying software has been a research topic since forever and still is. We do have better tools now to help with those decisions and hopefully they'll continue to improve in the future too. Whether that's semantic versioning. property based tests, dependent types and refinement types, automatic distribution, build and test tools,... the list goes on. the possibility of missing security fixes makes me leery of a purely manual update process.
Like @Wintermute, I'm struggling to follow what you're trying to say. The "better tools" you're referring to are precisely package managers. And they're useful precisely because they don't automate the decision entirely (leaving humans disempowered) but because they "help with those decisions" as you put it. So it's unclear to me where we disagree. Let me try to knock off a few things I'm not saying, just in case they weren't clear before: a) I'm not saying we should be deploying software to production by wantonly installing whatever the latest version of our dependencies happen to be. Things like Gemfile.lock in the Ruby/Bundler world are a good idea, and my post isn't about them at all. b) I'm not saying we should be upgrading our dependencies en masse and immediately running `git commit` without testing that the upgrade actually worked. Upgrading dependencies will and should always be a manual process. I just want it to be less of a bottomless time-sink. The two links I mention at the start of OP set all this background up. Perhaps I should have explicitly said people need to read/watch them before reading me. They're actually better posts written by better writers and programmers, so they're almost certain to be a better use of your time than my miniscule contribution (that I wrote without understanding Cargo, and so may well already be hopelessly wrong).
"3.0.2" is hard to parse? Are you serious? This reads like a complaint about the state of package managers, not a convincing argument against common versioning schemes. I really think you should break this up into two posts. Package managers have nothing to do with versioning. At a fundamental level, any package manager can be adapted to work with any proposed versioning scheme. Likewise, versioning isn't just a feature of package managers. The software I write for my job has version numbers, even though it isn't distributed through any package manager.
I agree that the article needs to change something. I'm not a good writer yet, and I definitely failed to get my point across to many (most?) readers. But I don't think separating package managers from the discussion of versioning is a good idea. Versioning is a social convention (as evidenced by the quantity of criticism my attempt at changing convention has engendered), and the #1 place the convention is propagated is in the package manager. You can in principle implement every one of my recommendations (or any alternatives people proposed in comments) without changing the package manager. But of course nobody would expect that to take. The big insight that provoked my post was that the bad behaviors the creators of Clojure and Mercurial were complaining about stemmed from bad defaults in package managers. > "3.0.2" is hard to parse? Are you serious? If this was the only sentence-level criticism you could make I'm not doing so bad :) Notice that I said "non-trivial", not "hard". In a tool whose #1 reason for existence is to "get the latest version", it seems a bad idea to make the format of version strings unstructured in code (they're literally strings surrounded in quotes) or convention (people are encouraged to add arbitrary words to them). Why make comparison unnecessarily difficult? I'm talking about creating a package manager from scratch (I'm not proposing every package manager break their users in a post about not breaking your users) for some hypothetical next big language, and in that situation it seems worth fixing even if it's not that big a deal. > The software I write for my job has version numbers, even though it isn't distributed through any package manager. My recommendation may absolutely not apply then. If your software isn't ever being upgraded en masse I have no opinion on what versions it should have. I'm speaking in the context of eco-systems that want to be able to distribute security fixes (at the least) on an ongoing basis. That's what the two links I was putting together were talking about, and that usually involves a package manager to automate the upgrade process.
Versioning is not the problem with package managers. It's entirely possible to implement a package manager that makes the right choices without changing how we version things. Cargo (Rust's package manager) does just that. That's why I don't think it's necessary to discuss versioning in an article about building a better package manager. Nothing interesting is trivial. That's almost tautological. Calling something out for being non-trivial is either meaningless or equivalent to calling it hard[er than it should be]. In fact, You don't actually need to make the versioning argument at all. I think you can make the exact same point made in the 3 paragraphs following my quote with the following single sentence: "By making the major version number part of the package name and combining the minor and patch numbers, we get a versioning system where the user is forced to pick a major version and can expect to always use the latest patch to that version". There are practical reasons why I disagree with the sentence above, but I think it does a pretty good job of making the same point you made in your article in less than half as many words.I'm talking about creating a package manager from scratch (I'm not proposing every package manager break their users in a post about not breaking your users) for some hypothetical next big language, and in that situation it seems worth fixing even if it's not that big a deal.
If this was the only sentence-level criticism you could make I'm not doing so bad :) Notice that I said "non-trivial", not "hard".
Yes, I'm not familiar with Rust, and I've been meaning to learn more there. The best response to my post thus far started off with a description of how Rust has successfully policed SemVer, and the issues they ran into: https://news.ycombinator.com/item?id=15676691#15677343. I'd greatly appreciate further pointers to how that community does things. > Nothing interesting is trivial. That's almost tautological. Calling something out for being non-trivial is either meaningless.. I just provided a trivial alternative that I found interesting. So much for your "tautology". > ..or equivalent to calling it hard[er than it should be]. I do call it harder than it should be, by providing a simpler alternative. It doesn't look like you disagree that a tuple is easier for the package manager to unpack than a string. You seem to be only saying that the difference isn't much. I've already agreed with that. So what are we arguing about? --- I have a problem with the statement that "nothing interesting is trivial": it becomes license for hiding over-engineering. I'd rather say that "everything can be trivial". It's right about the same fraction of the time, and even when it's wrong it's an impetus to find better ways, rather than to be complacent. I spend some time teaching programming, and it's amazing to me how often finding the right approach to teach something renders it almost trivial. See also Alan Kay's statement about the right perspective being worth 80 IQ points. --- I have a problem with statements as general as "nothing interesting is trivial" (Or, indeed, "everything can be trivial".) They aren't concrete enough to actually support any serious amount of reasoning. You can end up anywhere you like depending on how you interpret them. This comment is about as much of such fluffy debate as I can handle without breaking out in hives. --- Seriously, stop nit-picking wording in one sentence I quickly moved past in OP. It's mystifying to me why that's a better use of your time, rather than to elaborate on the "practical reasons" you so quickly skip past. I'm going to stop engaging here unless it is to discuss more substantive criticisms.