Thursday, November 5, 2026

Difficult Problems

In software, these days, if there is a fleet of existing interoperating systems, it is most likely that when they were developed, they focused on solving the majority of the easy problems.

Often, it is also the case that, in doing that specific work, they made any related difficult problems far more difficult.

What this usually means is that if things are not working smoothly, then there are probably no longer any easy solutions that would fix the mess. The development has painted itself into a corner.

Anything that would make significant progress in correcting some or all of these deficiencies is going to be extremely difficult now.

Why?

The obvious point is that the current solution is fragmented; e.g. there is more than one interconnected system. The reason they are fragmented is that people kept tearing off smaller parts and solving those. That behaviour is a side effect of people zeroing in on the easy stuff and then trying to solve only their bit in isolation. Thus you get a bunch of systems where interconnection is an afterthought.

If you have a space where there are a lot of these smaller independent fragments, not only do they, as separate pieces, cause artificial complexity, but also their focus, as tunnelled from the larger whole, forces them to skip over difficulties. That is, they are so focused on just getting their thing done that they do not care about the whole thing, so if they hit something difficult while doing their thing, they punt that out of their space. This leaves the space between all these systems filled with all of these punted difficulties. When this has been the approach for a while, most of the easy stuff is gone, and what remains is darn scary. The overall complexity of the Frankenstein mess is orders of magnitude higher than any sort of unified, difficult solution.

What to do?

Really, you have to go back over the mess and identify the difficulties. Pick a big one, start there, and grow it out to cover back over the easy stuff. That is, if hyper-focusing on solving simple things got you into this mess, then only hyper-focusing on difficult things will get you out of it.

Most difficult problems in software aren’t really that difficult; they are just difficult in a very restricted context. If you pull up and out a bit, there is probably a known way to get just that problem solved correctly. It definitely won’t be a cakewalk, but it is still likely solvable.

Given that, you take this difficult problem, a known thorn in everyone’s side, and you write up both a specification of the problem itself and a design for something that would fix it. With those, you see what other existing parts of other systems they now cover. Then, if you are sure that would really fix the difficult issues, you work out a slow, phased transition to get that difficult core into place, and gradually extend it out to everything else. If you keep at this, eventually everything else disappears, and what you have left is one single integrated, fully functional, “difficult” solution that works smoothly.

I’ll say it again. Simple solutions do not solve difficult problems; they only fragment them into bigger messes. If the problem is difficult, the solution needs to be at least as difficult. There is no getting around this. You cannot avoid difficult problems; you can only ignore them for a while. I’ll call this the first law of solutions.