Loglan 82, A micro-manual of the programming language - Basic constructs and facilities

8) Prefixing


Classes and prefixing are ingenius inventions of Simula-67(cf [1]). Unfortunately they were hardly ever known and, perhaps, by this have not been introduced into many programming language that gained certain popularity. Moreover, implementation constraints of Simula-67 bind prefixing and classes workableness to such a degree that both facilities cannot be used in all respects. We hope that LOGLAN-82, adopting merits and rooting up deficiencies of these constructs, will smooth their variations and vivify theirs usefulness.

What is prefixing ? First of all it is a method for unit extending. Consider the simplest example:

Assume the user desires to extend this class with new attributes. Instead of writing a completely new class, he may enlarge the existing one:

Class gas_bill is prefixed by class bill. This new declaration may appear anywhere within the scope of declaration of class bill. (In Simula-67 such a prefixing is forbidden in nested units.) Class gas_bill has all the attributes of class bill and additionally its own attributes (in this case the only one: cube_meters). The generation statement of this class has the form:

where z is a reference variable of type gas_bill. Remote access to the attributes of prefixed class is standard:

Consider now the example of a class with parameters.

Assume that in a program a class:

and its extension:

are declared.

Then for variable z of type id_card and variable t of type idf_card the corresponding generation statement may be the following:

Thus the formal parameters of a class are concatenated with the formal parameters of its prefix.

One can still extend class idf_card. For instance:

Prefixing allows to build up hierarchies of classes. Each one hierarchy has a tree structure. A root of such a tree is a class without prefix. One class is a successor of another class iff the first is prefixed by the latter one.

Consider the prefix structure:

Class H has a prefix sequence A, B, E, F, H. Let a, b, ... , h denote the corresponding unique attributes of classes A, B, ... , H, respectively. The objects of these classes have the following forms:

Let Ra, Rb,..., Rh denote reference variables of types A, B,..., H, respectively. Then the following expressions are correct:

Variable Ra may designate the object of class B (or C,..., H), i.e. the statement:

is legal. But then attribute b is not accessible through dot via Ra, i.e. Ra.b is incorrect. This follows from insecurity of such a remote access. In fact, variable Ra may point any object of a class prefixed by A, in particular, Ra may point the object of A itself, which has no attribute b. If Ra.b had been correct, a compiler should have distiguish the cases Ra points to the object of A or not. But this, of course, is undistinguishable at compilation time.

To allow, however, the user's access to attribute b (after instruction Ra:=new B), the instantaneous type modification is provided within the language:

The correctness of this expression is checked at run time. If Ra designates an object of B or prefixed ba B, the type of the expression is B. Otherwise the expression is erroneous. Thus, for instance, the expressions:

enable remote access to the attributes b, c, ... via Ra.

So far the question of attribute concatenation was merely discussed. However the sequences of statements can be also concatenated.

Consider class B prefixed with class A. In the sequence of statements of class A the keyword inner may occur anywhere, but only once. The sequence of statements of class B consists of the sequence of statements of class A with inner replaced by the sequence of statements of class B.

In this case inner in class B is equivalent to the empty statement. If class B prefixes another class, say C, then inner in B is replaced by the sequence of statements of class C, and so on. If inner does not occur explicitly, an implicit occurrence of inner before the final end of a class is assumed.

Example

Let class complex be declared as usual:

and assume one desires to declare a class mcomplex with the additional attribute module. In order the generation of class mcomplex define the value of attribute module, one can declare a class:

Class mcomplex may be still extended:

For these declarations each generation of class mcomplex defines the value of attribute module, each generation of class pcomplex defines the values of attributes module and alfa.

For reference variables z1, z2 z3 of type complex, the following sequence of statements illustrates the presented constructs:

Example:

Binary search tree (Bst) is a binary tree where for each node x the nodes in the left subtree are less than x, the nodes in the right subtree are greater than x. It is the well-known exercise to program the algorithms for the following operations on Bst:

member(x) = true iff x belongs to Bst

insert(x), enlarge Bst with x, if x does not yet belong to Bst

We define both these operations in a class:

In the example the common actions of member and insert are programmed in class help. Then it suffices to use class help as a prefix of function member and procedure insert, instead of redundant occurrences of the corresponding sequence of statements in both units.

Class Bst may be applied as follows:

As shown in the declaration of Bst, class may prefix not only other classes but also procedures and functions. Class may prefix blocks as well.

Example:

Let class push_down (p. 5) prefix a block:

In the above block prefixed with class push_down one can use pop and push as local attributes. (They are local since the block is embedded in the prefix push down.)

Example:

In place where classes push_down and Bst are visible together a block prefixed with Bst may be nested in a block prefixed with push_down (or vice versa). In the inner block both data structures are directly accessible. Note that this construct is illegal in Simula 67.




Last update 02/07/95
Comments, suggestions and critiques are welcome to : linfo062@crisv2.univ-pau.fr