Tuesday, 22 July 2025

Vibe Coding with Cursor

Recently we hear all the time about how AI is going to replace nearly all jobs, and in particular how nobody will need software engineers any more because AI can write all the code. I don’t believe that for a moment, any more than I believed the same thing of ICL’s much-hyped “The Last One” in 1981.

People talk a lot of about “vibe coding”, which means getting AI to write code that you have absolutely no idea how to do yourself. When it inevitably doesn’t work, you tell the AI thing what’s wrong, and it fixes it. It sounds too good to be true - and I suspect is. But AI can certainly simplify and accelerate a lot of routine coding for things like web interfaces, which probably make up well over half of all the software out there. For sure there will be job losses. 

A few weeks ago I downloaded the new AI-focussed editor and IDE, Cursor. I’d heard a lot about it from a friend of mine who in addition to being a high-powered investment banker and private pilot, also spends a lot of time writing code just for fun.

I’d just been finally getting my head around the finer points of Shor’s algorithm for factoring huge numbers using quantum computing, including an optimized implementation of all the underlying non-quantum math. I asked Cursor to write the same thing, in Kotlin. It did a respectable job, though for production use, even pre-quantum, it would have taken a lot more work. Just for fun I also got it to write what must surely be the only implementation of a quantum algorithm in Cobol, too. I’ve thankfully never written any Cobol in my life, but I remember it from the Danial McCracken book that I read when I was about 16. The code looked convincing.

Then my friend wrote to me in amazement at the latest thing he had got Cursor to do. There is some pretty amazing stuff in there. His program scrapes PDF documents describing airports and other aviation stuff. It’s all completely unstructured, and varies greatly between countries. Yet with a lot of help from Cursor he has built a complete, structured database of this information and - his latest effort that amazed him - a powerful web front-end to access it.

It was time for me to do something myself. A while back I wrote a program to help solve and investigate Wordle puzzles. It started in Kotlin, but I rewrote it in C++, taking advantage of the highly parallel AVX instructions available on the latest CPUs. The user interface is a classic CLI, just as it would have been 50 years ago.

I’d often thought it would be nice to have a web front-end, that would look like the Wordle phone app plus a bunch of extra features. But I have no idea how to write a modern web GUI, using the current tools like React, and no enthusiasm at all to spend weeks getting my head around them. So nothing happened.

But this was the perfect opportunity to see what Cursor could really do. Could I just tell it to write a web front-end to my existing 25,000 or so lines of highly optimized C++?

Before I dive into the details, here’s a summary of how it went. Sometimes you tell it to create something which seems pretty complicated, and it writes a bunch of code that works first or maybe second time. That really is amazing. Other times it just goes round in circles, generating something that doesn’t work, and the correcting it based on feedback - into something that doesn’t work for a completely different reason. One item took me a whole afternoon of going round in circles like this before it finally worked.

After a couple of days of not very intensive work, I have a working front-end and the necessary back-end support. If I’d done it myself, the actual coding might not have taken much longer than that, but it would have taken weeks to learn enough about React, even with the usual help from Google and StackOverflow. And I would have gone mad with frustration trying to find a working package to interface a Rest API to C++. (Ironically, I created a very powerful interface that does exactly that for my day-job software, but the solution is way too heavyweight for what I had in mind here).

It’s surprising how often Cursor creates something which doesn’t work, then when you tell it what hasn’t worked, it says, “oh yes, to make that work you need to do such-and-such - would you like me to do it?” Typing “yes” does the trick, and the it runs into another thing that doesn’t work but which it knows how to fix. And so on and so on, utnil eventually you get something that does work. But you can’t help wondering, if it knew all that, why it didn’t get it right in the first place.

When I had got it all working I asked my son, who works with React all day long, to take a look at the React code it had generated. His verdict: “It's sort of the right shape for React but quite brutally ugly”.

Now for the Details

I started by running Cursor in the directory containing all my C++ code, which it obligingly listed in a pane on the left side of the screen. Then I said something like “create a web front-end that accesses the functionality of my Wordle program here”.

It hummed and whirred for a bit and then produced some React code for the front-end. Then it said, “would you like me to create the back-end too?” Well, yes, that was the whole point. Over the next few days I got really good at typing “yes”.

The result was a bit of a surprise. It used a package called Crow to build a Rest API to its very own, very basic Wordle implementation, completely ignoring my code. That didn’t bother me too much - I expected to have to figure out an interface to the real back-end code that understands Wordle and all the complex algorithms involved. It took a couple of hours of refactoring my C++ code and inserting appropriate hooks in my new Cursor-created web_server.cpp file.

Then followed a seriously frustrating session. From the browser I could create a new game, but every attempt to interact with it just completely blocked at the browser end. It took a while to figure out that this was due to an arcanity called Cross-Object Resource Scripting (CORS). I confess to not fully understanding what this is, but the way Cursor had used React meant that it had to work. And it didn’t.

I spent ages googling, and trying to get Cursor to understand the problem and fix it. But it just kept going round in circles, telling about all kinds of completely irrelevant possible solutions. When a browser sees that a CORS interaction is about to happen, it sends a special OPTIONS request to find out whether the target is willing to support it. It’s just a question of adding a couple of text lines to the HTTP header. But whatever I did, these magic lines absolutely would not appear in my server’s HTTP response.

Finally, after a couple of hours, I discovered why, in the Crow documentation (which of course I hadn’t read before). Turns out that Crow refuses to let you modify the response to an OPTION request. I’ve no idea what the logic behind this is, but it makes it useless for this particular use case.

So… I said to Cursor, “generate the server for me using a package other than Crow”. It hit upon another package called Pistache, and generated the code to use that instead. The next hour or so gave me my best “typing yes” practice. The initial implementation wouldn’t build. Cursor identified an incompatibility between the code it had written and the version of Pistache it had installed. It then alternated between fixing its own code, and trying different versions and builds of Pistache. We went round that loop about 20 times before finally getting Pistache to work.

It turns out that Pistache is perpetually at version 0.99.xx, with the 'xx' varying on a daily basis and with an advertised total absence of backward compatibility. But in the end, it did work. I have absolutely no idea what I would have to do if I wanted to re-create the build environment.

Very quickly after that I had a rudimentary Wordle page that worked the way I expected it to, which was a pleasant surprise. I had spent maybe four hours of actual work, including the frustrating session with the useless Crow library.

Extensions

Now it was time to add all the extra functionality I wanted. The first things I added were how many possible words remain, and some suggestions for the best next word to try. Both can be turned on or off via respective checkboxes. Cursor did a great job here. It generated both the front-end and the back-end code and it took only a couple of iterations to get it to work properly. I was duly impressed.

The next item went much less well. The Wordle guesses are shown in a grid, with one word on each line, each cell coloured appropriately based on whether the letter is in the right place, the wrong place, or doesn’t appear at all. On the New York Times phone app, you type directly into the next, empty line in the grid. But Cursor had created a separate text box where you type, which then gets copied into the grid based on the result delivered by the back-end.

That’s functional, but not very pretty. I told it to make letters appear directly in the grid. It thought for a while, and generated a bunch of code. Nothing worked. You typed, and nothing appeared anywhere. It had explained that the text box was still there, and you’re still typing into it, but it’s hidden, and there’s code to move the letters into the right place as they are typed. Fair enough, if it works - but it didn’t.

It took a lot of iterations to get this to work as it should. But still, the letters weren’t being coloured based on the result, which defeats the whole purpose. And in the middle of trying to fix this, Cursor got stuck, running at 100% CPU and doing nothing. It often takes a while to figure stuff out, but this lasted for over an hour. I terminated it and restarted it. Coincidentally or not, soon afterwards it said that the log was too long and I would have to delete it to continue.

Left with no choice I did exactly that. But it wasn’t a good move. All the prior context of what it had done was lost. When I now said that the colouring wasn’t happening. it went off on several tangents to do with the code that colours CLI output, which is completely irrelevant to the web version. That was a very frustrating 10 minutes of saying “it’s your code that’s broken, nothing to do with this other class.”

Finally, in an oops moment, it realised it had changed the front-end code to expect a vector of guess results, but hadn’t changed the back-end accordingly. Once discovered, it was easy to fix. But it had taken most of an afternoon to get that far.

I once had a colleague a bit like that. He was a smart engineer and most of his work was good, but he would invariably break something, somewhere. When I pointed that out, he was very apologetic and rushed off to fix it - promptly breaking something completely unrelated. After he had left our company, his legacy included the most subtle, complex Heisen-bug I have ever experienced. It took over a week to find, finally done by reading every single line of every commit he had made in his final year with us. And even then it wasn’t obvious. Working with Cursor gives me a similar feeling.

After that unpleasant interval, though, things went amazingly well. I wanted to add a picture of a keyboard, with letters known to be inapplicable greyed out. I told it exactly that, no more, and it got it right first time. Even the aesthetics were good. Then I asked it to make the keyboard clickable, as a way to enter letters instead of typing them on the keyboard. That also worked perfectly first time.

Having got that far, I decided to pause and write about what I’d down, before I forgot it all. There is still plenty left to do. My first experience of vibe coding has been pretty positive. In a couple of days I’ve done something that would have taken weeks, and which in practice I would just never have done.

Saturday, 24 May 2025

The Kingdom of Two Sicilies

We were recently in and around Naples. Inevitably you learn about local history, and not only Pompei and Herculaneum. And so you learn that in the first part of the 19th century, Naples was the capital of the Kingdom of Two Sicilies.

A quick look at the map will confirm two facts you probably already knew: Naples isn't in Sicily (either of them), and there is only one Sicily. So, why was there a Kingdom of Two Sicilies, and why was Naples the capital?

And thus begins a long descent into Wikipedia and Italian history - although Italy, as a country, didn't exist until 1861. Which, not by coincidence, was the end of the Kingdom, whose existence lasted just 34 years from 1816.

It all started in the year 999, when Norman pilgrims returning from Jerusalem happened to be staying with Prince Guaimar III in Salerno, south of Naples. While they were there, the city was attacked by Saracens. The Normans, who were made of tougher stuff than the locals, ridiculed and attacked the besiegers, in an episode reminiscent of John Cleese in Monty Python and the Holy Grail.

Yes, this is the same Normans who a few years later invaded England, winning the Battle of Hastings in 1066 and placing England under Norman control for the next couple of centuries. They were evidently a pretty convincing bunch in battle. It's a long way from Normandy to Sicily, but they got about a lot.

After their help to the Prince of Salerno, the Normans were welcome back any time. Comparing Sicily - lovely weather, great food - to Normandy, it's understandable that plenty of Normans fancied a visit to see for themselves. Mediterranean tourism is nothing new, even before Ryanair.

The history of the period immediately following is very confused. There were a lot of battles, during which the Normans gradually accumulated more power and territory. What is certain is that in 1061, Robert and Roger Guiscard took control of Sicily from a bunch of feuding fiefdoms. With Sicily as a base, they gradually moved the boundaries of their local empire eastwards and northwards. In 1077 they reached Naples and took control of it. In 1130, the Kingdom of Sicily was formally established with the blessing of Pope Innocent II. Its capital was Palermo, which is definitely in Sicily.

The Normans evidently got fed up with Sicily. In 1198 the throne passed to Frederick II of the House of Hohenstaufen. As you may guess, he wasn't Sicilian. Their base was in Swabia, their capital near present-day Stuttgart. They were in turn replaced by Charles I of Anjou in France in 1266.

Things came to a head in 1282, when the Sicilian population got fed up with all this remote rule and threw them all out in the War of the Sicilian Vespers (Lambrettas were still a few centuries away). The throne of Sicily passed to Frederick III of Barcelona. Remote working is nothing new.

It took a while for the dust to settle, at the Peace of Caltabelotta in 1302. The Kingdom of Sicily was divided into two parts, the island itself and the mainland part. But the subsequent naming was surreal. The island part became officially the Kingdom of Trinacria, though still generally referred to as the Kingdom of Sicily. The mainland part was officially called... the Kingdom of Sicily, though generally referred to as the Kingdom of Naples. Makes perfect sense, n'est-ce pas?

This odd state of affairs had a very long life. In 1759, the King of Sicily (meaning Naples not including Sicily) was Charles VII of the House of Bourbon, which is to say French. But then he got king-hunted, and decided to take the offered new job as King of Spain. That left a vacancy in Naples, which Charles filled with his son Ferdinand. One of Charles' last acts as King of Naples was to start the construction of the largest monument to megalomania in Europe, the Palace of Caserta, just north of Naples. The building itself is vast, with over 1200 rooms, while the Versailles-like garden stretches over 3 kilometres.

In 1799, Napoleon attacked Naples and briefly took control of it. Ferdinand was forced to flee to Sicily (the island), which was protected by the British under Nelson. Sicily was a British protectorate from 1806 to 1814, which I suspect not many people in Britain know.

In 1815 Napoleon was defeated and the British lost interest in Sicily. Ferdinand took control again. His stay on the island evidently hadn't endeared it to him, because he took the opportunity to wipe out the other Kingdom of Sicily and to take control of both of them. The resulting joint venture he renamed (as you may have guessed) the Kingdom of the Two Sicilies. The islanders understandably weren't keen on this and revolted, but this and subsequent rebellions were brutally suppressed by Ferdinand and again by his son, Ferdinand II with support from Austria.

The Kingdom of the Two Sicilies only had a short life, though. In 1860 Garibaldi, as the head of the new united country of Italy, attacked and conquered Sicily. In 1861, everything became part of the Kingdom of Italy. If you'd like to know more, I suggest starting with the Wikipedia article. You will soon find yourself drawn into the complete history, as I was.

Thursday, 15 May 2025

Quantum Computing and Navigation - the State of the Art

I was fortunate to get tickets to the Economist's "Commercialising Quantum" conference on 13/14th May 2025. Over two days there were presentations and panels from people from manufacturers, researchers and other industry figures. Like all conferences, it was a bit of a mixed bag. But here are the main points that struck me.

When Will it be Useful?

Realistically, "quantum superiority" for a limited class of applications is probably 3-5 years away. IBM said 3, they're probably being optimistic though. "Q-Moore's Law" seems to hold - the number of qubits roughly doubles each year.

Strong consensus that the likely first application is chemistry and materials science (which is just a special case of chemistry anyway). For this you don't need anything spectacular, as soon as you have enough reliable ("logical") qubits to do more than conventional computers can (say 30-40), you have something you can use.

Error Correction

Raw physical qubits are extremely unreliable - error rates of 10-2 or worse. To make it useful, you need very powerful error correction. Masses of effort in this right now. The problem is that first, it takes a lot of physical qubits to create a single usefully-reliable logical qubit, and second, error correction is (relatively) slow. That matters, because for some technologies you only have microseconds before the whole thing turns to mush due to decoherence.

People talked about "logical qubits" without saying what they meant in terms of physical per logical. You can build a logical qubit (lqubit) with nine physical qubits, but it won't get you anywhere close to the reliability you need. Current estimates are that it will take 100-1000 physical qubits to make one useful logical qubit. So if your problem needs 100 logical qubits, you need at least 10,000 physical qubits. It's worse than that. To achieve an overall say 10-2 reliability, the reliability you need from each logical qubit increases with the number of them. So the number of physical qubits you need increases with the square of the complexity of the problem.

One company (Riverlane) has built an off-line error correction box, a 1U package using lots of FPGAs for speed. It sounds improbable, but they claim it works. You still have to program all the guard-bits in your quantum program, which is non-trivial, but they take care of the decoding.

How - Quantum Technologies

There are several competing raw physics approaches to building a quantum computer: superconducting, neutral atom, photonic, topological, trapped ion, quantum dot. There is a good survey article here . They all have been made to work at "toy" scale, and they all have $Bs of investment and serious companies (MS, Google, IBM, ...) behind them. They all have serious drawbacks, and none have been made to work at useful scale.

Clearly there will eventually be a winner, maybe two. I think it's fair to say that at this point nobody (who doesn't have a dog in the race) has the faintest idea which. It's not even certain that ANY of them can be made to work at scale, though given the $$$ and sheer number of quantum physics PhDs being thrown at them, something will probably emerge.

Crypto

THE talked-about QC application is cryptography, or rather breaking it. The nirvana is (relatively) rapid factorization of 2048-bit RSA public keys. It's still a long way off. Right now the estimate is that it will take about 10 million physical qubits. Assuming Q-Moore's Law, that is 15 years away. Supposing improvements in algorithms and error correction reduce that by a factor 10, call it 10 years. Still a long way off. (And "rapid" means in several hours, not seconds or microseconds).

Even so, there has been a lot of work on "post quantum cryptography" (PQC), i.e. cryptography which is resilient to attack using quantum techniques. NIST in the US has blessed several techniques. My guess is that the world will move fairly rapidly to using these, say within the next 3 years. That matters because for really critical stuff (like defence designs), state actors are already storing encrypted data hoping they'll be able to decode it "one day".

QC and AI

There were several sessions claiming to talk about this, but all the ones I attended were content free. Everyone agrees that QC will be part of the AI toolbox, but beyond that nobody had much to say.

Deployment

There were several companies proposing different kinds of "make QC usable for you" services and techniques. I'm 100% sure that this is the only way any "normal" software engineers will ever be able to use it, so this will be a big market. One day. 

Non-Computing Stuff - Quantum Navigation

Several sessions were about quantum-based navigation, i.e. getting GPS-like benefits without needing external radio signals. This is a huge deal because there are large parts of the world where GPS is unusable due to jamming and spoofing. There are two techniques, both dependent on fairly miraculous quantum technology. One is quantum INS - building accelerometers and gyroscopes that are orders of magnitude more stable than you get with classical techniques. The other is quantum gravimetry - measuring the local strength of the earth's magnetic field. Using that, you can relate your position to a map (which are available) and have a position accurate to within a few hundred metres.

The technology of quantum gravimetry is really mind-boggling, but a bit long to fit in the margin here. Basically it involves measuring the difference in position between two superposed quantum states of the same atom. If that seems reasonable to you, you have your head around quantum stuff a lot better than I do.