The Philosophy of Assembly
CS 301 Lecture, Dr. Lawlor
Complexity from Simplicity
So, that's assembly language. Each assembly instruction is quite
simple, but you can build all the programs in the world by combining
those instructions in the right order. In other words, the
complexity of real programs emerges despite the simplicity of the
instructions.
Many systems have this feeling. The best games work this
way--there are only a few simple rules, but they combine to produce
very interesting gameplay. Legos are the classic example--one lego
brick alone is totally useless, one hundred lego bricks can build anything.
The eastern game Go
is the classic example: on a small 2D grid players place two different
colors of stones. Stones surrounded on all sides by another color
change sides. An immense amount of strategy is required for
high-level play, often (claimed to be) far in excess of that required
by chess. The similar game "Othello" used to have tagline "A
minute to learn; a lifetime to master."
Mechanical systems are similarly built from extremely simple rules,
mostly "two pieces of metal cannot occupy the same space at the same
time". Consider how this principle drives all the complexity of
an internal combustion engine! Similarly, Linotype machines,
mechanical typesetters, date to 1886. They replaced hand
typesetting, used since Guttenberg's printing press, until they were in
turn replaced by digital typesetting in the 1970's. My wife and I
found a rusting Linotype in a vacant lot across from East Fred Meyer in 2005. The complexity--and genious--of these designs is incredible!
Simplicity from Complexity and the Wheel of Reincarnation
But something by the strange name of "style" does constrain the sorts of systems that you want to work on, even if far more intricate and weird systems can be built. Bjarne Straustrup, the designer of C++, wrote a quite bitingly sarcastic April Fool's Day "paper" in 1998 describing a variety of strange and horrible features
that he actually left out of C++ for good reason. This sort of
paper gives you a feeling for what is really the hardest and most
important problem in computer science: how do you scale up a system without screwing
it up? In other words: how do you build simple systems that
perform complex tasks? Because C++, for its many faults, really
is a better C. Classes allow C++ programs to scale up (to handle
big problems well), but not get screwed up (in other words, be too
complicated to work on), and because of this C++ is very popular.
Sadly, ripping parts out of a complicated system usually doesn't help
with the overall complexity. Here's how this process often goes:
- "This system is too big!". C++ is too complicated. Windows is too big and buggy. English has too many words.
- "We need to streamline it!". People invent Java, Linux, and Esperanto--smaller, cleaner versions of the original.
- "Now we just need it to work!". People add templates to Java, installers for Linux, and technical words to Esperanto.
- The system eventually grows too big...
In other words, a system Y that started out being "a simpler X" often
eventually grows to be more complicated than the original. Then
people start to build system Z, which is... "a simpler Y". One
name for this process is the wheel of (computer design) reincarnation, which by my estimate takes about 10 human years per revolution.