blog.mikro2nd.net

Programming by Composition

One of the big obstacles to "composing software out of small pieces" is that programming languages are so shit at interoperability. And this is a bit of a mystery to me.

There's an application for my desktop-of-choice (KDE) that I would use but for some missing or malappropriate functionality. Now, I'm nominally a "programmer", so, in theory, capable of writing some code that would supply the missing or maladjusted want. But. (And it's a biggie!) The application is written in C++.

I worked in C++ for something like 10 years. Got paid for that, too. So I know the language and large swathes of the toolchain, and, while my knowledge is sorely out of date by now, I'm confident it wouldn't take me all that long to catch up.

Ain't gonna happen.

There's reasons I quit that ecosystem, and I'm never going back (I swear, Your Honour). I find it a hateful and obtuse way to programme computers, and there are other programming languages and ecosystems I'd prefer to use. (Possibly you'd hate my choices; this is not to be judgemental — we all have our likes and dislikes and that's OK.)

This is about, "Why can't I use Language-K to write some functionality for, or modification to, application-X that's written in $Language-Other-Than-K?" At least not reasonably easily.

The reason I find this slightly mysterious is that, at base, all programming languages end up being rendered and presented to a CPU in the target machine language, using the target environment's calling conventions, memory and OS access, and so on. Whatever source language we express our algorithms in, it all ends up looking and acting exactly the same. Otherwise it doesn't work. So why can't those source languages talk with each other or interact in some simple, straightforward way?

Oh, I know about FFIs — those shaky, swaying and unstable rope bridges across the canyons of the different calling conventions, stack-frame layouts and language standard libraries. They're an utter bastard to use, and even worse to debug. You spend orders of magnitude more time wrangling the accidental complexities of type conversions and wrappings, null handling, string formats and similar than you do on the (usually relatively simple) bit of functionality you want to add or fix in Application-X.

You'd think there'd be some sort of Swiss Army Knife tool out there to handle all that messy (necessary, but still accidental) complexity for you. I call to mind Pandoc in the text-format-conversion space.

But even imagining such a Utopian world where such conversion was possible — automated, even! — there's still the problem that the way we structure software seldom, if ever, lends itself to any deep level of modification. The best we can generally hope for is that the original designer/writer of the software was sufficiently foresighted, and had the patience and energy, to supply useful, well considered hooking-in places in the overall framework of their code where we might hang new or altered silicon.

Such things happen seldom. The stuff of pipe-dreams except for very, very few exceptions.

So is there a way out of that labyrinth?

One path would be to have all programming languages compile to some common, tiny sized, agent-like services or atoms that interoperate via something like a messaging paradigm. (Waves at Smalltalk.)

Not happening. You're never going to persuade everybody to Change The World.

So what else?

(Thinking still in progress...)