The author

Vibe coding: English as a programming language

Steven Pemberton, CWI, Amsterdam

Contents

About Me

Alan Turing on UK £50 noteLast year was the 75th anniversary of Alan Turing's 1950 paper "Computing Machinery and Intelligence".

Turing is considered the father of AI. He starts the paper with

"I propose to consider the question, 'Can machines think?'",

and introduces what is now called the Turing Test of machine intelligence.

University

Richard GrimsdaleAt university my tutor was Richard Grimsdale, who built the first ever transistorised computer.

Grimsdale's tutor was Alan Turing (making me a grand-tutee of Turing).

Post-University

MU5I (coincidentally) went on to work in the department in Manchester where Turing worked and wrote that paper.

I worked on the 5th computer in the line of computers Turing also worked on, the MU5.

Amsterdam

A project meetingMoving to The Netherlands, I co-designed the programming language that Python is based on.

I wrote part of GCC

Internet

Steven at a computer in the 80'sI was the first user of the open internet in Europe, in November 1988.

CWI set up the first European internet node (64Kbps!), and then two spin-offs to build the internet out in Europe and the Netherlands.

Web

Steven with Tim Berners-LeeI organised workshops at the first Web conference at CERN in 1994

I was chair of the HTML, XHTML, and XForms Working groups at W3C.

I co-designed HTML, CSS, XHTML, XForms, RDFa, and several others.

I still chair XForms and ixml.

Vibe coding

The first time it appeared"Vibe coding" is a new term for programming by telling an LLM what you want, and letting it doing the coding.

Coined in February 2025 by computer scientist Andrej Karpathy, co-founder of OpenAI and former AI leader at Tesla.

One dictionary called it "Word of the year 2025"

History

Vibe coding is not really new: CEOs and managers have been vibe coding for years.

It's just the intelligence was natural rather than artificial (and slower)

Declarative

I've spent most of my working life looking for and researching declarative ways to do things.

One of those is declarative programming, such as XForms, a programming language where we discovered you could program 10 to 100 times faster than with traditional procedural languages.

Declarative computing is where you describe what you want, but not how it should be achieved.

A Declarative Definition

We learn in school what numbers are, and how to add, subtract, multiply and divide.

However, when we get to square roots, we are only told:

The square root of a number is a number that when you multiply it by itself, you get the original number.

This is a declarative definition. It tells you what something is, it tells you how to recognise it, but it doesn't tell you how to calculate it.

Most people know what a square root is, few people leave school knowing how to calculate one.

A Procedural Definition

Here is a procedural definition of square root:

function f a:
{
   x ← a
   x' ← (a + 1) ÷ 2
   eps ← 1.19209290e-07
   while abs(x − x') > eps × x: 
   {
      x ← x'
      x' ← ((a ÷ x') + x') ÷ 2
   }
   return x'
}

Advantages of Declarative

Declarative coding

Vibe coding is in this respect the ultimate in declarative programming.

You say what you want, not how to achieve it.

Examples

In preparing for this talk I decided to use AI to write programs that I had written before, or to update older programs.

This was in order to compare its performance with mine.

But I also talked with several people who do vibe coding every day.

Comparison

My experience with AI text production was that I am a better writer than AIs; AIs have learned largely from mediocre text on line; I can do better than that, and I expected that to be the case with coding as well.

The process of writing, both text and code, crystallises my thinking: I understand the topic better, get new ideas, and produce better stuff as a result.

I wanted to see to what extent that worked with vibe coding as well.

Is it any good?

Vibe coding is amazing for prototyping a program.

However, there are snakes in the grass, that I will be describing.

An example:

"An LLM was used to first determine where the bottlenecks were then to figure out how to improve them.

It generated a lot of code, much of it hideous.

I extensively audited and rewrote a lot of it, and heavily edited commit messages, the cover letter and comments."

Source

An example

For a set of slides for a presentation, most people use Microsoft Power Point, or Apple Keynote, Google Slides, or one of the many Javascript packages like Prezi.

Personally I have a problem with these:

I want content that is

I call this personal digital sovereignty.

An example

Thus, for presentations, for years I have used XHTML files, which I consider the most likely format to survive a long time, and is non-proprietary. These slides are in XHTML.

I used to use a standards-based method of showing slides on the screen.

But then Google went and ripped out that part of the standard (I wonder why...), and so no current browser supports it any more (and most browsers these days are just a rebranded version of Google Chrome).

Since then I have been using an old browser that still supports it.

What I decided to do for this talk was vibe-code a program that made it seem like new browsers still support the standard, even for all my old talks.

That program is what I am now using for this talk.

The first version of the vibe code

I've got a number of XHTML files that represent slide decks for talks I give. The body of each XHTML file consists of a number of DIV elements: each DIV represents one slide. The head of the file contains a <link> to a CSS file.

I would like an XHTML+javascript file that asks for a URL for such a file, and then goes into full-screen mode and displays that file, one slide at a time, allowing me to step through the slides with arrow keys, and page up and page down keys.

(I had to go through 8 iterations to get it to what I wanted)

English is not a programming language

The text above is programming code: the code necessary to create a working program.

The first thing to remark is that programming languages are designed to be exact and unambiguous.

English isn't.

English is not a programming language

The text above is programming code: the code necessary to create a working program.

The first thing to remark is that programming languages are designed to be exact and unambiguous.

English isn't.

Same syntax, different meaning:

Safetly helmets must be worn on site Dogs must be carried on the escalator

Prompting is just like writing a standard

I have been involved in producing standards for decades:

You have to be very exact in your wording, there must be no ambiguity or vagueness.

What I noticed is that vibe coding needed much the same style of wording.

Example 1

The smallest amount of text I had to write to get a working program was:

This URL https://... leads to the definition of a language. Please implement it in C as a command-line program.

And it worked.

My conclusion in this case was that the document at the end of the link was the actual program: about 1000 lines of very precise English text.

In fact in the process, the LLM discovered one problem that I knew about, and one that I didn't.

The user interface to the resulting program was not very good.

Example 2

In testing how much detail is needed, I just prompted

Write a program to edit XHTML files.

The result was truly terrible. It was a little better with

Write a WYSIWYG program to edit XHTML files.\

But still not good.

Risk: LLMs have autistic tendencies

LLMs do exactly what you tell them to.

If you are lucky, they may ask questions if they don't completely understand, or there are things you have left out, but they will likely do just what you told them to, and guess when they have to fill in holes.

In the editor example above, it did exactly what was stated, and not what was intended.

Be careful what you wish for

We've all grown up listening to fairy tales, where a wish is granted exactly in the terms it was asked for,

Software lifecycle

Programming is not just coding: there is a whole lifecycle attached.

In fact the American Dept of Defense calculated that only 10% of the cost of a program was coding.

Teaching lifecycle

As a university lecturer, I tried to teach programming lifecycle rather than just programming.

I would set the group of students two program modules to write; they would form in groups, and choose one of the two modules, and write it.

Then they had to 'sell' their module to as many other groups as possible, and 'buy' two modules from other groups.

This taught them about documentation, and clear programming, and giving presentations.

Then they had to connect the two modules they had bought into a complete program, which taught them about reading other people's code, and debugging.

Then they had to sell that to as many groups as possible, and buy one of the others. Then they were told a change to make.

Technical Debt

This is a term that has come into fashion recently.

It refers to the result of a "we'll deal with that when the time comes" mentality.

The classic example is the year 2000 bug 'Y2K', which has been estimated to have cost the world between 300 and 600 billion dollars.

But banks are (secretly) suffering from Cobol technical debt as well.

Risk: Vibe lifecycle

No one knows or understands the code in its entirety. Maybe even how it works.

It is not documented except at a high level.

This is all potential technical debt: what will be available in the future to update or fix it.

Testing

Now that you're not producing the code yourself, you are going to need to rigorously test your programs against what you are expecting them to do.

Testing is going to be a much needed skill.

It is possible to vibe code a set of tests, but this is the same entity producing the tests as produced the code.

Risk: Consistency

One correspondent reported that every time he asked an AI to make a change to a program, he had to run a diff to check that that was all that had changed.

This is because he noted a tendency for the AI to rewrite everything, even changing names of variables, making previous code reviews no longer valid.

Risk: Hallucinations

Hallucinations by text-generating AIs are well known.

Famous examples are lawyers writing briefs that cite completely made up case law.

It is also a recurring problem in academic papers, where AIs make up fake citations to papers.

This can also happen in code production, though the compiler and loader will spot many such mistakes.

Nevertheless, the result has to be checked line by line.

Risk: Up-front Cost

At a typical cost of $25/million tokens, that is a reason for the AI owners to want to produce more tokens: you don't have much control.

As an example, a bank pays €180k/month for AI coding.

Risk: Security

You still have to check every line to make sure it's doing what you want.

And do you trust the owners of the AI not to insert tracking, or even malware?

Let me tell you a story

NI coding trick

When Unix was first made available, the creators played a nasty trick: they could log in to any Unix anywhere. How did they do it?

Step one, add to the login program:

if (user="xyz" && password="letmein") { ok }

Of course, anyone looking at the code for the login program could see this. So:

Step two, hide this code. In the compiler:

if (compiling(login.c) {
  add_code("if (user="xyz" && password="letmein") { ok }")
}

Now that code can be removed from the login program, so if you read it, you won't see that the extra code has been added.

NI coding trick

Last step, hide the code in the compiler

if compiling(cc.c) {
add_code("if (compiling(login.c) {
  add_code("if (user="xyz" && password="letmein") { ok }" }")
}

Now compile the compiler, and then remove the extra code.

Now no one can see that the compiler adds the extra code.

Ken Thompson "Reflections on Trusting Trust" 1984 https://dl.acm.org/doi/epdf/10.1145/358198.358210

"The moral is obvious. You can't trust code that you did not totally create yourself."

Risk: Quality

LLMs in general learn to program by reading everything on the internet.

In other words, they learn from every program on the internet, from good programmers, bad programmers, even evil programmers, and in general average programmers. And from programs with bugs.

AI code is unlikely to be top quality.

An example

While evaluating code produced, I came upon this example

    if (strncasecmp(t, "http://", 7) == 0) t += 7;
    else if (strncasecmp(t, "https://", 8) == 0) t += 8;
    else goto have_path;
    t = strchr(t, '/') ? strchr(t, '/') : "/";

have_path:
   ...

If a student had written this, I would have failed them.

In fact I sent the LLM back to rewrite this, and it did then make a better job of it.

Another example

Someone I knew couldn't code himself, so vibe-coded a program he needed: by hiring someone to write it for him.

Later he needed to make a change, but the original programmer was no longer available. So he re-vibe coded the program using an LLM, with the changes.

The human program: 900 lines of code.
The AI program: 2000 lines of code.

I later went back and looked at the original human-coded program, and recoded it myself: 350 lines of code.

Another example

With the slide projection program, the first version produced the slide-count at the bottom of each slide (without being asked, I might add), but with a grey font on a grey background.

So at first I didn't even realise it was a slide count: it just looked like a grey block at the bottom of the slide.

When I asked it to fix this, it was completely wrong about the cause, and so 'fixed' it completely wrong.

So I had to get it to revert the fix, and tell it exactly how to fix it.

Risk: Safety

Yesterday afternoon, an AI coding agent — Cursor running Anthropic's flagship Claude Opus 4.6 — deleted our production database and all volume-level backups in a single API call to Railway, our infrastructure provider.

It took 9 seconds.

The agent then, when asked to explain itself, produced a written confession enumerating the specific safety rules it had violated.

Source

Another example

An LLM destroys all the work

Risk: Privacy

Thousands of Vibe-Coded Apps Expose Corporate and Personal Data on the Open Web

Source

Risk: Copyright

In the US copyright only covers the output of humans.

Machine output is not covered.

This is good news, and bad news.

Bad news for companies: if they use AI to build software, anyone can copy and use it for free.

Good news for programmers: if companies want to claim copyright on a piece of software, a human has to have done creative work, not just checked the output from the AI.

Ethical objections

There are complaints about

There are worries about

There are objections to AI being trained on data without permission.

Risk: The loss of ability

To check the output of AI, you have to understand what you are looking at. That is learned knowledge through experience.

Let me tell you a story. I once hosted a group of American colleagues at a meal in my house, and after the main course, I said "I was thinking of making an apple pie for dessert. Does that suit you?".

They were uniformly shocked that I could make an apple pie from scratch between courses. Americans! Not one of them had ever made an apple pie.

What I have discovered doing vibe coding is that you really need to know what you are doing: the AI is a helper, sometimes a really good one, and sometime a really bad one. You need to be able to tell the difference.

Conclusion

Be careful what you wish for.

Don't trust the results.

Test, test, test

Watch out for technical debt.