Forward-Compatible Code

Main Thread 1 min read

Most developers know about backward-compatibility — ensuring code runs under past versions. But what about forward-compatibility? Developing code compatible with future versions can be equally important.

I recently had a task to update some legacy code. This code was high-profile. All of our stacks ran a version. So I needed to ensure that my updates were compatible.

Upon reviewing the code it contained a version variable (VER). Perfect! A version variable is perfect to use as a feature flag. I could wrap my updated code inside conditionals until the rest of the stacks were upgraded.

1if (this.version == 101) {
2 // new code
3}

Done. Right? Well, yes and no. Yes, this code is backward-compatible. I safely wrapped my new code in featured flags. So I can rest assured it will only run when the feature flag is set. In this case, when this.version equals 101. However, no because unit tests failed for old versions of the code.

After some debugging, I found the issue:

1if (this.version > VER || this.version < 100) {
2 return;
3}

Although I incremented VER for my new version, the old version still had the previous version number. While my code was indeed backward-compatible, old versions always failed this little gem: this.version > VER. The old code was not forward-compatible. This logic prevented me from using an ideal version variable as a feature flag.

I will not speculate on the original developer's intention. However, given the code's high-profile and the existence of VER the logic above is odd and a good demonstration of code that is not forward-compatible.

Find this interesting? Let's continue the conversation on Twitter.