Styles of Defining Objects

I learned my favorite style for behavior definition from reading the 370 Principles of Operation. Everything about a computer that changed as the computer ran, could be attributed to state in some named part of the machine, most often the content of some named register or memory location. These parts, registers and memory locations often did not correspond exactly to the hardware within the machine but the machine’s behavior towards the program was as if they did.

An alternative style of description which I normally avoid is to define the current behavior of a system in terms of historical events. An example of this is to say that a memory location, when fetched, will return the value most recently stored at that location. This description does not give a name, nor even indicate a concept of “what is stored there now”. I contend that most people who can reason about computer memory will immediately conjure up an image of what is stored in a memory location now. Giving a name to that concept is usually a better pedagogical plan, I think.

Another contrasting example is the relationship between the domain and its domain creator in Keykos. There are many domain creators and even more domains. Only the domain creator that created a domain can destroy that particular domain. The “here and now” style of description requires a name for that thing about a domain that keeps the wrong creator from being able to destroy it. We called that thing the domain’s “brand” and also specified that the domain creator had a “brander”. New domain creators always come with a brander different from those of existing and past domain creators. When a domain is created its brand is the brander of if its creator. When a domain is asked to destroy a domain it is unable to unless the creator’s brander is the same as the domain’s brand.

Another example is Seymour Cray’s 1604 computer. (A fine machine, by the way) It held two instructions per 48 bit word but there was no address for anything smaller than a word. Upon an interrupt the program counter would be delivered to the system software in order that the computation could be resumed. The information on whether the first instruction in the designated word had been executed before the interrupt was not included in the program counter. It was hidden in an unnamed part of the machine. This part of the machine had its only effect upon resumption after the interrupt. A system program designer who needed to allow nested interrupts needed to postulate the existence of this part, devise a scheme to test its state, and devise another scheme to restore its state. Perhaps if the part had been given a name it would occurred sooner to Seymour that the system program needed direct access to it.

Recently I have become fond of distinguishing between behavior and state. Objects of one type necessarily share behavior but need not share state. Indeed with sufficient attention to defining state and behavior it may be possible to define “type” in these terms. It is not necessary to share implementation in order to share behavior. The division between state and behavior is not always clear. An attractive place to waffle is creation arguments that set initial immutable state of an instance. Such an implementation can be described as a single type whose instances have immutable but various states; or alternatively described as a parameterized set of behaviors and types. The decision is pedagogical.

I wrote the above in late 2002. I am now (2007) aware of another issue in this area. The 370 manual stuck to one level of abstraction fairly rigorously. It described an abstraction that was fairly far from any real 370 implementation. Its description, however, was extremely precise. While describing the diagnose instruction and programming aspects of machine failures, it had to admit to some vague underlying different reality.

Any terminological dilemma of “one man’s input is another man’s output” was sidestepped by providing one vantage point from which to name all the parts of the machine. Relative terms such as “input” were thus not required.

By comparison the Keykos manual tries to describe kernel functions as the Principles of Operation described the 370. The reader would have to discern from the manual, or learn elsewhere, about abstraction techniques.

Later parts of the Keykos manual describe function that is built outside the kernel using the same terminology with which kernel functions are described. This was a departure from the 370 style which would never have tried to describe some 370 program on the same level as the hardware. Only gradually did I explicitly realize that software running outside the kernel could provide function largely identical to kernel function and that this was a strength of the system. We had designed for this pattern without making it an explicit design goal.

We speak above of domain creators and the domains that they create. What we say about them depends on the code obeyed by the domain creator. Keykos documentation seldom specifies what code some purported property depends on. Keykos savvy programmers are never confused but that is not good enough.