May 2026

Software Development Has Always Been Moving in One Direction

From assembly to compilers to frameworks to AI: software development keeps moving toward higher abstraction, faster feedback, and clearer intent.

Strategy & History
From assembly to compilers to frameworks to AI: software development keeps moving toward higher abstraction, faster feedback, and clearer intent.

I wrote my first program when I was eight years old.

It was written in BASIC, and getting from source code to something runnable was not a smooth, invisible experience. I had to run the compile commands myself, create the intermediate files, and then run the command that linked everything into the final program.

In seventh grade, I wrote another program on an early Macintosh. It had basic animation, and this time the compiler handled the hard parts for me. I could write the program, run it, and see what happened.

That was a small experience, but it was an early lesson in the direction software development has been moving for decades: less mechanical ceremony, faster feedback, and more attention on what the developer is trying to express.

I have been fortunate to watch that movement happen in real time. In 1995, I launched my first website. In 1996, I started playing with JavaScript. I used early Visual Basic tools that gave developers more command over the interface while moving us farther away from the compiled code underneath. At a national retailer, I worked with Visual Basic, KornShell, Perl, COBOL, and JCL.

In early 2004, I was also working with Microsoft’s DTS framework, where packages and DLLs could be loaded from remote servers. DTS pointed toward distributed composition, but the development and deployment friction was real.

I was laid off at the end of 2004. .NET had recently arrived, and I decided I wanted to learn it. In 2005, I spent about four months building a property management system as a .NET Windows application.

That project taught me more than syntax. Part of the system managed properties. Part of it managed contracts. I added functionality that read Word documents, parsed contract data into contract objects, and evaluated that data inside the application. It was still a single executable with a set of DLLs, but it was the first time I really thought about software as data moving from one part of a system to another and back again.

In 2006, at a woodworking tool manufacturer, I read about web services, started exploring them, and began publishing internal APIs.

Visual Basic had already introduced me to components, and Classic ASP had introduced me to server-side web applications. .NET made reusable components explicit through classes and assemblies. With my background growing up around construction and engineering, the idea of small components being folded into larger components registered immediately. That mental model has stayed with me ever since.

Each step moved more of the work away from raw mechanics and toward composition, systems, and intent.

I have seen us go from needing a surprising amount of code to render a simple image on a page to needing a similar amount of code to retrieve data from a remote database, shape it, render it, and style it into something useful for a customer.

Looking at each shift individually, it can feel like normal technology churn. One tool replaces another. One style becomes fashionable. One platform wins, then another platform wins.

But the durable pattern is bigger than fashion.

Software development keeps moving toward higher abstraction, faster feedback, and more explicit intent.

Agentic AI is not a departure from that pattern. It is the continuation of it at a scale that makes the old movement easier to see.

From machine instructions to human logic

Writing code that spoke directly to hardware meant thinking like a machine. Assembly language required precise knowledge of registers, memory addresses, and instruction sets. High-level languages moved the programmer’s job from speaking machine to expressing logic. The compiler handled the translation.

That was the first major move up the ladder. Humans stopped describing every machine operation and started describing what they wanted the machine to accomplish.

Structured programming pushed the same idea into code organization. Goto statements and tangled control flow gave way to functions, loops, conditionals, and clearer scope. Code became more readable. Teams became more possible. The abstraction covered not just machine translation, but the organization of logic itself.

From procedures to systems

Object-oriented programming raised the abstraction from procedures to systems. Instead of writing sequences of instructions, developers modeled concepts: objects with state and behavior, relationships between entities, and encapsulated complexity.

OOP did not make complexity disappear. Nothing does. But it gave developers a way to organize software around a domain instead of around a sequence of steps. A codebase became less like a script and more like a working model of the business.

That shift matters because the human role changed. The developer spent less attention on the mechanics of flow control and more attention on the shape of the system.

From isolated programs to distributed platforms

Software eventually stopped living on one machine. Networked systems forced developers to think about latency, partial failure, distributed state, permissions, retries, and systems that did not exist entirely under their control.

Service architecture extended that change. A single application became an ecosystem of collaborating services. Complexity did not shrink, but it could be bounded, owned, and deployed in pieces.

The same thing happened with collaboration. At a national retailer, I was introduced to enterprise-grade source control in an environment with more than a hundred engineers. Source control was not a convenience there. It was a control system. Without explicit practices, the work would have turned chaotic quickly.

Then cloud and DevOps compressed the distance between writing software and running it. Provisioning that once took days or weeks could happen in minutes. CI/CD pipelines automated the integration and deployment work that used to require dedicated coordination. The feedback loop between “I wrote this” and “this is running” changed dramatically.

This is where the pattern becomes obvious: abstraction moved up, feedback got faster, and the developer’s job moved from operating individual machines toward shaping systems.

I saw the business value of that shift clearly at a mortgage SaaS provider. The company needed to move customers from on-premises deployments into secure, isolated cloud environments. The design had to protect sensitive mortgage data, scale cleanly, and be repeatable enough that the company could move every customer over time. The work was delivered three months ahead of schedule, including infrastructure as code automation. Setting up a new customer environment went from a week-long process to about four hours.

That is what good abstraction buys you. It does not make the hard problems disappear. It moves them into a system that can be repeated, reviewed, improved, and trusted.

From mechanics to expression

The language and data abstractions that followed were smaller than cloud, but they pointed in the same direction. ORMs, LINQ, lambdas, functional patterns, and async/await all moved common work away from mechanical ceremony and closer to visible intent.

A complex loop became a readable pipeline. A callback chain became sequential-looking code. Routine data access moved closer to the domain model. Package ecosystems did the same thing at a larger scale by turning thousands of solved problems into importable dependencies.

None of this eliminated the need to understand what was happening underneath. It changed where the default attention went. Developers could spend less time rebuilding the same scaffolding and more time composing systems out of known parts.

From autocomplete to agents

AI-assisted coding began as another feedback-loop compression. GitHub Copilot and its successors made boilerplate cheaper, suggestions faster, and local iteration more fluid. Humans still wrote and approved the lines, but the cost of getting to a first draft dropped.

Agentic development is different. The shift happening now is not just AI autocomplete. It is developers directing intelligent agents that can plan, execute, test, revise, and move across a codebase with far less manual keystroke-by-keystroke control.

The change is not only speed. It is the shape of the role.

Earlier development workAgentic development work
Write code directlyReview and shape code
Implement each stepDefine the outcome and constraints
Hold one workstreamOrchestrate multiple workstreams
Solve the problem manuallyDescribe the problem precisely

The long movement is from operating machines toward expressing intent. Agentic development is where that movement becomes explicit. The human contribution shifts toward framing, standards, architecture, review, and judgment.

The Shape of the Shift

Map the eras against what changed and a pattern emerges:

Machine → Logic → Systems → Platforms → Intent

Each era added a layer between the developer and raw implementation. Each layer freed some cognitive capacity for higher-order work. Not every shift did this in exactly the same way, and not every abstraction was an unqualified win. Bad abstractions create their own problems.

But the broad direction is consistent. The work keeps moving away from raw mechanics and toward clearer expression of intent.

Microservices are a useful warning here. They moved teams away from one large application, but they also moved complexity into networking, deployment, observability, retries, data ownership, versioning, and operational discipline. For some organizations, that was a better trade. For others, it was a more expensive way to recreate the same confusion across more processes.

That does not disprove the direction. It proves abstraction only helps when the surrounding practices mature with it.

The leap from AI assistance to agentic development follows the same pattern. The size of the jump is different because the unit of delegation changes. You are no longer delegating syntax completion or boilerplate. You are delegating work.

What This Changes

The next shift is not that developers stop understanding software. That is the lazy version of the argument. The shift is that more of the daily work moves from direct implementation to directing implementation.

Instead of writing every line that implements a spec, developers will spend more time defining the spec clearly enough for a system to implement. That moves more of the work toward architecture, judgment, and review. The code still matters. The implementation still matters. But the highest-leverage human contribution moves earlier in the chain.

Natural language interfaces to development pipelines will become more normal, but the phrase “natural language” can be misleading. Casual language is not enough. The valuable skill is expressing intent with precision, context, constraints, and a clear definition of done.

That makes the developer’s role more directional. The best engineers will not merely type faster with AI nearby. They will define better outcomes, maintain stronger standards, set better boundaries, and catch wrong turns earlier.

None of this means implementation knowledge becomes worthless. It means the bottleneck moves. The engineers who understand how systems work will use that knowledge to direct agents more effectively: to spot wrong turns faster, set better constraints, and catch the cases where the output looks right but is not.

This Isn’t New. It’s the Pattern

Every time one of these shifts happened, there were engineers who resisted it. High-level languages would produce inefficient code. OOP was overengineered for simple problems. Cloud was not as reliable as on-prem. Package dependencies were a security risk.

Some of those concerns were valid. That is the part hindsight often flattens. Every abstraction creates new failure modes. Every layer introduces new ways to misunderstand the system.

The point is not that the new layer is automatically better. The point is that useful abstraction wins when it lets capable people work at a higher level without losing the ability to reason about what is underneath.

The current shift is no different. The question isn’t whether agentic development changes the role. It already has. The question is whether your team understands what the new role actually requires.

It requires clear thinking, high standards, tight feedback loops, precise communication of intent, and the ability to evaluate output critically without writing every line yourself.

Those are not new skills. They are engineering leadership skills that have been valuable for decades. They have just moved closer to the center of the work.

That has already changed how I work. I can now manage multiple independent agents at the same time, and the skill feels familiar because it is closer to managing multiple developers than operating a better autocomplete tool. The better I define the architecture, the constraints, the standards, and the definition of done, the better the agents perform.

The direction has been visible for decades. Developers keep moving farther from raw mechanics and closer to judgment, intent, architecture, and orchestration. Agentic AI did not invent that movement. It made the destination harder to ignore.

← All writing