Looking Backward To Move Forward In Software Engineering

Jason Scott has a delightful blog post about a hacker, John Brooks, who released an update to Apple’s legacy operating system ProDOS. Without access to source code, Brooks took the object code of ProDOS 2.0.3 and fixed some of its bugs, added features, and bundled in some new programs. This is amazing on several levels. I’ll quote liberally from Scott, but do read the whole enjoyable post:

The project is understatement itself, simply called Prodos 2.4. It updates ProDOS, the last version of which, 2.0.3, was released in 1993.

[...] compatibility has been repaired for the entire Apple II line, from the first Apple II through to the Apple IIgs, as well as cases of various versions of 6502 CPUs [...]. Important utilities related to disk transfer, disk inspection, and program selection have joined the image. The footprint is smaller, and it runs faster than its predecessor (a wonder in any case of OS upgrades).

First, the pure unique experience of a 23-year-gap between upgrades means that you can see a rare example of what happens when a computer environment just sits tight for decades, with many eyes on it and many notes about how the experience can be improved, followed by someone driven enough to go through methodically and implement all those requests. [...]

Next is that this is an operating system upgrade free of commercial and marketing constraints and drives. Compared with, say, an iOS upgrade that trumpets the addition of a search function or blares out a proud announcement that they broke maps because Google kissed another boy at recess. Or Windows 10, the 1968 Democratic Convention Riot of Operating Systems, which was designed from the ground up to be compatible with a variety of mobile/tablet products that are on the way out, and which were shoved down the throats of current users with a cajoling, insulting methodology with misleading opt-out routes and freakier and freakier fake-countdowns.

(Emphasis in original.)

I had a great time playing with BASIC in the ProDOS 2.4 emulator on archive.org last night, and it got me thinking. This ‘primitive’ computing environment has some advantages that modern systems sometimes lack.

Because it’s small and simple, BASIC starts fast. Some machines of the time even had BASIC in ROM; some even booted directly into BASIC. Apple BASIC provides graphics (GR and HGR) as well, enabling people to immediately get started drawing pictures as well as using text mode. (Python, in a sense a modern BASIC, has similar functionality, which is awesome.)
Simplicity and constraints.
Like spreadsheets, BASIC presents an extremely simplified — some would say fatally limited — model of computation. For example, all variables are global (!). BASIC has GOTO and GOSUB, but most dialects have no true function calls or exceptions. And so on. But these limitations are not a problem if the person using the language doesn’t need the features — and it’s possible to write plenty of useful applications without them. Steve Wozniak intended Apple BASIC to be a game development platform, and BASIC got a lot of attention in the business world as well.
BASIC’s simplicity and constraints make it much easier for people to learn. There’s simply less to know. We all love C for its compact simplicity, and we all revile C++ for its complex bloat. And we love how slim our K&Rs are next to the other tech books on the shelf. But BASIC is so simple that Joshua Bell’s Quick Reference gives people most of what they would need to write programs near the upper range of what BASIC is capable of.

Obviously, I don’t want to give up the nice modern goodness we have. I like my hundreds of gigabytes of music, wifi, maps, and the modern web. But I think it’s hugely important for all software engineers to at least dabble in retrocomputing once in a while, so that we can see what we’ve lost and what good lessons we’ve forgotten over the decades.

We have, in fact, lost and forgotten many things. Software is not, in fact, necessarily getting better over time; I often feel that we are treading water and only making insignificant changes in the margins. Worse, basic infrastructure code for the entire Internet is close to being unmaintained and is at risk of exploding randomly. We’ve forgotten that stability, by itself, is a feature. Simplicity, by itself, is a feature. Knowability, learnability, and hackability are features. (Hackability: I’d bet it’s easier to learn 6502 assembly and patch a binary than it is to get a truly great result while maintaining code written in a modern JavaScript front-end framework.)

A lot of what we are building now seems to be what engineers and other technical people want, or what their host corporations want, rather than directly responding to real people’s real computing needs. When Bricklin and Frankston shipped VisiCalc, it directly responded to people’s needs. Even though spreadsheets present a very limited model of computation, they present a model that people can learn and use and which is sufficient to solve real problems. You really can run a business from Microsoft Excel, and people do. Meanwhile, Apple iTunes seems to get more mazelike with each release...

At this point, hackers in the audience are getting nervous about all my cheerleading for non-general-purpose computers. What about generativity, for which we require fully general models of computing? Obviously we technical people need that. But general models of computing are not necessarily what most people need from a machine or software product. And many or most of the problems people have with computers — unexplainable errors, malware, unnecessary bugs, and more — are the direct or indirect result of giving people hacker machines when what they wanted was a spreadsheet machine.

Presenting limited models of computing is not (necessarily) ‘dumbing the system down’. A system whose users perceive it to be dumbed down is one that is not sufficient for its purpose, and sufficiency is still our minimum bar for shipping. Rather, by presenting people systems that they can learn and use to solve problems, we are enhancing the human. Consider that presenting a bash prompt, although it’s incredibly powerful, does not actually empower most people. Instead, it confuses and disheartens — disempowers — them.

We technical people need to change our recipe for building and delivering software. We should not serve only ourselves; we should make sure we’re not doing something just because we can; we should not love complexity for its own sake. I’d like to see us follow a recipe more like this:

  1. Find out what someone’s problem is.
  2. Produce something that is sufficient to solve that problem.
  3. At this point, the solution is likely to be simple, because it is merely sufficient. Make the most of the glorious limitations:
  4. Iterate, but only if necessary and in response to people’s needs. Take your time, even as long as 23 years.