Software Engineering Can't Be Solved

People keep predicting the end of software development. Every few years, someone announces that the hard parts are about to become easy. Once that happens, they say, development will be solved. AI made these voices louder than ever.

This reveals a fundamental misunderstanding of what problems are.

There is no such thing as a solved problem. All solutions are temporary.

Consider transportation. We solved the problem of moving people across distances. We built cars. Problem solved.

Except now we have traffic congestion. We have parking shortages. We have urban sprawl designed around car ownership. We have millions of deaths from accidents. We have air pollution. We have climate impact. We have the question of who can afford to own a vehicle. We have entire industries devoted to insurance, maintenance, and road infrastructure.

Then we said we would solve traffic with self-driving cars. Now we have new problems. Liability frameworks. Edge cases in perception systems. Coordination between human and autonomous vehicles. The social question of job displacement for drivers. The infrastructure question of mixed autonomy roads.

Each solution spawned a new class of problems that did not exist before. We did not solve transportation. We transformed what transportation problems look like.

The same pattern appears everywhere.

We solved long-distance communication. We built phones. Now we have spam calls, robocalls, phone addiction, the expectation of constant availability, and the erosion of boundaries between work and personal time.

We solved information access. We built search engines. Now we have SEO spam, misinformation at scale, filter bubbles, attention economies, and the challenge of determining what is real.

We solved food production. We built industrial agriculture. Now we have soil depletion, monoculture vulnerability, supply chain fragility, nutrition deserts in cities, and debates about sustainable farming at scale.

Every solution rearranges the problem space. It does not eliminate problems. It creates new ones that were impossible before the solution existed.

This is not a flaw in how we solve problems. This is the structure of problem-solving itself.

Software development follows the same pattern.

Suppose every difficult part of software today becomes easy tomorrow. Suppose infrastructure management, debugging, deployment, testing, and scaling all become trivial. What happens next?

The goal post moves.

When those things become easy, they stop being the frontier. They become the baseline. The moment something is easy, it becomes invisible. It becomes the foundation for the next layer of problems.

If deploying distributed systems becomes as simple as running a local script, people will stop thinking about deployment. They will start building things that assume effortless deployment. They will create systems with hundreds of services because the cost of managing them dropped to near zero.

Now the problems are different. How do you reason about a system with 500 microservices that auto-scale based on unpredictable traffic patterns? How do you debug emergent behavior in a system where no single service is broken but the interactions create failures? How do you maintain consistency when every component can be independently deployed by different teams across different time zones?

These problems do not exist today at this scale because the baseline difficulty of deployment prevents most teams from reaching them. When that constraint disappears, the next layer becomes visible.

This has already happened multiple times in computing history.

Memory management used to be a central challenge. You had to think about allocation, deallocation, fragmentation, and pointer arithmetic. Languages with garbage collection made that easier. Did programming become solved?

No. The attention moved. Now people build systems with garbage collection pauses that cause millisecond-level latency spikes in distributed systems. Now people debate the tradeoffs between throughput and pause times. Now people spend time profiling allocations to avoid triggering collections during critical paths.

The problem shifted. It did not disappear.

Concurrency used to require manual thread management. Then we got higher-level abstractions. async/await. Promises. Green threads. Did concurrent programming become solved?

No. Now people build systems that coordinate thousands of asynchronous operations. Now the problems are about backpressure, cancellation, and reasoning about complex state machines that span multiple async boundaries. The easy stuff disappeared into the language. The new hard stuff emerged at the next level.

This pattern is not a bug. It is the whole point.

Making something easier does not reduce the need for expertise. It shifts where expertise applies.

When cars became reliable enough that most people stopped needing to understand engines, we did not need fewer engineers. We needed different engineers. We needed people who could design traffic systems. We needed people who could model urban planning around vehicle flow. We needed people who could build navigation systems that coordinate millions of simultaneous routes.

The expertise moved up the stack.

This happens because human ambition is not fixed. People do not build up to the edge of what is possible and then stop. They build to the edge, then use that edge as the foundation for the next thing.

Every time the floor rises, the ceiling rises with it.

If AI makes writing boilerplate code effortless, developers will stop writing boilerplate. They will start composing systems out of larger blocks. The questions will become architectural. How do you design systems that are comprehensible when each component was generated in seconds? How do you maintain quality when iteration is nearly free? How do you prevent the explosion of entropy that comes from making creation too easy?

These are not the problems of today because today, the cost of creation acts as a natural filter. When that cost drops, the filter disappears. Volume increases. New problems emerge.

People who predict the end of programming are imagining a fixed target. They see the current set of challenges and imagine those challenges disappearing. They forget that the challenges are not fixed. They are relative to the baseline.

If everyone can build a web app in five minutes, building a web app is no longer valuable. The bar moves. Now the question is what you build with the assumption that web apps are free. The people who thrive will be the ones who see the new frontier.

Programming has never been about syntax. It has never been about knowing how to write a for loop. Those are tools. The skill is knowing what to build, how to structure it, and how to navigate tradeoffs in a system that is always more complex than you can hold in your head.

That skill does not disappear when the tools get better. It becomes more important.

When low-level concerns fade, high-level concerns grow. When tactical problems become easy, strategic problems become the bottleneck. This is not unique to software. It is the pattern of every mature field.

Software development will follow the same path. The tools will improve. The floor will rise. The frontier will shift. The people who succeed will be the ones who understand that the goal is not to avoid problems but to reach more interesting ones.

There is no finish line. There is only the next problem.