It is usually possible to learn about the principles of a system by watching it under construction, especially if a construction engineer is available to answer questions. We describe here a process called the “big bang” which occurs at the beginning of the lifetime of a Keykos system. Keykos restarts from a checkpoint upon normal power up. A system may go for years and many power-ups without another big bang.
In my experience complex systems have been built with layered abstractions. I will call them “services” here. A body of code implements some service assuming the availability of other “older” services. We may say that the newer service relies upon the older. Services are thus organized into a partial ordering. We will speak of newer services being built upon older services. Older services tend to be more primitive. A “bottom up” programmer is likely to write the older code first but with careful planning this need not be. Writing older code first does let one test code as it is written and is thus conducive to unit test. Design of the various layers, by contrast, is typically coordinated and proceeds in parallel.

As a system boots, older services organize themselves before the newer ones. What does this mean? A recurrent pattern in the birth of a service is that construction code, specialized to the service, runs to build structures necessary to provide that service. Construction code may rely on older services. Construction code is not used except in a big bang. In Keykos the environments for construction code is poorly documented. The ordering of these service initiations is controlled by obscure code that is understood by few. As each service initiation finishes a new capability is placed in an widely available array of capabilities for the new services. Each brand of specialized code must know where it is in the partial ordering so as not to call on facilities that do not yet exist. This is not pretty but I know of nothing better. No system that I know of comes up elegantly.

This pattern is much like Scheme’s let* construct which produces a sequence of values each potentially depending on the preceding ones. In the Keykos big bang these values are procedures as implemented by Keykos objects. Scheme’s first class procedures support the same style. Keykos lacks Scheme’s syntactical discipline to manifest the pattern.

This pattern is much like what happens when a new instance of an object appears in an OO language. In Java the special creation code “static {...}” runs before the code defined in any object methods. In Keykos instance initialization is even more like service initialization. A new service is an object, usually one of a kind.

In complex systems mutual recursion may be necessary. When abstractions X and Y each need the other the usual technique is to make a crude version of X good enough for Y, construct Y, then produce X' on Y which is like X except that it is better founded. Y may not need the full function of X. To fit the partial ordering theory here we distinguish between X and X' by calling them different abstractions, even if they use the same code! Yet more complex patterns are frequently used. The Keykos “big bang” creates two generations of abstractions that are alike except for the generality of the “capability array abstraction” that they use. Instances of the early classes do not run after the big bang.

There are interesting parallels here with foundational mathematics. In school you may have learned in a foundations class: Natural numbers, (just positive), Integers, Rationals, Reals, Complex. Each of these is defined in terms of the previous concept.


On the IBM 370 we used the assembler’s powerful macro facilities to build the primordial pages and nodes. The nodes and key therein were all unprepared. The few primordial processes were composed of these pages and nodes. After loading, they were immediately available for processing by the standard kernel. The nodes inhabited item space and the pages, some preloaded with domain code, each occupied normal page frames. On later machines, which lacked powerful macro assemblers, we directly transcribed the procedures that had been expressed in macros, into C. This C code ran as part of the kernel and before the kernel began, first upon loading after which we were back to the 370 situation after loading.

In either case most of the dilution and distribution of authority among early domains was done by once-only domain code. As the kernel began to run the pages and nodes were about the same in the two styles of system. In systems without powerful assembler macros there were two versions of the kernel which were alike except that the big-bang version included the initial morphogenesis code where the restart kernel included just a dozen or so lines of code to read the special list of processes off of the disk.


See related ideas on predicativity.
See another observation about a different sort of layering.