In the design of the Keykos kernel we have attempted to minimize the number of kinds of things, as well as to minimize their complexity. Of the kernel objects with state there are only pages and nodes. The distinction between nodes of a domain and nodes of a segment is not part of the logical state of a node and the kernel learns the distinction only as it begins to consider the node by means of some key thereto. This distinction is temporary and kernel optimizations are made wherein the kernel remembers for a time that some particular node is playing some particular role which is significant to the kernel, such as a domain root. This memory can be blown away whenever it gets in the way of the simplicity afforded by the external specs. The primary case of recovering the external simplicity is checkpoint-restart which is sublimely ignorant of such differences.
Very early on we contemplated a port object thru which messages would be sent. Receivers would also designate that object in order to receive messages. This was rejected out of parsimony because we felt that the extra flexibility was seldom useful and when it was needed there was no missing function that could not be had as well by introducing an extra domain. It is not proper to complain that in those cases where it was needed the extra domain would be less efficient. Conceptual simplicity is valuable, even when paid for by real performance. I do not contend that architectural simplicity trumps performance. It is a trade-off which must balance apples (of Platonic simplicity) and oranges (or real performance). In the trade-off it is also necessary to consider the potential time and space costs of relating the receiver to the port. Ultimately simplicity has real-world payoffs as well, particularly as the architecture ages.
Architectural simplicity affords hair. (Hair is the opposite of simplicity!) In Keykos we spend a good deal of this affordance on checkpoint-restart. That too was a trade-off. So far I am glad we made that trade off.