All writing

Programming in High Level

From machine instructions to natural language: what we gain with each new layer of abstraction, and why our experience still matters.

When we write a function in a language such as Python or Java, we are already accepting that another tool will handle a large part of the work. We do not choose every instruction the processor executes. We do not decide, line by line, which CPU register will store the value. We rely on programming languages, compilers, frameworks, and operating systems to turn what we write into something the computer can understand and execute.

That distance from the hardware usually feels perfectly normal. Until a new tool lets us work a little further away from it.

We can now describe a task in natural language and ask an AI model to produce an implementation. The request can be in English, Portuguese, or another language the model understands. For someone who has spent years developing the skill of writing code, that can raise a perfectly understandable concern: How much of what I know is still valuable?

The starting point for this reflection is Otavio Lemos’s video “Will AI put an end to programming?” (in Portuguese). In the section on the history of computing, he describes programming with AI as another layer of abstraction. I find that perspective useful for understanding both the technical innovation and the resistance it provokes.

The layers we build on

An abstraction lets us work on a problem without manipulating every detail of its implementation all the time. We can arrange some of these layers like this:

Layer What we express directly
Binary language All that an Intel or Apple Silicon microprocessor can understand.
Assembly Non-binary instructions, using simple commands, labels, and symbolic addresses.
Programming languages Where we were: calculations, functions, types, conditions, loops, etc.
Natural language with AI Where we are now: goals, examples, and constraints that the model uses to implement the code.

This outline simplifies a history with many more branches. The layers coexist, and whether a language is compiled or interpreted does not, by itself, determine its level of abstraction. Libraries, frameworks, tools and IDEs also let us delegate decisions that once had to be made one by one.

The practical effect is familiar: we can devote more attention to the problem we want to solve. For example, to calculate an arithmetic mean, we can write an expression using numbers and variables, leaving the compiler to select assembly instructions and CPU registers. Low-level details still exist, built into the tools and available when we need to investigate what they are doing.

We have been here before

This delegation has met resistance before. In a 1974 memorandum, Betty Holberton recalled Fortran tests carried out in 1957 and reported that programmers at her laboratory feared this new way of programming could threaten their livelihoods. Concern about the economic value of a skill has always been there, long before AI assistants.

There were good technical reasons for skepticism, too. In his history of Fortran, John Backus described doubts about the efficiency of automatically produced programs. Some of those doubts came from experience with earlier attempts that had made programs slower. Making a compiler worthy of trust required engineering work.

That seems essential to today’s discussion. We can recognize resistance to change while taking criticism about quality, control, and reliability seriously. A new tool needs to demonstrate where it works well. It needs to prove itself in practice.

When a skill becomes part of who we are

There is also a more personal difficulty. A skill is often a source of pride. It is the result of a great deal of dedication and study, and it becomes part of our professional identity. When a tool starts doing that task, the disruption can go beyond learning a new interface. We may feel that something that took years has suddenly become irrelevant.

Some tasks really can lose economic value as they become cheaper to perform. Knowing how to do something manually becomes less of a differentiator when many people can get an acceptable result with the help of a tool. Even so, the value of experience also depends on the ability to recognize when a result is inadequate and why.

Programming languages also leave questions open

With AI models, that evaluation deserves particular attention. Otavio himself points out the limits of the compiler analogy. A programming language has formal rules; a request in natural language can leave important decisions open. The model can also produce different implementations for the same request. It does not offer the same determinism in translation that we expect from a compiler, which, in turn, also cannot guarantee that the program we wrote solves the problem in the best possible way.

Consider this request:

Calculate the total of approved payments.

An implementation in Python could be:

total_cents = sum(
    payment["amount_cents"]
    for payment in payments
    if payment["status"] == "approved"
)

The code adds integer amounts in cents and filters by status. But the request left quite a lot undefined. Are all the payments in the same currency? Does the list already cover only the intended period? How should refunds be handled? Should an approved payment that has not yet settled count toward the total?

We can clarify those rules in the request and ask for tests using concrete examples. We can also inspect the code, consult someone who understands the process, and check the system’s behavior. Experience shows up in the questions we choose and how we evaluate the answers. A short implementation can hide a difficult business problem.

Experience still has its place

That is why I see value in continuing to learn what exists in the lower layers. Understanding memory helps us investigate excessive consumption. Understanding databases helps us recognize a query that will get worse as the data grows. Understanding concurrency helps us spot a failure that a single-threaded test would miss. That knowledge can guide a tool even when it writes much of the code.

My bet is that it is worth learning to work at this new level while remaining willing to move down to the lower layers when the problem demands it. I like to think that my past experience will help me define what to build more clearly, recognize limitations, and verify results. Without, of course, giving up the staggering productivity gains this new level offers.

Programming already involves entrusting part of our work to other tools. With AI, we are renegotiating how large that part should be and the criteria for trusting it. Walking away from the table and giving up those productivity gains would be a mistake. That is the negotiation I intend to focus from now on.

Your perspective

Continue the conversation

Leave a comment with just your name and message. No account, sign-in, or email required.

A spam check may appear. Your comments await moderation until one has been approved.

Loading comments…

This discussion is for the English version. The Portuguese version has its own comments.