Reflection in Oberon

Christoph Steindl
Johannes Kepler University Linz
Institute for Practical Computer Science
Altenbergerstraße 69, A-4040 Linz
steindl@ssw.uni-linz.ac.at


Abstract

In programs we usually distinguish between the data level and the program level. Variables are at the data level and can be accessed by the statements of a program. Modules, types and procedures are at the the program level. They serve to structure a program but they are usually not viewed as data. Sometimes, however, programs want to inspect the entities of other programs at the program level, for example, in order to answer the following questions:

  • What are the field names of a record type T declared in module M?
  • Which procedures are currently active (e.g., when a run-time trap occurs)? What are the names, types and values of their variables?
  • Does the caller of the currently executing procedure have a variable named "x", and if so, what is its type and value?

Questions like these are considered to be on a meta level. They treat modules, types and procedures as data. They have to know the structure of this "data" in order to access (or even modify) their components. If a programming system supports questions of this kind we call it a metaprogramming system. If programs can ask these question also about themselves we call such a system reflective.
Metaprogramming and reflection were pioneered by the languages Lisp and Smalltalk. In Lisp all programs are treated as data. It is possible to inspect their structure and even to dynamically build new programs (higher order functions) that can be executed. In Smalltalk types are represented as classes and procedures as methods of these classes. The structure of a class is described in a metaclass of which the class is an instance. The metaclass information can again be accessed and even modified. Many other languages allow metaprogramming in a similar way as it is done in Lisp or Smalltalk (e.g., Self, CLOS, or Beta).
The original Oberon System offered only a limited degree of reflection. It provided a module Modules which allowed programmers - among other things - to inpect information about all loaded modules. Later a module Types was added which provided basic information about record types. However, Types was not documented in the books about Oberon. In his dissertation J. Templ implemented an experimental version of Oberon for Sun workstations which treated modules, procedures and record types as data allowing also full access to their components.
We implemented a module to provide access to run time data structures and some applications that make extensive use of it (e.g., a post-mortem debugger, a database interface (provides functionality simlar to Embedded SQL in Oberon, but without the need for preprocessing), a heap inspector and a general output module).


Paper at the 6th ECOOP Workshop for PhD Students in Object-Oriented Programming, Linz, Austria, July 7-8, 1996.