Here's an example where innocuous decisions can lead to needlessly complex software.

Let's say you're working on some software and you decide to use asprintf, a GNU extension. It's a fairly benign extension, after all, and clearly useful. You might not even notice it's an extension because someone on stackoverflow told you to add -D_GNU_SOURCE to your build 30 problems ago. Your system is glibc anyway.

Now your program doesn't work on musl libc, which eliminates Alpine and Void Linux. It also no longer works on newlib, so that's most embedded devices out. Linux is the only system which ships glibc, so it's also done for on BSD, Minix, and so on. The next big operating system will have to resort to reverse engineering glibc to support your program, since asprintf isn't defined by any standard.

That was just one small, seemingly benign change. What if, knowingly or not, you've made dozens of such changes in your project? What if you pull in a dependency which has made similar concessions? What about transitive dependencies? What if we build an entire industry of computers on the shoulders of software which has made these little compromises, all the way down?

If we're ever going to make it out of this mess, we have a responsibility as programmers to strive for simple software, to dig our way out of this enormous hole we've put ourselves in. The only way up is to become more simple, not more complex.

This is why I see languages like Rust, systems like Fuchsia, and so on - as if they were handing out shovels.


@sir Just for the sake of absolute correctness, note that asprintf is implemented in musl (alongside some other GNU extensions). That said, it's still non-standard and not implemented by all libcs.

@emersion @sir And all the BSDs. Its use is actually encouraged. 😂

Sign in to participate in the conversation

The social network of the future: No ads, no corporate surveillance, ethical design, and decentralization! Own your data with Mastodon!