Complexity vs. Abstraction

When I first learned about computers, they were much less complex than they are now. They were still complex in the sense that there were a lot of individual components, even in an eight bit microprocessor. True, most of those components were etched on a single monolithic piece of silicon, but they corresponded very directly to the discrete components that had comprised the previous generation of computers.

As Moore’s law predicted, the number of transistors on that monolithic piece of silicon roughly doubled every eighteen months. Consequently, computers got more and more complex to the point that, except for specialists that for the most part write compilers for higher level languages, no one actually programs at the machine level much anymore.

That is a shame. Writing assembly code, as the most primitive language a computer can be programmed in is called, is a kind of zen experience. It is exhilarating to know that you are indicating the exact instructions that the computer is going to execute. If you get it right you are ecstatic, if not, you learn exactly how the computer works in the process of debugging your code.

Donald Knuth, one of the pioneers of modern computer science and author of The Art of Computer Programming series, created a hypothetical computer with which to demonstrate assembly language programming in general without getting bogged down in the particulars of any one specific CPU. He called it the MIX processor. He has since updated it and calls the updated processor MMIX.

As real physical processors get more and more complex and faster and faster, it becomes attractive to implement simple processors in software running on them. These abstract processors are called virtual machines. They are attractive because they can be implemented across a wide selection of physical processors and then code written to run on the virtual machine will run on all of the different physical processors without having to recompile it. As Sun Microsystem phrased it, write once, run anywhere.

Now we can teach students to program in byte code, the machine instructions of the virtual machine, and give them much the same experience of programming in assembly code on a microprocessor.

It is enlightening to a novice programmer to think about programs at their most fundamental. It imparts understanding and wisdom that carries over into the more mundane process of writing code in higher level languages, like C, Java, or Python to name a few popular examples.

It turns out that as our processing hardware becomes faster and faster and more and more complex, we build a tower of abstractions on top of it, each one simpler and yet more powerful than the last. It turns out that this is much the same way that our own brains construct layer upon layer of abstractions by clustering neurons in clumps and then grouping the clumps into larger clumps and so forth.

It’s only a matter of time before one of our programming experience becomes self aware and emergent artificial intelligence is let loose upon the world. Unless it already has been.

Sweet dreams, don’t forget to tell the ones you love that you love them, and most important of all, be kind.