I want to write books that teach kids how computers work at their most fundamental level.
Perhaps the most fundamental concept in computing is how integers are represented and used as a code for the processor. Before somebody can understand that they need to be familiar with the concept of numerical place value in binary. Generally K-12 curricula don’t convey enough about why binary (and hexadecimal) are so useful and fundamental to our digital world. That’s why I have a plan to improve how kids are educated about numbers.
Pretend you’re a young child who doesn’t yet understand much about numbers. Now imagine you’re sitting at a desk. A rectangular area on the desk’s surface in front of you and you see a pile of blocks outside the taped area. You also notice some speakers and a monitor which prominently displays 0000.

You move several of the smallest blocks into the taped area. Suddenly the monitor changes to 0004 and you hear the speakers say “four”.
Surprised by the change you decide to move the blocks back out of the taped area.
“Wow, it’s back to 0000 again! And it said ‘zero’.”
You add the blocks you just removed. In response the monitor goes back to 0004 and you again hear “four”.
You repeat the process a few times and decide the monitor and speakers reflect something about the blocks inside the taped area. But what exactly?
The taped area has no blocks and 0000 illuminates from the monitor. Unsure what to think you decide to move small blocks into the taped area one at a time.
0001(one)0002(two)0003(three)0004(four)
Your memory stirs. “Oh, that’s the one I saw before.”
0005(five)
You recall your parents saying the same words as they touch each of your fingers.
0006(six)
“That symbol changes every time I move a block. Will it change if I take away some blocks?”
0005(five)
“Five, yeah, I just saw that one!”
0004(four)
“I remember four too.”
After more experimentation it would be clear that these symbols and sounds map to the real world concept of quantity. Even better, the relationship between the three is continuously reinforced.
Now suppose all the blocks are taken away and replaced with rods.

0040(forty)0000(zero)0040(forty)0000(zero)0010(ten)0020(twenty)0030(thirty)0040(forty)0050(fifty)0060(sixty)0050(fifty)0040(forty)
Doing the same thing with the rods results in different sounds, but the symbol changes are remarkably similar. In fact, they’re the same changes except that the position of the symbol that changes is different.
You’re given a rod’s length of unitary blocks back. Soon you realize that either adding all those unitary blocks or adding a single rod results in the same feedback from the monitor and speakers. From what you can tell this is true regardless of how many rods are already in the taped area. Eventually you conclude that a rod and ten unitary blocks represent the same quantity.
Place value in the base 10 numbers would become intuitive with enough experimentation. This system is flexible enough to work with other bases, including binary.
Going from that point to explaining how a 32-bit ‘word’ gets processed by a CPU isn’t that hard.
Anybody who knows me well is aware that I cycle through short-lived technical obsessions. Maybe I’ll dabble with some software for a few hours or a programming language for a few weeks. Sometimes I latch onto something and keep with it for a long time, but for the most part it’s about the thrill of learning and exploration.
Each of these short bursts requires startup time and has a learning curve. Even worse, when I move from one project to the next I often don’t take enough time to organize and backup what I’ve accomplished.
I’m not terribly concerned that I’m not focusing on a single project over the long term. The most important ones eventually stick. But what I am concerned about is not being organized enough to easily make progress on an old project or synthesize previously disparate projects. Enduring the exact same start up process over and over is clearly a waste of time. Plus, anticipation of wasted time deters me from returning to old projects, thereby making the projects suffer from bit rot.
Many projects require me to use software. Even when I’m developing my own software, I depend programming tools. It’s inescapable. And every piece of software will only work if its requirements are respected. Those requirements may even include other software packages with their own requirements. Eep!
Open source operating systems like Linux address this problem by including package managers. These nifty tools let you say, “I want application X to run on my machine,” and it tries to make that happen by installing all the dependencies and then finally application X. Doing this by hand is a pain, so it’s a good thing package managers exist.
So why am I complaining? I could just use a package manager, right? No, it’s not quite that simple. Before I can install an application from the package manager, the software developers would have to first package up the software for the package manager. And then the maintainers of the package manager have to include the package. The net result is my package manager won’t always let me install the software I need.
Usually the next step is to download the source code to /usr/local/src and compile it directly. Of course I have to do the same thing for any dependencies the package manager can’t handle. This isn’t too bad when the software developers document the dependencies properly. Still, it’s cumbersome if there are enough dependencies.
Programmers like myself prefer to build on the latest releases of software because sometimes the newer version will behave differently than the older software. Unless the changed behavior is identified as a regression bug, the newer version better reflects where the technology is going. Who would want their precious new code to be obsolete from day one because it depends on deprecated behaviors? Certainly not me.
The requirement to work with the latest releases poses a few problems for minimizing startup time.
gem for Ruby libraries. Package managers affect global state of the system, sometimes in the same directories, so the distinct package managers can clash. There’s no standard way to resolve these collisions—it requires experimentation and research time.All these problems can be resolved by limiting the scope of these global changes. What I mean by global scope here is each problem affects the state within the operating system, but not beyond that. If I had a different operating system for each project, the potential for these sorts of collisions would be non-existent. I couldn’t afford to buy a new computer every time I move on to a new obsession. It’s also silly to keep repartitioning my hard drives to support more operating systems. Instead I could simulate that effect by installing a new virtual machine on my computer for each project.
In the next post I’ll explore whether virtual machines are a good solution or just another problem.