The Sinclair ZX Spectrum Keyboard

When I was 12 years old, I got sight of an actual computer. One day at my cousins’ house, set on a table and wired up to their TV was a small, black rectangle. They were pressing keys on it to play games (Schizoids and Ant Attack I remember). I was curious – the games looked more interesting than the simple arcade games I played on my Atari console. I got closer and peered over and saw the keyboard and it changed my life. Here’s what I saw:

By Bill Bertram - Own work, CC BY-SA 2.5,

This was a 16K Sinclair ZX Spectrum. What on earth did all those words and symbols mean? It looked like it was made by aliens to control a spaceship.

For playing games, the keyboard was mostly left untouched: Q was up, A was down, O was left and P was right. I later heard that you could use the rest of the keyboard for “programming”. What was that? I had to know more.
But this was the early 1980s and there was no way for me to find out. The library had nothing. There was nothing on TV yet. School – forget it. Parents – not a chance.

I had a paper-round and about that time, a new weekly magazine was launched:

click to read

I bought a copy every Saturday (⅕th of my weekly wage) and read every word. In the first issue, they started a “learn BASIC programming” course and I followed along. It was all very strange: variables and loops. But I got the gist of it and started writing out simple programs in a notebook, ready in case I ever got a computer of my own.

The home computer market was exploding in the UK. Only a couple of years earlier, the machines had monochrome displays and 1K of memory. Now they had fifty times more memory, colourful graphics and sound effects. There were suddenly dozens of computers with similar features to the Spectrum and the Home Computer Course reviewed one in depth each week.

In most cases, the keyboard was an integral part of the computer, but they all had very dull keyboards compared to the Spectrum. The Commodore ones for example (C64 and VIC20) looked like this:

And the (much more expensive) BBC micro looked like this:

By BBC_Micro.jpeg: Stuart Bradyderivative work: Ubcule (talk) - BBC_Micro.jpeg, Public Domain,

They had some weird squiggles like * ~ and # but the Spectrum had those in addition to all the other alien voodoo.

With hindsight, there was a British class thing going on between the families who owned Spectrums and those who owned BBC machines – but that’s for another blog post. As is the effect that Thatcherite policies via entrepreneurs like Clive Sinclair had on people like me.

The ZX Spectrum keyboard was very special. The QWERTY layout was based on a typewriter, although the space key was tucked away in the bottom corner: this was not designed for typists. It had rows of small, soft keys – each one a multifaceted jewel packed with powerful incantations. Often ridiculed for its rubberiness, not many commented on the multilayered design. Most of the keys had 6 different functions. The H key for example:

  • at the start of a program line would give the GOSUB keyword
  • elsewhere would give the letter ‘h’
  • with caps shift would give the uppercase letter ‘H’
  • in extended mode would give the SQR keyword
  • in extended mode with shift would give the CIRCLE keyword
  • with symbol shift would give the ^ symbol

My parents knew I wanted a computer, but I wasn’t expecting to get one. Then the following Christmas I received a ZX Spectrum+. This had 48K of memory and had an updated keyboard:

This keyboard was in a more sober black and white and, at first glance, not as bejewelled but all the mysterious markings were still there. When it was switched on it gave a blank screen with a message at the bottom:

© 1982 Sinclair Research Ltd

Pressing a key gave a flashing cursor:

Nothing else; just a throbbing K. For a 13 year old this was very intriguing. An invitation to work out how to talk to the machine.

There was a line editor. To program in Sinclair BASIC you typed a line number to specify the sequence and then pressed a key to give the keyword and followed it by variables, literals and possibly more keywords. The one-key one-keyword system had several advantages. First, it saved memory. With only a few kilobytes available, every byte counted. Storing each token as a single byte saved lots of space. For example, 1 byte for GOSUB instead of 6 for G, O, S, U, B, plus a space. It also meant the parser could be smaller: no need to check for accurate spelling or the case of “GOSUB” – it was already tokenised. A side-effect of this was that the user had less typing to do and had less chance for typing errors. But I think a crucial side-effect was that all the keywords were printed on the keys. Many of these are familiar words almost forty years later, but back then they were magical words. Words such as DATA, BREAK, GOSUB, ENTER, POKE and INPUT.

As my programming reached the next level, using an actual computer, I began to use more and more of those words and symbols. I even learnt of two new colours: Cyan and Magenta. A few of the keywords were rarely needed and some I would never use because they were for controlling disk drives (CAT, FORMAT) and I only had cassette tape for storage. But some remained unknown, even after trying to read the manual entries and testing them out (they mostly gave syntax errors or strange numbers). These turned out to be the mathematical functions but I couldn’t grasp why they were there – maths for me at the time was nothing more than long division and fractions.

I mostly tried to program games. Starting with laboriously typing in program listings from computer magazines such as Sinclair Programs. This was the first one I bought:

click to read

I drew inspiration from many commercial games. A few of my favourite ones were:

(game screenshots from

These were all the more enjoyable for having to wait several minutes for them to load:

I should admit that I paid for none of the early games – they were swapped in the playground and copied tape-to-tape.

The manuals for the Spectrum were excellent. I never mastered the Z80 machine language but developed a variety of BASIC programs, all stored on cassette tape. I don’t know what people thought I was doing on it all day – they never asked. Some of the types of things I was developing:

  • platform games (mostly trying to copy David Jones’s work – Spellbound especially)
  • platform game room editors
  • football and tennis games (mostly trying to copy Jon Ritman’s Match Day)
  • space flight games (turn-based and simulators)
  • graphics drawing programs (tools for creating game assets)
  • font creating programs
  • teletext systems
  • word processors
  • programming languages
  • database programs
  • weather maps
  • connect 4 (with the computer as an opponent)
  • assemblers
  • text adventure games (which smelt of Artificial Intelligence in many ways)
  • text adventure game builders (like the Quill)
  • text and graphics adventure games (based on one or two screenshots I’d seen of Ultima)

I spent a lot of time trying to work around the limitations of the machine, for example trying get more than 32 characters on a line, like Tasword managed to do:

I learned how to convert between binary and decimal, for creating graphical characters on an 8 by 8 grid. I made re-usable templates covered in cellophane.

Some of my projects failed because I was missing some key knowledge. Any time I wanted to do a physical simulation, such as a pool table or give a 3D perspective, I would be stumped. For example, I really wanted to write a flight simulator and needed to draw a false horizon instrument.

I could draw a circle for the outline using the CIRCLE command. And I could draw a horizon line from one point to another but as the line tilted, its ends would go outside the circle. How could I make the line ends move to fit inside the circle? I tried a few obvious things like shortening it by a pixel for each tilt step but that cut the corners and gave a diagonal sweep inside the circle. I was stuck. I didn’t know what to ask, let alone know anyone who could help.

It was only many years later, long after secondary school even, that I realised some of those inscrutable keywords would have helped:

The SIN, COS and TAN functions (and their inverses, ASN, ACS and ATN) and the PI constant (which would have been even more intriguing had they put the π symbol on there – the earlier ZX81 had it):

These functions would have solved many of my problems. How was the teaching of trigonometry at school so dull that I never linked any of it with my passionate interests? It was presented with no contextual or historical introduction and simply shown as a way to find missing parts of triangles with the sole purpose of answering exam questions (which I did well at, but truly understood very little). I am still amazed by how much of the maths education I received managed to completely miss my innate interest in the subject. It was all made so matter-of-fact and detached and never something to be understood or marvelled at. Here’s how it should be done:

Despite people telling me to “get outside more instead of staring at a screen”, all my early attempts to emulate the programs I liked would come in handy when I later (accidentally) did a degree in Computer Science. There we’d come across similar problems and I’d discover that someone in the 1960s had already thought about it and solved it. Things like how to draw a straight line on a bitmapped screen, how to project a 3D model onto a flat screen, how to parse a language and how to have a natural language conversation with a computer about facts. Having the time to think about these problems in isolation made them all the more enjoyable to study later. I’m still studying them today.

Now I’d like to contrast having a machine like the Spectrum as a child against a couple of alternatives: one co-temporary with the Spectrum, and one more recent.

To play games in most other countries in the 1980s you would most likely have used a home console, for example, the Atari 2600

By Evan-Amos - Own work, Public Domain,

Or the Nintendo Entertainment System (NES):

By Evan-Amos - Own work, Public Domain,

These had no keyboards, just joysticks, and no way of creating your own games. A whole generation of would-be programmers was left waggling.

The Spectrum was released in the US as a Timex, but I don’t think it did so well:

The NES was originally going to be more like this:

By Russell Bernice and Chris Donlan ("Doonvas"), CC BY 2.0,

What a difference that would have made.

Today, younger generations are faced with something equally as closed:

Introducing iPads into primary schools to teach kids “computing” is probably not going to have the desired effect. Ironic coming from the company who created this:

By Ed Uthman - originally posted to Flickr as Apple I Computer, CC BY-SA 2.0,

Some lessons I think:

  • A flashing cursor (blank page) with some enticing pointers to make your own things can be a better invitation to learn than a set of menus, or a step by step tutorial or a pre-built app.
  • Don’t over-simplify something by hiding things: lead them on with intrigue and enigmatic references. Keep the most advanced things visible and accessible. This worked for me another time with Chemistry lessons. They were fairly dull (again a subject I was fascinated with before school) but there was one thing that a teacher said to us which made me consider doing an advanced course. It was a bombshell to me along the lines of “of course this [the Bohr model of the atom] is all wrong, but I can’t explain why here – you’ll need to study A-level to see why.”)
  • We’ve grown used to it over a couple of decades but the ability to find out how to do anything on the internet is truly amazing and removes so many barriers for so many people.

That Cambrian explosion of home computers will live forever. They’re emulated in software now and so are reincarnated in every new wave of machines. There’s even a Spectrum one as an easter-egg in a well-known TV broadcaster’s Film Scheduling system – ahem.

Here’s just one ZX Spectrum emulator that runs in a web browser:


Unfortunately the keyboards we have now are all the same, unadorned by gems, but their interconnectedness means we can share and find our own jewels.

Order Yourselves

FuseOrderAre you going to a festive, company meal this year? Many restaurants want you to pre-order your food. This usually involves a number of frustrating, error-prone steps1. And, unlike ordering at the table, guests are in the dark about what everyone else is choosing.

There is a better way: FuseOrder.

1. The meal organiser creates the event and adds people to invite (or makes the link available to guests).

2. As a guest, you can see who else is going and what they’ve chosen. Then you can make your selection from the menu, whenever suits you.

3. Once everyone has chosen, the organiser locks the event and can make it available to the restaurant for them to approve. The restaurant also sees a summary of the order.


At the meal, everyone can be reminded of what they ordered and, if it helps, see how much theirs cost.

FuseOrder isn’t just for Christmas though. Add your own places and menus for:

  • sandwich rounds (have them prepared when it’s quiet)
  • takeaways (also helps splitting the bill)
  • office coffee rounds
  • pub rounds (get them on the bar before you arrive)
  • company/group meals
  • sporting events (e.g. bike rides, runs)
  • spa visits
  • sharing food preparation
  • conference programme choices
  • voting (e.g. for movies/games nights)
  • combining orders for party/barbeque food
  • theatre drink pre-orders
  • anniversary meals

FuseOrder: Your guests and yours hosts will love you.


Typical steps involve:
* the organiser getting hold of a menu and reserving a table for a rough number of guests
* sending a copy of the menu to the invited guests (I’ve seen some illegible photos used for this!)
* collecting all the responses and translating them into actual items on the menu
* chasing up missing and confusing responses
* handling people changing their minds
* collating a summary of the items ordered
* telephoning the restaurant and reading out the summary and confirming the number of guests
* the restaurant writing down the items and translating them into items on their menu
* handling people changing their minds too late
* the restaurant creating another copy of the ordered items for the chefs
* everyone arriving for the meal and asking “what did I order again?”
* keying the order into the till for the bill
Each of these steps is fraught with delays and chances for compounding transcription errors or omissions.

Space Invaders

Osaka Invader

We invent games to build worlds, often founded on reality. Chess is an ancient example. The chess pieces represent real-world characters from the time of the game’s creation. The medieval world had fighting kings and queens and knights on horseback and… bishops? As a child, I found it strange that there were bishops on the chess battlefield, not realising that the church used to be a more militant power.

Bishop Invader

Games let us replay history and simulate what-ifs and what-might-have-beens.

Computer games also build worlds, in ever more immersive ways. They are simulations of their time. The seminal video game Space Invaders was released by Taito in 1978. A genre-defining shoot ’em up, it introduced the concepts of multiple lives for the player and high scores.

Space Invaders screenshot

The creator of Space Invaders was Tomohiro Nishikado. This guy was driven: for over a year he designed and built every part of the game himself. He built his own hardware and composed the sound effects, programmed the game and designed the artwork.

Space Invaders was released around the time of Star Wars, not long after the race to the moon. People believe the game is about defending Earth from waves of invading alien creatures from another planet. It’s not. The game is about an earlier time.

Tomohiro Nishikado was born in the city of Osaka, Japan in March 1944.

Destructio ab Alto

Seventy years ago today, just before midnight on 13th March 1945, forty three B-29 super-fortress bombers from the US 314th Bombardment Wing (Very Heavy) arrived in formation in the night sky over Osaka. Tomohiro was just coming up to his first birthday. The US air force had control of the skies so the bombers could fly at the low level of 2,000 metres. The planes dropped hundreds of one ton bombs onto the houses below. Napalm and incendiary cluster bombs were dropped to spread fire over a wide area.

The Osaka civil defence system was no match for the attack. Ground-based anti-aircraft guns had been set up to defend against small groups of planes, not wave after wave filling the night sky. One hundred and seven bombers from the 313th Bombardment Wing (Very Heavy) formed the next waves. One hundred and twenty four bombers from the 73rd Bombardment Wing (Very Heavy) made the final attacks. 1,732 tons of bombs were dropped in three hours, destroying around 8 square miles of the city centre.

Osaka after air raid

Thousands of Osaka residents were killed and many more were injured. Over half a million people were made homeless. Two US aircraft were lost, one on take-off.

There were more heavy raids on the city in June, again with hundreds of B-29s, and then another on 14th August, 5 days after Nagasaki. A total of 10,270 tons of bombs (92% of them fire-starting) were dropped on Osaka.

space monsters

Tomohiro’s city was destroyed from above. He named his unwinnable, city-defending simulation “Space Invaders”, in English, not Japanese. The high scores and multiple lives reflect the methods of counting the human cost of the bombings. The B-29s were the aliens who invaded his space. Americans were the Space Invaders.

Osaka Invader

How your bank is tracking your phone

I strongly suspect that my credit card company and my bank have access to my mobile phone location. Here’s why:


A few weeks ago my wife was driving me to the train station. I usually drive to work but sometimes get the train. On the way we got a flat tyre and managed to limp along to the garage opposite the train station. My wife hadn’t brought her phone or purse with her so I gave her my credit card to pay for a new tyre, while I caught the train. She knew my PIN and had used it several times before to pay for meals and such without any problem, though always while I’d been there. She managed to pay for the tyre with no problems.

That morning, and for the rest of the day, I didn’t use any other payment cards to remove the chance that the credit card company and bank might spot me paying in two places at once.

Special, secret ways

The next day (so first-class post, probably posted in the morning soon after the tyre payment) I received a letter from MBNA credit cards. I knew why they’d written before I’d opened it. It said that they had issued a new card because my current card was no longer to be trusted. I don’t remember the exact phrasing, but it didn’t say what the problem was, just that they had special, secret ways to detect things and I should no longer use my card and wait for the new one. It arrived a few days later and had a whole new number which meant I had to change all my online payments.

I’d used my card over the years at some strange times of day and in a wide variety of places, but I’d never had a card cancelled before. I couldn’t fathom how they’d worked out that it wasn’t me using the card. The card companies have long been proud of their clever, secret algorithms that can spot fraudulent usage patterns, and I’d assumed they also took into account the usage location from their card machines: using a card in London at 10:00 and then again in Madrid at 11:00 would probably trigger an alert. But my card was only used once that day. I’d driven to the train station many times over the last few years, so my paying for a new tyre at that time of day wasn’t suspicious. I wondered about CCTV cameras in the garage and how male/female face detection might be happening, but ruled them out: the place wouldn’t even have cameras.


It was a few days later, watching my debit card being processed, that I realised what they must have done. They’d tracked my mobile phone and linked it to the card! My phone went with me on the train. At the time the tyre was being paid for, the phone was probably in the office with me, which meant it couldn’t be me using the card near the train station.


I’ve been thinking about how they might be doing it. So, not this, but something like this

Pattern Matching

Mobile phone companies track the movement of phones. It’s fairly easy then to pick out patterns and from these give very valuable hints to the card companies. For example, they could tell if a card is ‘at home’ or ‘has gone to the usual daily place’ so the card company could be fairly sure whether the phone has been left at home or is with the owner. They could also tell how long ago the phone had passed through a given area (and at what speed: by car or foot or train etc.), perhaps indicating that the card had been recently dropped or stolen and so making any payment attempt more suspicious. I think this is what happened in my case.

Linking level

I initially thought the card-to-phone linking was being done at a level above the two companies, because I’ve never had a mobile phone contract and didn’t think the phone company new my card number, and I certainly hadn’t given the card company my mobile phone number as a contact number. Or maybe the companies were intersecting the card payment times and places with all the mobiles in those areas at those times and growing a database of cards always used in the vicinity of specific mobile phones – quickly refining it to link each card to a single phone? That’s still possible, but then I remembered I had recently topped up the phone using that credit card, so the phone company had seen my card number and had already linked it to my phone. Perhaps during the phone top-up my phone number was also passed to the card company, so both parties would know both numbers.

Possible API

There are a number of ways the card company could be asking the phone company for the tracking data. I suspect they involve the phone company charging different fees for each method, but paying those fees would be easily justified by the reduction in fraud:

  1. Before payment time. They pre-emptively and periodically ask where the card owner’s phone is and keep track of it in their systems ready for when a payment is attempted. If the attempt is not in the expected vicinity, perhaps based on the phone travelling speed, suspect it.
  2. At payment time, before approval. When a payment transaction begins, they ask where the card owner’s phone is and if it’s not in the vicinity, suspect it.
  3. After payment time. Some time after a payment has been approved, they ask where the card owner’s phone was at the time of the payment and if it wasn’t in the vicinity, suspect it.

Perhaps they use a variety of these. Maybe 2 (at payment time) for higher value transactions, and 3 (after payment time) otherwise, since it’s cheaper. Also, 3 (after payment time) is less vulnerable to any slow-down in real-time processing by any of the checking systems, but risks having to approve payments before being able to suspect them based on the phone location.

But surely this is illegal

Checking at or after payment time (2 or 3) might make the illegality of finding out a person’s location moot, since the card company would already ‘know’ the person’s location from the payment initiation. This might be a strong reason to prefer this approach.

Another way, perhaps to reduce the privacy intrusion, would be to re-phrase the question. Instead of asking where the card owner’s phone is or was, ask whether it is or was in the vicinity of the transaction. The yes/no answer perhaps wouldn’t constitute giving away the location but would still allow the location checks to be made.

To link cards to the variety of phone companies, a single point of contact would likely be needed (either per country or perhaps on a larger scale). The existing card-processing body may have taken on this role. This could then either route the card questions to the appropriate phone company or, more likely, have access to a central ‘anti-fraud’ database, collating relevant phone movement details, and answer the questions from one place.

So my guess is that the phone companies ‘share’ their phone movement data with a third-party ‘security provider’, possibly with some government protection (remember how keen they were to prop up the banks in the national interest?). The payment processor would then make a simple API call to this third-party asking for a probability that the card owner is with the card at a specified place and time. The response could be “don’t know” if the phone seems to be ‘at home’ or is switched off. Or it could be 1 if the phone is very close to the given place at that time (which could be ‘at home’ for online payments from your home IP address). Or close to zero if the phone is nowhere near the place and has recently moved: getting closer to zero as the movement pattern approaches the standard pattern for that phone. Or maybe 0.5 if the phone was last tracked some time ago but within travelling distance of the place.

A better way to avoid privacy issues with data-sharing would be for the ‘security provider’ to just forward the “if one of your mobile phones has been linked to this card, what’s the probability that the owner is in this place at this time?” question to a number of phone companies at once and return any response. I think it would be easier to justify since the card company can say that they already ‘know’ the user’s location, as does the phone company, and all they are doing is checking that they both agree, with one of them legally holding a mapping of the card to the phone number internally. This type of continuous fact-confirming could also enable the phone company to build up and maintain a mapping of cards to phones based on proximity, as mentioned earlier. They could pre-tokenise the card numbers too, so the actual checking appears to be a random-looking number, a position and a time, with a single score as a response.

So are they breaking any laws? I don’t know. Maybe they don’t apply to this location ‘meta-data’ or especially not to the inferred meta-data if they’re using the “just checking we both agree and building co-incidence mappings” approach. But I’d like them to be more open about what they’re doing and their relationships. And I’d be interested to know when and how it first began.

I don’t think the Freedom of Information Act applies to these companies. The UK Data Protection Act should make them say which details they have about a person, but I know the information they have and that isn’t the thing. It’s how they’re inferring the connections between the information that matters. This sort of tracking and data-joining is inevitable, and privacy was probably only a brief interlude in the grand history of things.


I don’t think that this is just a UK thing. My bank used to ask me for the dates when I was travelling abroad so I could use my debit card without them declining it. A few years ago they stopped asking, and now the latest advice on their website is:

“Our fraud detection systems are constantly verifying transactions to ensure your security when you use your debit card abroad. This means you can have peace of mind that your card is protected from unauthorised use and you don’t need to let us know before you travel.
If we think a payment could be high risk, it may be declined so that we can get in touch to check it’s genuine.

To help us provide you with the best service, please keep your contact details (including mobile number) up to date, so we can get in touch with you if we need to.”

In other words, “we have new, special, world-spanning ways that you don’t need to know about. And, by the way, we very much think that you ought to give us the mobile number that you should have with you when you use your card.” And of course, you will be taking your mobile with you everywhere.

I realise this could all be a touch of paranoia (have you seen how they’re tracking your smartphone’s wifi signal around shops?)! I should really test my theory by buying a tyre with my phone on me, and then another day handing off my phone for someone to take to my office while I buy another tyre, but maybe it needs to be a payment above a certain amount. I think I’ll wait until I need another two tyres. Until then, I’d love to hear from anyone who can corroborate any of this.

“Welcome to InfoLink, the best way to organise your life.”

         █████ █   █ █████  ███  █     █████ █   █ █   ▄█ 
           █   ██  █ █     █▀ ▀█ █       █   ██  █ █ ▄█▀ 
           █   █▀█▄█ ████  █   █ █       █   █▀█▄█ ███  
           █   █  ██ █     █▄ ▄█ █       █   █  ██ █ ▀█▄  
         █████ █   █ █      ███  █████ █████ █   █ █   ▀█

I recently found one of my first shareware programs, InfoLink, tucked away in a BBS (bulletin board system) archive.

InfoLink was a personal information manager (PIM) – they were all the rage in the early 1990s. It took the hyperlinking ideas that were just being employed by the nascent world-wide-web and let the user build and edit interlinked pages of information. I suppose it would now be called a personal wiki. It distinguished between links for people, places, things and events and had a calendar to show the events. It could call out to external programs to view and edit files or send faxes.

I designed it in 1993 while I was travelling around Europe with work. I wrote it in 1994 using Turbo Pascal, which I’d won in an AI programming competition in a Computer Shopper show in London when I was 18. The indexing in InfoLink was my first implementation of a B-tree.

It still runs (via DOS emulators in Linux for me now), and looks pretty useful I think, even two decades on.

Here’s a download of the zipped INFOLINK software. The program executable is 70K.

Here’s a shot of the main index page:

And editing it shows the link tags:

See the breadcrumbs in the Route panel, and the lovely drop-shadow!:

I have the source code somewhere on a floppy disk, and the compiler on several 5¼” floppy disks. I think it would be a challenge to build it again.

Best Thing I Never Had

Beyoncé’s “Best Thing I Never Had” is a song about her saying good riddance to her boyfriend. It has some cleverly engineered but contradictory sounding lyrics:

  1. You turned out to be the best thing I never had
  2. I will always be the best thing you never had
  3. I will never be the best thing you never had

Sentences 1 and 2 use exactly the same phrase “the best thing never had” to mean directly opposing things for You and I. While sentences 2 and 3 seem to flatly contradict each other, but mean the same thing. How come?

Let’s analyse the sentences and see how they work. To make it simpler, I’ll refer to the singer as B (for Beyoncé) and him as C.

Starting with sentences 1 and 2, the trick lies with the word “best” and how its scope can be stretched in two ways, making the phrase ambiguous.

Sentence 2 (“I will always be the best thing you never had”) has the simpler interpretation. B (Beyoncé) states that she is the best thing. The word “best” is tightly bound to the word “thing” – it has a very restricted scope. So “best” here can mean its usual ‘highest valued’. And then the “you never had” is an extra bit of information that states that C (he) has never had B. The upshot is that B is the best thing. Here it is a bit more formally:

[B is a thing ∧
 ∀x[[x is a thing ∧ ¬x = B] → B has higher value than x] ∧
 ¬C had B

In sentence 1 (“You turned out to be the best thing I never had”), the not-having is being done by B. The scope of the word “best” can include the “never” and then its negation affects the interpretation of “best”. So “best” here can mean the ‘best to not have’. The best thing to not have, from her point of view, is the lowest-valued thing. So, loosely speaking, C is the worst thing. This is the key to the seemingly misworded song title.

[C is a thing ∧
 ∀x[[x is a thing ∧ ¬B had x ∧ ¬x = C] → C has lower value than x]

Sentence 3 (“I will never be the best thing you never had”) is interpreted in the same way as sentence 1 (with the parties exchanged) and then negated by the initial “never”, and not as simply a negation of sentence 2 despite the syntactic similarity. C is doing the not-having and from C’s point of view, the best thing to not have is the lowest-valued thing. So here “the best thing you never had” says that B is the lowest-value thing that C has never had. The “I will never be” inverts this to mean B is the highest-value thing that C has never had (and adds that this state will be maintained as long as B is around). So, again roughly speaking, B is the best thing.

¬[B is a thing ∧
  ∀x[[x is a thing ∧ ¬C had x ∧ ¬x = B] → B has lower value than x]

Of course, our dual interpretation of these ambiguous sentences is made in the context of the rest of the lyrics. In isolation, we could interpret them in other ways and have one of the following:

  • a) Beyoncé as the worst thing wallowing in self-deprecation singing about her missed opportunity to have the best thing (flip our interpretations above)
  • b) Beyoncé and him both being each other’s best thing and both missing out (only use one interpretation, based on our original view of sentence 2)
  • c) Beyoncé and him both being each other’s worst thing and both lucking out (only use one interpretation, based on our original view of sentence 1)

Using the open world assumption, these ‘best to not have things’ will never do. Neither party can know the value of all the things they’ve never had, so the superlatives are moot.


ThinkSQL ODBC Driver Source

The ThinkSQL ODBC driver source code is now available here.

The driver is pure Delphi but the specification is C-based and very detailed. Memory handling and complex state transitions between client and server made this a large undertaking.

The Java JDBC specification was closely based on ODBC, but garbage collection made the JDBC driver much easier to implement.

It’s worth mentioning that the Python DB API specification is tiny in comparison to the ODBC documents but led to a much simpler, smaller and more elegant driver codebase. The Python driver can do all the things that the ODBC driver can do, but with less than a tenth of the code. It is more readable and maintainable and less fragile, and easier to use. And it actually works on multiple platforms. The surprising thing was how much simpler Python made the low-level network communications (mostly thanks to the struct module), especially considering Java was originally designed for low-level systems. Compare this Python method with the Java and Delphi ones:

The Python version

def getpUCHAR_SWORD(self):
   if self.bufferPtr+_sizeof_short>self.bufferLen:
       if self.bufferPtr==self.bufferLen:
           return _fail
   si=struct.unpack('<H', s)[0]

The Java version

public String getpUCHAR_SWORD() { 
  if (bufferPtr+Global.sizeof_short>bufferLen) {
    if (bufferPtr==bufferLen) {
    else { //the buffer is not quite empty
      return Global.failString; 
  short usi=0;
  for (int siz=Global.sizeof_short-1; siz>=0; siz--) {
    short b=(short)buffer[bufferPtr+siz];
    if (b<0) {b=(short)(b+256);}
    usi = (short)(usi | b); //i.e. reverse order
  if (bufferPtr+usi>bufferLen) {
    if (bufferPtr==bufferLen) {
    else { //the buffer is not quite empty
      return Global.failString; 
  return new String(buffer,bufferPtr-usi,(int)usi-1);

The Delphi (C-like) version

function TMarshalBuffer.getpUCHAR_SWORD(
                                var puc:pUCHAR;
                                var sw:SWORD):integer;
          fail = probably means data is left in buffer, 
                 but not enough 
                 else errors as from Read
   puc has 'allocated' space allocated by caller,
   unless -1 => allocate here (but caller must free!)
   returns buffer data up to the allocated length
   (including 1 character for a null terminator)
const routine=':getpUCHAR_SWORD';
var actual:SWORD;
  if bufferPtr+sizeof(sw)>bufferLen then
    if bufferPtr=bufferLen then
    begin //the buffer is empty
      if result<>ok then exit; 
    begin //the buffer is not quite empty
      result:=fail; //buffer overflow


  if bufferPtr+sw>bufferLen then
    if bufferPtr=bufferLen then
    begin //the buffer is empty
      if result<>ok then exit; 
    begin //the buffer is not quite empty
      result:=fail; //buffer overflow

  if allocated=DYNAMIC_ALLOCATION then
    {Now allocate the space for the buffer data}

  if (allocated-sizeof(nullterm))<sw then
end; {getpUCHAR_SWORD}

The best a man can get?

For some reason I don’t really understand, I shave my face almost every day. I use a manual razor, currently a Wilkinson Sword Quattro-Iced-Titanium-Strontium-something or other. I did try to stick with a perfectly acceptable Gillette three-blade razor but was forced to upgrade to a four-blader by some clever, nationally coordinated, stocking systems. Whatever’s next? I’m now trying to avoid upgrading to a manual razor with a battery in, and an extra indicator to tell me to buy more blades.

For many years I put up with buying a new pack of blades every couple of months or so, as a single blade used to last me between 1 and 3 weeks (over £9 for a pack of 4 blades, which cost under £0.05 each to manufacture). But I could never stomach the adverts. The ones where men are hugging babies and doing man things, like driving cars and playing golf all set to a crescendoing power ballad. Especially the father’s day specials. So here’s my response to the bad adverts – a top tip that Gillette don’t want you to know that will save you hundreds of pounds: When you’ve finished shaving, dry the razor head on a towel.

That’s it: after every shave, make sure there’s no water left on the metal blades by dabbing them on a towel and your blades will last many, many times longer. I’ve been doing this for a few years, and I now only use about 3 blades a year. Do it – they’ll have less money to spend on their insulting adverts. Or grow a beard.

Think SQL

Several years ago, I spent a lot of time developing a relational database management system – ThinkSQL.

In a future post I’ll write down the reasons why, and probably release the development diaries. But for now, the source code for the server is available here:

As I say in the README:

The source code is linear per se, but while writing it, it was an organic thing, generating great interwoven trees in the computer memory and in my head that were many-layered and that were modified and traversed, and impacted on a dynamic multi-versioned data store alongside many other threads, causing and needing deep psychological flow. The code comments are released as-is, and are often streams-of-consciousness.