Oberon – The Overlooked Jewel 1
Oberon – The Overlooked Jewel
Michael Franz
University of California, Irvine
Abstract
Niklaus Wirth has received much deserved fame for the creation of Pascal,
but in many ways, he subsequently became a victim of Pascal's success. In an
age of rising specialization, in which most researchers are trying to define
themselves as experts in increasingly narrow domains, Wirth stands out as a
rare generalist, almost an “Universalgenie” of our discipline. Sadly, the
larger computer science community has been unable or unwilling to
recognize Wirth's broader horizon as a builder of systems, and throughout
his career has pigeonholed him as a “language and compiler guy”.
But ever since Pascal, the language aspect has been almost secondary to
Wirth's work. Modula(-2) and Oberon both came out of larger system-level
design projects that simultaneously also developed workstation computers,
modular operating systems, and suites of innovative application programs.
Unfortunately, these other important contributions were overshadowed by
the programming languages they were associated with, and hence never
received the recognition they deserved.
This article presents selected facets of Project Oberon, the latter of
Wirth’s two large system-level design efforts. The leitmotiv of this project
was a quote from Einstein, “make it as simple as possible, but not simpler”.
And if any further evidence was still needed, Oberon provided the conclusive
proof for Wirth’s mastery of The Art of Simplicity.
1 Introduction
The world at large will remember Niklaus Wirth primarily as “that language guy”,
and associate his name with Pascal, the programming language he created in the late
1960s. But the fame that the widespread success of Pascal brought to Wirth was at
best a mixed blessing, as it overshadowed all of his subsequent accomplishments,
some of them even greater than Pascal itself.
This was, of course, partially a problem of Wirth’s own making. In his modest
Swiss Engineer’s manner, and quite untypical for a celebrated academic, Wirth
consistently avoided exploiting the initially high-speeding Pascal bandwagon for the
2 Michael Franz
purpose of “marketing” his subsequent ideas. Indeed, he even refrained from giving
his later programming-language creations names such as “Pascal-2”, “Pascal Plus”,
or “Pascal-2000” but instead opted first for “Modula”, and then “Oberon”. Both of
these languages would probably have been considerably more successful if the
connection to the Pascal legacy had been made in their name1, but this would have
run counter to Wirth’s view that a marketer he is not.
Unfortunately, in an academic culture of increasingly flatulent self-promotion,
such modesty eventually almost inevitably leads to a certain degree of self-imposed
obscurity. In Wirth’s case, the world continued to clamor for “more Pascal” for quite
a while, but Wirth had long moved on to new horizons and more or less ignored
these requests. Eventually, the world lost interest, and it, too, moved on to new
horizons, which unfortunately were not always compatible with Pascal and its
successor languages.
The principal reason why Wirth did not immediately respond to clamors for
“more Pascal” was of course simply that he did not view himself primarily as a
“language guy”. Indeed, Wirth’s publication record quite conclusively demonstrates
that his talent has always been much broader and focused chiefly at the system level.
Twice in his career, Wirth was instrumental in building a complete computer system
“from scratch”, each consisting of a hardware platform, a modular operating system
and related systems-level software such as compilers and assemblers, and also a
limited amount of highly innovative application software.
Both of these systems, Lilith/Medos/Modula2 in 1981, and Ceres/Oberon in
1988 were years ahead of their time and could at the point of their inception be
rivalled by only a small number of far more complex research systems being
developed at places such as Xerox’ Palo Alto Research Laboratory3. For example,
the Oberon System of almost ten years ago anticipated such innovations as a
hypertext-based user interface, living “applets” embedded within documents, target-
machine independent mobile code, and document-centric computing. And Oberon
provided not just the vision, but also executed that vision in a robust implementation
1 Wirth himself makes this observation in [Wir93].
2 The Lilith/Medos/Modula-2 system is usually summarily referred to as the “Lilith system” while the
“Ceres/Oberon” system is commonly known as “The Oberon System”. This probably reflects the
greater relative importance of the hardware aspects at the time of Lilith, as well as the fact that
Oberon soon emancipated itself of the Ceres hardware platform by being ported to several alternative
architectures as well.
3 The Lilith and Oberon proj ects were in fact both inspired by systems that Wirth had encountered at
Xerox PARC, namely the Mesa and Cedar systems. Wirth succeeded in replicating many of the key
characteristics of these advanced systems with considerably less effort, achieving this remarkably
reduction in complexity to some extent by leaving out some inherently complex features, such as
preemptive multitasking. As a consequence, comparisons with the much larger research systems
existing at the time aren’t entirely fair.
Oberon – The Overlooked Jewel 3
that could actually be and consequently was used on a day-to-day basis—quite
unlike some of today’s “research” systems.
In retrospect, both the Lilith and Oberon systems were probably too far ahead of
their time, which is why they did not receive the enthusiastic responses they should
have deserved. In both cases, the situation was exacerbated by the fact that the
research community was expecting a language from Wirth, while he delivered a
system. As a consequence, the predictable result in both instances was that the world
at large focused only on the language component of Wirth's offering, and more or
less ignored the remainder that was at least as important.
The story of Lilith is for someone else to tell. This article presents my hindsight
view of The Oberon System, from the highly subjective perspective of having been
one of the early members of Wirth’s Oberon group (since early 1989)4. I will try to
illuminate certain aspects of Oberon that were relevant then and still are relevant
today, concentrating on the lesser-known facets rather than the previously published
ones. The most important influence throughout was of course Wirth’s insistence on
simplicity of design, which finally seems to be finding a resonance in the world of
computing. I believe that Wirth’s ultimate impact will be felt even stronger ten years
from now than it is today, and that the legacy of his accomplished career devoted to
The Art of Simplicity will be enduring.
2 The Oberon Compiler
Niklaus Wirth is widely known as the creator of several programming languages.
What is less well known is that he also personally wrote several compilers, including
the first single-pass compiler for Modula-2 that later evolved into the initial
compiler for Oberon5. These compilers distinguished themselves by their
particularly simple design – they didn’t aspire to tickle the last possible bit of
achievable performance out of a piece of code, but aimed to provide adequate code
quality at a price-point of reasonable compilation speed and compiler size. At the
time, this was in stark contrast to almost all other research in compilers, which
generally had been characterized by an enormous and ever-increasing complexity of
optimizations to the detriment of compilation speed and overall compiler size.
In order to find the optimal cost/benefit ratio, Wirth used a highly intuitive
metric, the origin of which is unknown to me but that may very well be Wirth’s own
4 To the best of my knowledge, when I started my Diploma Thesis in the Fall of 1988, I actually
became only the third day-to-day user of Oberon (after J. Gutknecht and N. Wirth himself). At that
time, all other members of the Institute for Computer Systems were still using Modula-2, and the
Oberon System and language themselves were still undergoing minor revisions.
5 The initial compilers for Pascal were written by E. Marmier, U. Ammann, and R. Schild [Wir93], and
the initial Modula-2 compiler by L. Geissmann.
4 Michael Franz
invention. He used the compiler’s self-compilation speed as a measure of the
compiler’s quality. Considering that Wirth’s compilers were written in the languages
they compiled, and that compilers are substantial and non-trivial pieces of software
in their own right, this introduced a highly practical benchmark that directly
contested a compiler's complexity against its performance. Under the self-
compilation speed benchmark, only those optimizations were allowed to be
incorporated into a compiler that accelerated it by so much that the intrinsic cost of
the new code addition was fully compensated6.
And true to his quest for simplicity, Wirth continuously kept improving his
compilers according to this metric, even if this meant throwing away a perfectly
workable, albeit more complex solution. I still vividly remember the day that Wirth
decided to replace the elegant data structure used in the compiler’s symbol table
handler by a mundane linear list. In the original compiler, the objects in the symbol
table had been sorted in a tree data structure (in identifier lexical order) for fast
access, with a separate linear list representing their declaration order. One day Wirth
decided that there really weren’t enough objects in a typical scope to make the
sorted tree cost-effective. All of us Ph.D. students were horrified: it had taken time
to implement the sorted tree, the solution was elegant, and it worked well – so why
would one want to throw it away and replace it by something simpler, and even
worse, something as prosaic as a linear list? But of course, Wirth was right, and the
simplified compiler was both smaller and faster than its predecessor.
And fast these compilers were – not just Wirth’s original compiler, but also the
Oberon compilers that were subsequently developed by his students for a variety of
target architectures [BCF95]. Every single one of these compilers outperformed the
respective manufacturer’s recommended compiler for the particular architecture by
several orders of magnitude in compilation speed, and on several of the platforms,
also in code quality. Only on the newer RISC platforms could the Wirth-style
compilers not quite compete, mainly because they used a linear-scan register
allocation mechanism rather than the more advanced graph-coloring variants
employed by their competitors [Cha82]. It is quite ironic that in the current trend
towards “just-in-time” compilation for Java, in which compilation speed is more
important than the last bit of execution speed, Wirth-style compilation is making a
grandiose comeback – unfortunately sometimes without proper attribution7.
6 A more detailed discussion of this and related metrics, and an example application of the metric, can
be found in [Fra94b].
7 For example, Adl-Tabatabai et al. [ACL98] describe a compilation strategy for Java that they might
just as well have copied from one of Wirth’s books [WG92, Wir96], but they present it as a new
invention and give it the new name “lazy code selection”. Wirth has been teaching the identical
method at least since the mid-1980’s, calling it “delayed code emission”.
Oberon – The Overlooked Jewel 5
3. The Oberon Libraries and Application Program Interface
The fact that they had no prior experience in operating system design turned out to
be a blessing when Niklaus Wirth and Jürg Gutknecht were designing the interfaces
of the core modules of the Oberon system. Unconstrained by any preconceived
notions of how “things should work”, they designed a thoroughly novel system
architecture that exhibits quite a few little strokes of genius throughout.
For example, anyone who has ever had the opportunity to use Oberon’s file
system is likely to find most other file system interfaces lacking. Unlike
conventional file systems, Oberon’s differentiates between the abstractions of a data
file and an access mechanism to it. The latter is called a “Rider” and maintains the
current position8. An arbitrary number of these Riders may operate concurrently on
the same file, sharing just one set of buffers with full synchronization. In other file
systems, these two abstractions are intertwined, making the “current position” a
property of the file itself. Worse still, these other file systems often permit the
creation of several unsynchronized access paths to the same file by allowing
“multiple opening of the same file”– this may of course lead to corruption of the
associated data file if the ranges of several concurrent access paths inadvertently
overlap.
Oberon also separates the directory operations from the file operations. When a
new file is created in Oberon, no entry is made into the directory, making the file
anonymous. A name can be entered into the directory at any time, which makes the
file permanent on the disk and possibly shadows an existing file with the same
name. At any given moment, a directory lookup will simply return the instance of
the file that was last registered. In my experience, this separation of directory and
file operations makes programming much more intuitive and simple.
As a third example from among the many contributions that simplify the task of
programming, the Oberon System allows an arbitrary number of files to be open
simultaneously, and they neither need to be explicitly closed, nor deleted. Instead,
file closing (with concomitant buffer flush to disk) is delegated to the garbage
collector: files whose descriptors become unreachable from the executing code are
automatically closed, and if such a file is also no longer accessible via the directory
(either because it has never been registered or because another file with the same
name was subsequently registered) it is automatically deleted and its storage space
reclaimed.
The file system is only one example of how Oberon solved some age-old
problems in a novel and practical manner. Future system designers would do well to
study Oberon’s application program interfaces more closely.
8 C. Szyperski [Szy92b, Szy98] later generalized this separation of concerns into the “Carrier/Rider”
design pattern and applied it successfully to domains other than the file system.
6 Michael Franz
4 Oberon’s Hypertext-Based User Interface
At the time of its creation, Oberon’s user interface was highly unusual and outright
intimidating to newcomers. In the initial absence of introductory tutorials for
beginning users, it also had a very steep learning curve—in short, this was a system
for “power users” (and yet was used very successfully for many years by ETH’s
undergraduate population).
However, revisiting the Oberon user interface ten years later, one finds that it no
longer seems so intimidating. Oberon-style interaction has become ubiquitous, since
today every web browser and even Microsoft’s Windows desktop has many
similarities with the Oberon system of yore. Furthermore, people have become much
more accustomed to initiating complex commands by mouse actions.
But even today, Oberon’s design is unrivalled in its simplicity and complete
avoidance of modal dialogs. For example, a file being displayed in a Viewer
(window) could be saved under a different name in the original Oberon system
simply by editing the name displayed in the Viewer’s title bar and then clicking the
save command in the menu. To this date, I find this more intuitive than any “save
as” command offered in any modern system that then will pop up a modal dialog
box to enter a new name.
Oberon’s steep learning curve was due to the fact that it used a three-button
mouse, in which almost all combinations of simultaneous mouse-clicks (and “inter-
clicks”) had separate meanings. Oberon also differentiated between a current focus
(a user-set coordinate on a screen, most often used to mark a whole window for a
subsequent command), a text entry position, and multiple text selections. In almost
all other systems, these points of attention are combined, but separating them is what
makes powerful commands (such as “replace all occurrences of the second most
recent text selection in the document currently marked by the focus by the text
selected most recently”) possible.
But the real power behind Oberon’s original user interface9 came from the
pervasive use of text as a unifying abstraction. All text in Oberon behaved the same,
whether it was a file name displayed in a Viewer’s title bar, a command in a menu
bar, the output of a “list directory” command, or the contents of an editor window.
And almost all operations offered by the system operated on such abstract texts
rather than on “passive” character arrays or data files. For example, if one had
wanted to, one could have run the Oberon compiler directly on the text representing
a Viewer’s title bar, or one could have compiled the associated menu bar (although
9 J. Gutknecht and H. Marais subsequently developed an enhanced graphical user interface for Oberon
System 3 [Gut94] that makes the end users’ experience far more pleasant. Not surprisingly, however,
this increased end-user convenience comes at the price of a somewhat higher complexity on the
programmers’ side. It also brings with it a certain loss of the rigid regularity of the original text-based
system, because the user interface now contains a multitude of data types other than text.
Oberon – The Overlooked Jewel 7
neither of this would have made much sense). Oberon’s approach of incorporating
text as a fundamental abstraction was a major improvement over the traditional
“pipe” solution as found in Unix-like systems, simultaneously more powerful and
intuitively simpler.
5 Extensibility and Document-Centric Approach
The Oberon System was designed with extensibility in mind—the ability to augment
the system’s functionality, possibly even at run-time, without having to modify or
recompile any of the existing parts [PS94]. This naturally leads to an operational
model founded on the principle of dynamic loading of code modules. Oberon refines
this model considerably by allowing multiple entry points (so-called “commands”)
into each dynamically loaded module that can be activated by the end-user
individually, and by preserving a module’s global state across multiple invocations
of such individual commands.
Remarkably, Oberon’s architecture from the very beginning offered a still
greater degree of extensibility, beyond the mere provision of additional commands
in supplementary modules. By adopting a document-centric approach based on a
generalization of the classic Model-View-Controller (MVC) design pattern [KP89],
Wirth and Gutknecht arrived at a highly flexible and elegant system structure,
permitting end-users to create wholly separate Model-View-Controller triplets that
could nevertheless share the display space and other system resources with the built-
in MVC-triplet supporting the text abstraction.
The key to this flexibility was a departure from the traditional object-oriented
model of class-based dynamic dispatch with implementation inheritance10. Oberon
replaced this model with an architecture in which the messages themselves were
represented by objects11. This had two important consequences: First, t
本文档为【Oberon 操作系统】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。