OVER THE FULLERENESHIFT

OTAKUSPEEDVIBE

23/11/2024 - The Limits of Cross and Backwards Compatibility

Note: Keep in mind that I don't have much experience with a lot of topics I'm gonna mention here, so correct me if I make any mistakes. Thank you!

What Makes Cross-Compatibility Hard

As I've mentioned in my previous blog post, home page, and probably more pages as time goes on, I really, really, care about backwards-compatibility and cross-compatibility.

The only problem is, full backwards and cross-compatibility is impossible. This is probably obvious but I'm gonna rant about it nevertheless just to show exactly why this is bothering me so much.

When most people think of cross-compatibility, they think of something like an app that works on Mac, Linux, and Windows - maybe mobile platforms too - iOS and Android. There are a few problems with this though:

  1. Versions for Mac, Linux, and Windows often need to be slightly modified to compile properly or run as expected.
  2. An app made for desktop and mobile is often just two different apps entirely - I want cross-compatibility as in the same app running everywhere; this just isn't the same, and requires a lot of work.
  3. APIs: Different OSs will have different APIs, which makes UI, graphics, and many other things a pain to make cross-compatible; there a few solutions to rendering graphics specifically:
    • To make the app render the same everywhere, abstract away system calls as much as possible; no more system UI, no more system fonts, etc. Everything is entirely controlled by the app or library, at the cost of making everything look slightly odd everywhere and likely slower performance and more bugs - I believe this is what Java does (or used to do).
    • Not making the app render the same everywhere - just use system APIs, fonts, UIs, etc. It'll look close enough. Of course this provides a better experience on every platform in general, but when I say cross-compatibility - I want everything to be as similar as possible.
    • To make the app render the same everywhere, just use WebView/Chromium. From my experience, this seems to be the most common solution now in 2024. But this has heavy performance costs - only write JavaScript if you're making a website - and on that note, why not make a website instead?

Backwards-Compatibility and the Web

The web is convenient in that almost every modern device has a built-in browser, and browsers are designed to work as similarly as possible everywhere. This is basically perfect for what I want, especially since making a website means no downloads are required - you can make things that work on iOS without having to jailbreak your device or use TestFlight or the App Store. Neither do you have to deal with compatibility for every Linux distribution ever.

Developing websites you run into a different problem though; backwards-compatibility.

Of course backwards-compatibility is also problematic on compiled platforms outside of the web, but much less so. Installing older versions of Windows or any other OS means - well, installing an OS. Older devices might be limited by hardware, but finding and buying an old iPhone is significantly more difficult than installing an old browser.

Notice the little text on the footer of this site? "Tested on Firefox 132.0.1 64-bit Windows and Chrome 1.0.154.59?" Yes, I actually test to make sure this site works on the first version of Chrome. It wasn't hard to set up. I just downloaded it off the Internet Archive and that's it. Using an old, non-compatible browser is much, much, easier than using an outdated device or hardware. And by extent, this means backwards-compatibility is a much bigger problem to face on the web.

Sidenote: I don't know about any Linux distributions or Mac, but Windows doesn't even maintain backwards compatibility with lots of old apps, so making an app really backwards-compatible without rewriting it is impossible anyways, for Windows at least.

What Makes Backwards-Compatibility Hard

Browsers have evolved a lot, and maintaining backwards-compatibility with old browsers is made easy by projects like core-js and babel - kind of. It all depends on how you define "old", as these mostly don't support IE (To clarify, I don't aim to support Internet Explorer either, but I could if I wanted to - these projects will never add more support to IE, because why would they? A more important thing to me though is that the oldest version of Chrome supported by Babel is 3; I make everything compatible with Chrome 1), can't polyfill HTML elements, and obviously can't and don't polyfill features like WebGL. This is especially important to me since 3d graphics in Chrome 1 is something I've been trying to achieve for a while, and it has to be done with CanvasRenderingContext2d.

Despite all of the efforts to achieve compatibility between all browsers, it's still not perfect for all my needs. It also really bothers me that I'm losing control over the exact output of programs like Babel, but that's a separate topic.

This means code compatible across every version of every browser has to be written manually - a pain, but worth it, for me.

This is gonna sound ridiculous, but no matter how hard you try, full compatibility across all browsers will always be impossible, and for one very simple reason - anyone can make a new browser. It might not be complete or follow every standard, but it's a browser, and that's exactly the problem. All of the solutions you can come up with will only work on spec-compliant browsers or ones with known errors and bugs. More obscure browsers (unlikely), and really old browsers won't support JavaScript correctly or entirely.

Does this all seem absurd and stupid? That's because it is. No one will ever use any website I make on Chrome 1 over than myself. I'm not doing this for any actual use; I'm doing this because I want everything to feel complete - I want it to be perfect.

Going Past Browsers

Ok, browsers aren't perfect for this. Are there any other options? Yes. Assembly.

The most common CPU architecture is x64/x86. Since x64 is compatible with x86, x86 assembly is basically perfect. It doesn't matter what your OS is, as long as you have an x86 or x64 CPU, the program can be run.

The problem with this is it's leaving a lot up to the BIOS.

The second, much bigger problem is that writing anything actually good in assembly is ridiculously hard.

Oh, and if you're thinking "What about ARM? x86 assembly isn't fully cross-compatible," you're right. The first two problems I can ignore and go past, but there is no way to write assembly that's compatible between ARM and x86. Not only that, although ARM and x86 are generally the most used, theoretically something could be running on a completely different architecture - so even if I manage to get some sort of compatibility between ARM and x86, maybe a CLR or VM of sorts - this still won't be perfectly compatible with everything.

Admittedly, devices not using x64, x86, or ARM probably aren't capable of running a browser or any modern OS in the first place, which I never mentioned in the previous sections, but that's fine. If you can't open a browser, how will you even be able to check that a website renders properly or not?

What next? Make my own hardware? No thanks. Not only is that really difficult, my goal is cross-compatibility, not consistency on a single platform that no one but me has access to.

x86 assembly can be emulated on other devices using projects like QEMU but it doesn't work on web, which means excluding devices it can't be compiled to, like iOS. I could try to write an emulator for x86 in JavaScript for maximum compatibility, but even if I was able to do that, reading binary files is basically impossible in old browsers and it would be painfully slow. And as for QEMU, it means the user has to install an external program, which isn't really the kind of cross-compatibility I'm looking for - It's not cross compatible if you have to run it on an emulator or VM that doesn't come with the app itself.

Conclusion

Perfect cross-compatibility and backwards-compatibility is actually impossible. This sucks for me but there's literally nothing I can do.

I could try implementing a VM that works on web and all major OSs, but that would be difficult to do in a performant way and would lose some of the lower level control I could have, especially in a browser where the lowest level is still human-readable - JavaScript.

Oh well. I'll just have to deal with it and try to get as close to full backwards and cross-compatibility as I possibly can.