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
Please contact:
Jørgen Steensgaard-Madsen - Technical University of Denmark
Tel: +45 4525 3732
E-mail: jsm@it.dtu.dk