System Design can be Language Design
by Jørgen Steensgaard-Madsen
A set of software components can provide the meaning of a specialised programming language, with one component giving the meaning of one form of statement. This view on what constitutes a component stresses compositionality as the most important factor and allows late, dynamic composition of components. Ideally one might express component definitions and compositions in the same language. The actual approach is to allow definitions written in a commonly used language and compositions to be expressed in a model language. The ULC-system(Uniform Language of Composition) is a tool being developed by the author at the Technical University of Denmark to support the view expressed above, and it is ready for field tests. Among the many academical tests carried out, support for multiprogramming primitives deserves mention.
The project is based on the hypothesis that system design can be language design. It is normative because it supports a particular view on the component concept and a related view on language design. Some components can be considered classes as known from object-oriented programming languages. But a component may be even more general as for instance a higher-order class of objects having classes as members.
The relevance of the hypothesis is, of course, only a conviction that eventually should be justified by experience. But the need to compose separately defined components corresponds to a need for a language to express compositions, and this is taken as a strong evidence for the relevance of the focus on languages.
In practice a component will often represent pragmatic knowledge about the use of primitives from various existing libraries. The relation between components and library primitives can be compared to the relation between structured programming languages and assembler languages. A typical exercise is to set up a structure of processes interconnected by pipes as outlined in the figure.
This cannot be done in a typical Unix-shell, and it requires a good deal of pragmatic expertise to express it in C. The program text in the sidebar shows a readable expression for it in an appropriate ULC-language.
In simple terms a component is a subroutine (of higher-order in some model language though.) Dynamic composition of components can be realised as an interpreter for combined calls of such routines. A composition language can consequently be described by something similar to prototypes as in a C header file for a set of subroutines.
The ULC-system can generate an interpreter from descriptions in a header file. The interpreters will be called ULC-interpreters and their input, ULC-languages. The ULC-system has characteristics similar to conventional compiler or interpreter generators, with the header file corresponding to the syntactic descriptions needed by such generators. Conventional generators state meanings in terms of syntax trees. The ULC-system requires meanings given as components, and these are independent of the tool's internals and of syntax trees in particular.
A generalised syntax for subroutine calls, that look more like structured statements, is implemented at the user interface. This interface is common to the ULC-interpreters. A particular command is translated into a syntax tree with the meaningful tokens from the call encoded lexically. The ULC-system can then directly interpret the syntax tree or translate it into the component definition language.
Addition of new statements and operators to an existing ULC-language is easy. Components are written separately in an ordinary programming language, so ULC-languages are expected to be developed incrementally. Portability is presently obtained by depending on the source language accepted by GNU C (with extensions!) as the implementation language.
Dynamic composition of components has particular interest during system development, even for systems that do not require this themselves. Translating commands into GNU C, whereby one can obtain a program that is independent of the ULC-system, should make the ULC-system useful for program development in general.
A type system is used for the description of subroutine prototypes and commands are checked accordingly. But no type appears in a command, since the descriptions are detailed enough to let the system infer actual types where needed.
Several aims are pursued with the project: it should lead to a tool that is practically useful; the basic hypothesis should be tested; the formal meaning of the tool itself has to be determined; several ideas about language design are examined; and the notion of components should be exercised in new areas.
The ULC-system is ready for tests with applications that are either suitable for students' projects or require industrial cooperation.
A particular area of interest for further research will be generation of embedded system software, especially generation of kernels for arbitration of process.
A particular relation to logic and formal semantics is promising with respect to achieve formal specifications of components and hence enable formal validation of command properties.
Further information about the contents and current results is available via the author's home page at: http://www.it.dtu.dk/~jsm
Jørgen Steensgaard-Madsen - Technical University of Denmark
Tel: +45 4525 3732