Thirty years ago I graduated with a degree in Mathematics and I was looking to start my career. My 21 year old self dismissed accountancy as too boring, being an actuary as even more boring and law as something I did not have the intellect to study (These days I find accountancy and actuarial science fascinating and have postgraduate legal qualifications - go figure).
The one career option that did excite me was computers. This was surely the future. The technology that was going to take over the world was Windows - the same advantages as Apple Macs, but business friendly software delivered on commodity hardware. And I wanted part of the action. I just needed to learn how to write Windows applications.
I had saved enough pennies from my time at University to buy a piece of commodity hardware myself (a PC Clone with an Intel 486sx, 640x480 pixel VGA or perhaps a SVGA display, 8MB of RAM, I think a 40MB hard drive and a 14" monitor) to run Windows 3.1. I already knew Turbo Pascal, but I asked around and the demand was increasing for Windows C++ programmers. I therefore bought Turbo C++ 3.1 for Windows and set about learning to build Windows applications.
Six years earlier, on a dark cold night on a Norfolk Broads boat, my father had shown myself and my brothers his party trick. He laid out 4 piles of matches on the table. The first contain 7 matches, the next 5, the third 3 and the last pile contained just a single match. There were two players; each played in turn. Each player took as many matches as they wanted to, but from only one pile. It was a game of "misery" as the person who took the last match was the loser. My Dad called the game Matchsticks and the thing was he always won!
Liking a challenge I went away and figured out how he did it. I thought this was an ideal game to implement on a computer and wrote a version for the BBC Micro B. (Years later I found out the real name of the game is Nim and that it was one of the first ever computer games).
As I started to learn about writing Windows applications, I realised that the only way to learn was to write an application and that Matchsticks would be a good candidate. I could take advantage of the graphics capability to show the matches and I could use the mouse to select the matches for removal. I had quite a bit to learn, but soon had a 16 bit Windows version of Matchsticks. The computer could play optimally or drop its skill level as required. I created a matchstick icon to display the piles of matches and implemented mouse based selection of matches - the hardest part of the program. Within a couple of months I had secured my first job as a Windows C++ programmer and my career was on its way.
Recently I implemented another game, Optimal Ghost, as a React web app using Clojure (Script) and I thought back to my this first Windows app. Somethings were so similar, yet other things had changed drastically. Did I still have the source code? I did. Could I get it to compile and run I did. (By installing Ubuntu on a retired 10 year old MacMini, Virtual Box, then Windows 3.1 and Turbo C++).
Looking again at the code, I expected to be horrified. After all this was the first non-trivial C++ program I wrote. But I am pretty happy. Of course there are things I would do differently. I would not create a class instance just to initialise a static. But there are also things that I like. The code is tight. It makes extensive use of the const keyword and has lots of if DEBUG with extra validation for test builds.
Most of the issues with the code reflect general software practices of the time. For example the lack of unit tests. It was the early noughties before I started to introduce the idea of unit tests at work (based around NUnit) and received some push back. And far later before writing unit tests became an essential part of software development. It was a similar story with throwing exceptions. C++ at the time did not support them. And then it took a long while for them to become established. And even longer for people to work out how to use them safely!
Writing Matchsticks was very different to writing Optimal Ghost. For Matchsticks I only had to know three bits of technology: C++, OWL (Borland's C++ framework) and the Windows SDK. The executable is 182k.
But development was difficult. A bug even in a well written C++ program could corrupt memory. And in Windows 3.1, which did not have memory isolation or protection, such a bug could bring down the entire operating system hours after the buggy code was run. Switching to Windows NT to develop applications for 16 bit Windows applications was a game changer for me. The app you were developing may crash but not the IDE or the operating system itself.
There was no StackOverflow and barely a World Wide Web. It was not until 1995 that I first got an internet connection. And this was over an insanely expensive dial up connection using a 14.4Kbps per second modem (today my internet connection is always on at 1Gbps). Information had to be looked up in books or in computer help files.
The number of different technologies used in Optimal Ghost is insane: Clojure, Java, JVM, ClojureScript, Javascript, HTML, CSS, HTTP, REST, Jetty, Ring, Swagger, React, Reagent, Reframe, TailwindCSS, ShadowCLJS, DNS, ElasticBeanstalk, EC2 and roughly 200 other 3rd party Clojure(script) libraries. The Jar size is 65MB. No developer can ever hope to be a master of all these technologies. All that can be expected is a good knowlege of core technologies and the ability to look up solutions or solve from scratch as the need arises.
There is some benefit from all this complexity. To run Matchsticks in 1993, the user would have needed a physical copy of a 3.5 inch disk and would have needed to copy it onto their computer to run. Today, anyone in the word with a computing device (laptop, tablet, mobile phone etc) with a resonably modern browses can run Optimal Ghost by clicking on a link.
Throughout my career I have always been learning. Learning new technologies and techniques to write more reliable software more efficiently. Within 4 months of writing Matchsticks I had ported it to 32 bit so it would run natively on Windows NT 3.1 and the new class of reliable 32 bit operating systems that were just then emerging.
More broadly the first 10 years of my career were dominated by C++ programming. Then as machines and Java improved, I switched to Java for roughly the next 10 years. Builds were simpler and faster. A whole class of memory corruption bugs where eliminated. And then for roughly the last 10 years I have been using Clojure. With the REPL the modify, build, run, test cycle is instantaneously. And the persistent datastructures mean a whole class of bugs relating to modifying data, especially in multi-threaded code, is eliminated.
And what does the next 10 years hold for me. What technology is going to increase my productivity x times? I don't think it is going to be a new programming language although I find Idris interesting. The technology that holds this promise is AI code assistants. I already have GitHub Copilot sitting on my personal computer making coding suggestions - some profound but a lot of noise. And when my company is comfortable with the legal issues, I hope to use this technology at work.
The 16 bit Windows 3.1 source code.
The 32 bit Windows NT source code.
Screen cast showing the game.
Screen cast showing the tools
Screen cast showing installation of the tools
Comments