TheJach.com

Jach's personal blog

(Largely containing a mind-dump to myselves: past, present, and future)
Current favorite quote: "Supposedly smart people are weirdly ignorant of Bayes' Rule." William B Vogt, 2010

Reasons I dislike semver

  • If the MAJOR changes, you know something intentionally broke, but you don't know what
  • You can figure out what broke by seeing your own code break, or perhaps ahead of time by reading the release notes.
    • Frequently in practice there are no useful release notes about the breakage, though. If they're following semver strictly, you can maybe find details in documentation, and review changes to documentation when there are no useful release notes. You could also step through all the commits -- but we're trying to avoid that effort, no?
  • This leads to interpreting a version number as maybe-care.don't-care.don't-care
  • And so the only possible benefit is increased laziness by ignoring the don't-cares, because the intent is that you can upgrade freely until the MAJOR changes
    • But this laziness is bad, and in practice doesn't turn out so nicely, because changing the MAJOR only captures intentional breaking changes, and not the very common unintentional breaking changes
    • That is, if your goal is just to prevent breaking, intentional or not, you can't even trust a PATCH change, because bugs happen
    • Plus, you might actually care about the smaller bug fixes and new features! You should really spend effort to see what changed and consider updating, when there's an update. It might even be critical to your program's security. Sorry, you can't be lazy without consequence.
    • Additionally semver makes no requirements on granularity. Change one thing that breaks? Update the MAJOR. Change many things completely (version 2.0 baby!) in a way that requires most everyone to do a rewrite? Update the MAJOR. Which one of those is this update? You have to look to find out.
    • Not everyone uses semver, and nor will they ever thankfully, but this means you can't be lazy for everything. Because of scale, it's less effort to be consistent with how you handle updates for all your dependencies, rather than dividing processes and trying to be lazier for semver'd libraries.
    • So even with some semver, you need to have automated builds and tests at a minimum, this lets you try every new version regardless of whether the MAJOR changed or not, regardless if the library is semver'd or not, and see if it breaks you in a way you can easily detect
  • In practice, when breaking changes happen, the response of the project is one of three not very helpful options, the second being the best but you still experienced breakage
    1. It was intentional, revert or deal with it
    2. It was unintentional, revert or wait until we push a new patch to restore behavior
    3. It was unintentional, but we like it, so we'll bump the MAJOR and re-release, revert or deal with it
  • If it does break, most people don't care whether that break was intentional or not, they're mad that they need to work around it. Those three responses aren't helpful.

Summarizing: I find semver useless (it saves no effort or frustration in practice) and even harmful (it condones making breaking changes without recognizing that people don't like breakages, intentional or not), and so is not worth standardizing on.

The better thing to do as a library author is to not break APIs! When you have this attitude it's very possible to have non-breaking APIs for a long time, much like when you embrace an immutable-by-default language you learn that you don't need as much mutation as you thought.

One way to do it is to maintain multiple versions of your API within the same program, and support all versions indefinitely. It's not as bad as it sounds, and in many cases might just mean exporting a "myFunc2" and updating documentation that users should really use that one. You can even add instrumentation to discover usage, and consider removing if you find no one really is using the disfavored entry point, but it's better to just not break things ever.

See Full Post and Comments

Added some social media integration

Got slightly annoyed when I shared a link to an old post and twitter didn't do anything nice with it. So, now it should.

This is the biggest blog update I've done in a while... despite only being like 30 lines of diff, most of which echoing the meta tags themselves (thanks to this getting started reference), my PHP has gotten rusty, and it took longer than it should have. Also discovered my error setup that emails me when an error occurred isn't working anymore, so I needed to fix that. And a few other maintenance things -- my cookie/session handling logic needs an overhaul later, it's not using secure defaults.

Maybe it's just time for that rewrite after all. =P

See Full Post and Comments

Two problems addressed by an issue tracker, testing, and code review

I haven't been coding much since "retirement". A bit here and there, and I enjoy it every time, but sometimes I'll go weeks without doing any. Still, what little I've done, I've recognized some insights about myself and the way I write software that I might not necessarily have fully gained if I still had employment. It's nothing mind-blowing, I'm sure many programmers either realize something similar already, or just don't have the same problems. (Parts of the methodologies of professional development try to prevent the problems from arising, and you can make use of those as an amateur/hobbyist/out-of-worker just fine, as we'll see.)

The way to approach this is by noticing two "problems". They both stem from the fact that left to my own devices, my development flow naturally drifts towards a lazy style reminiscent of when I first started programming and didn't know any discipline to make things better. Sometimes that's fine, you can just brute-force it, and indeed that's how many of the things I did got done. An example of this style is not using version control much -- just develop the whole thing until it's ready, then commit it and ship it! Once I have a "base thing" though, I can then more easily apply some discipline, so the two problems I'm now going to highlight come most strongly in the earlier phase.

The first problem I found nicely described by this old blog: Imagination Overrun. The second problem is also described there, Knowing When You're Done.

See Full Post and Comments

Six-month early "retirement" report

Today I read The 2021 Early-Retirement Update since it showed up on HN. This prompted me to write a bit about my current situation -- admittedly not a report (I lied), mostly just a few quick and useless thoughts.

It always bemuses me when I see people figure out something like "There’s so much left of life, so much that will change, so much that will deviate from peoples’ original plans." The only constant is change! Yet here we are, someone careful enough in their thinking to pull off FIRE, who has probably read a lot, and yet this insight is new to them at the age of 41. (They're 43 now.)

So I'll write down some of my own thoughts I had well-before I hit the trigger to quit. (Last September was my final month, just in time for my 30th birthday on October 2nd.) These thoughts are what I think gave me the basis to be as "eyes open" about things as I could have. Maybe they'll be amusing for others to read too.

See Full Post and Comments