ISSN 0105-8517
The BETA Programming Language
Bent Bruun Kristensen
Ole Lehrmann Madsen
Birger Moller-Pedersen
Kristen Nygaard
DAIMI PB - 229
November 1987
AARHUS UNIVERSITY O
COMPUTER SCIENCE DEPARTMENT 5 FF
I
wi orkogate116—DK e000 Aas Denna | [Tf
Tolphone: 450 127408 Tel 64767 aased olTHE BETA
PROGRAMMING LANGUAGE!
Part 1: Abstraction Mechanisms
Part 2: Multi-Sequential Execution
Bent Bruun Kristensen, Aalborg University Centre
Ole Lehrmann Madsen, Aarhus University
Birger Moller-Pedersen, Norwegian Computing Center
Kristen Nygaard, University of Oslo
Abstract. The BETA programming language is a modern
language in the SIMULA 67 tradition. It supports the object-
oriented perspective on programming and contains compre-
hensive facilities for procedural and functional programming.
BETA replaces classes, procedures, functions and types by
a single abstraction mechanism called the pattern. Patterns
may be organized in a classification hierarchy by means of
sub-patterns. The notion of virtual procedure is generalized to
virtual pattern. Virtual patterns combined with sub-patterns
make it possible to delay the specification of an attribute in a
pattern, Attributes may then have different bindings in differ-
ent sub-patterns, BETA also provides a unified framework for
sequential, coroutine and concurrent execution. ‘This paper is
a tutorial introduction to BETA.
2 fo appear in: Research Directions in Object Oriented Programming. Edited by B.D. Shriver
and P, Wegner, MIT Press, 1987.Part 1: ABSTRACTION MECHANISMS
1 Introduction
BETA is a modern language in the SIMULA 67 ([SIMULA]) tradition.
It supports the object oriented perspective on programming and contains
comprehensive facilities for procedural and functional programming. Re-
search is going on with the aim of including constraint oriented constructs.
BETA replaces classes, procedures, functions and types by a single ab-
straction mechanism called the pattern. It generalizes virtual procedures
to virtual patterns, streamlines linguistic notions such as nesting and
block structure, and provides a unified framework for sequential, corou-
tine, and concurrent execution. The resulting language is smaller than
SIMULA in spite of being considerably more expressive.
Instances of patterns, called objects, may be used as variables, data struc-
tures, procedure/function activations, coroutines and concurrent systems.
Patterns may be organized in a classification hierarchy by means of sub-
patterns. Virtual patterns combined with sub-patterns make it possible
to delay the specification of an attribute in a pattern. Attributes may
then have different bindings in different sub-patterns. This corresponds
to dynamic binding of methods in Smalltalk ([SMALLTALK]). In con-
trast to Smalltalk, the use of virtual patterns may be checked at compile
time, even though the binding is done at run-time.
The first part of this paper describes the abstraction mechanisms and
the mechanisms for sequential execution. The second part describes the
mechanisms for supporting multiple action sequences, including alterna-
tion (generalized coroutine sequencing) and concurrency. Part one is a re-
vised version of [BETA 83b]. Part two is a revised version of [BETA 85a].
The appendix contains a summary of the BETA syntax.2 Basic Constructs
2.1 Objects and Patterns
A BETA program execution is a collection of objects. In a BETA program
objects are described by object-deseriptors having the following form:
(# {begin object: description}
D1; D2;...D_ {list of declarations}
enter In {input parameters}
do Imp {imperatives to be executed}
exit Out {output parameters}
#) fend object description}
Dy, Dz, ..., Dp are declarations of attributes. Inis a list of input param-
eters. Imp is an imperative that describes the actions to be performed
when the object is executed as a procedure, coroutine or process. Out is
alist of output parameters produced as a result of object execution. The
enter-part corresponds to value-parameters and the exit-part to result-
parameters.
An object descriptor may be used to describe a pattern of objects. A
pattern consists of a named object descriptor:
CO: (Di; Dain
enter In
doImp
exit Out
#)
Patterns serve as templates for generating objects (instances). The ob-
jects generated as instances of C will all have the same structure, That
is, the same set of declarations, the same enter-part, the same do-part
and the same exit-part.
Declarations serve to describe attributes which may be objects and/or
patterns. For example, objects that represent points (c.g. on a screen)
have two Integer attributes.Point: (#2,y: @Integer#)
The above pattern for Point has empty enter-, do-, and exit-parts and
a single declaration that uses the predefined pattern Integer. Given this
pattern, Point-objects may be declared by
P1,P2: @Point
If Point objects are to be moved around, this may be described by adding
the pattern attribute Move within the pattern Point:
Point:
(#2,y: @Integer; {two object attributes}
Move: {a pattern attribute}
(# dz, dy: @Integer
enter (dz, dy)
doz + de> a;
ytdyoy
#)
#)
A Point object P1 may then be moved by executing an instance of P1’s
Move- attribute:
(11,22) + P1.Move {Execute P1.Move with parameters (11,22)}
The pattern Point has two object attributes and a pattern attribute, but
no enter-, do-, or exit-parts. Pattern attributes of a pattern correspond
to interface operations in Smalltalk classes. Object attributes correspond
to instance variables. The do-part of an object has no counterpart in
Smalltalk and is used when the object is executed as a procedure, corou-
tine or process. The do-part is invoked by invoking a pattern name as in
P1.Move which invokes the do-part of the Move-pattern in P1 as a proce-
dure. P1.Move describes that a temporary instance of the Move-pattern
will be created and causes the do-part of this instance to be executed.
The do-part of an object represents a very important extension of the
notion of objects that allows patterns to be executed as procedures andto be used in modelling ongoing processes and in system simulation.
2.2 Evaluation
The basic mechanism for specifying sequences of object execution steps
is called an evaluation. An evaluation is an imperative that may cause
changes in state and produce a value when its executed. The notion of an
evaluation provides a unified approach to assignment, function-call and
procedure-call.
Examples of evaluations are
(11,22) + PL. Move
atdze
The evaluation
atde+e
specifies an ordinary assignment (the assignment of x + dz to z). An
evaluation may specify multiple assignment as in:
BaIad
where 3 is assigned to I and the value of I is assigned to J.
The evaluation
(11,22) > PL. Move
specifies a procedure-call, The value (11, 22) is assigned to the enter-part
of P1.Move and P1.Move is then executed with these enter parameters.
Note that the pattern P1.Move is invoked as an instance.
The general form of an evaluation is:
Ey + By 9 En
where n > 0. Each £; is either an object denotation (object or pattern)or an evaluation list (F,, Fa, ..., Fm) where each Fj is an evaluation. The
execution of an evaluation takes place as follows:
e E, is executed,
¢ a value transfer from Ey to Ey is carried out,
© Ey is executed,
ou.
© By-1 is executed
© a value transfer from EH, to E, is carried out,
e E, is executed.
Execution of B; means executing the do-part of Bj, if E; is an object-
denotation. If H; is an evaluation list then it is the empty action. A value-
transfer from E; to E;,, means assignment of the elements of the exit-list
of E; to corresponding elements of the enter-list of Hj,1. If one or both
of E;, Ei, are evaluation-lists, then these lists take the place of enter/-
exit-lists. A value-transfer from Bj to Ej41 is legal if the corresponding
elements of their enter/exit-list are assignable. For the predefined pat-
terns, we have that Integer-objects are assignable to Integer-objects etc.
Note that the recursive definition of assignment means that the do-part
of objects being assigned during a value-transfer are also executed.
A BETA pattern is among other things a unification of procedures and
functions. In figure 1 an example of a BETA program that demonstrates
the use of patterns in a procedure/function like manner is given:
The program contains the declaration of two patterns: Power and Re-
ciproc, and two objects of the pattern Real: A and B. The do-part of the
program consists of the evaluation-imperative
(3.14,2) + Power + Reciproe + (A, B)
The execution of this evaluation-imperative takes place as follows: The
values 3.14 and 2 are assigned to the input parameters X, n of Power
(described by enter (X,n)), the do-part of Power is executed, the output
6G
Power: {Compute X" where n > 0}
(#X,Y: @Real; n: @Integer;
enter (X,n)
dol Y¥;
(for inz: n repeat ¥ « X + ¥ for)
exitY
#)
Reciproc: {Compute (Q,1/Q)}
(#Q,R: @Real;
enter Q
do (if (Q = 0)
// True then 0 + R
/| False then 1/ QR
if)
exit (Q, R)
Ss
A,B: @Real;
do (3.142) Power + Reciproc > (A,B)
{A=3.147, B=3.14-}
#)
Figure 1: Example of using patterns as procedures/functionsparameter Y of Power (described by exit) is assigned to the input
parameter Q of Reciproc, the do-part of Reciproc is executed and finally
the output-parameters Q, R of Reciproc are assigned to A,B. {...} isa
comment.
The do-part of Power consists of two imperatives: an evaluation-imperative
assigning Y the value 1 and a for-imperative. ‘The index-variable, inc,
steps through the values 1,2,...,n. The do-part of pattern Reciproc con-
sists of an if-imperative.
BETA will contain a number of predefined patterns for commonly used
data types such as Integer, Boolean, Char and Real and their operations.
The patterns +, —, , etc. will denote the usual operations on integers.
Similarly for the other predefined patterns. For example the following
declaration declare 3 Integer-objects
I,J,K: @Integer
‘The standard infix notation for Integer expressions can be used:
14171; (I#J)+122 5K
It corresponds to the following evaluation using function calls:
GD) 3+3% (UJ) +12) 3+5K
2.3 Control Structures
The iteration control structure of BETA is called a for-imperative and
has the following form:
(for Index: Range repeat Imperative-list for)
where Indes is the name of an Integer-object and Range is an Integer-
evaluation. Range is evaluated prior to the execution of the for-impera-
tive and determines the number of times that Imperative-list is executed.
Indez will step through the values 1, 2, ..., Range. The scope of Indes is
the Imperative-list. Index cannot be assigned to.The selection control structure is called an if-imperative and has the fol-
lowing form:
(if By
// B, then I,
// Ey then Iz
|B, then I,
if)
where Ep, Bi, Bp, ..., By are evaluations. Ey is first evaluated, and that
value is tested for equality with By, Ey, ..., Hy in an arbitrary order. If
Eq = E; then I; may be selected for execution. If one or more alternatives
are selectable, then one of these is chosen randomly. If no alternative may
be selected, the execution continues after the if-imperative.
The equality test between two evaluations E’ and E” is carried out as
follows:
© Let H! and EB” be “primitive” objects, that is instances of Integer,
Boolean, Char and Real. Here the usual test for equality of values
is used.
Let E’ and E” be two “compound” objects. The do-parts of E’ and
E” are executed. Then the exit-parts of B! and B” are tested for
equality. This implies that user defined equality is supported.
Let EZ! and E” be two evaluation lists. Corresponding elements of
the lists are tested for equality.
Let B! have the form A; — ... + An and let E” have the form
By >... By. EB! and B” are executed as described in the previous
section. In addition A, and By, are tested for equality. The possible
do-parts of Ay and By, are only executed one time.
An imperative in the do-part of an objetct descriptor may be labelled
I: Imperative
where L is a name. The scope of the label is the Imperative to which the
label is attached. That is, L may only be referred to within the Imperative.
9The execution of a labelled imperative may be terminated by executing a
leave- or restart-imperative within it. If leave L is executed, the execution
continues after the imperative labelled by L. If restart L is executed, the
execution continues at the imperative labelled by L,
the labelled imperative is repeated.
the execution of
Consider the following example:
L: (if...
// ...then
M: {2}
(for ... repeat
// -.. then leave L
// ... then restart M
if}for)
// then...
if) {1}
An execution of leave L implies that execution continues at {1}. An
execution of restart M implies that execution continues at {2}.
Figure 2 describes the pattern Register, which is similar to Hoares Small-
IntSet. The pattern Register describes a category of objects. Each
Register-object consists of the attributes Table, Top, Has, Insert and
Remove, Table is an consisting of 100 Integer-objects. The action part of
a Register-object is the single evaluation 0 + Top. Has-objects consist
of the attributes Key and Result.
The do-part of the program consists of an execution of the evaluation
R, which has the effect of initializing the Register-object R. Then the
clement 5 is inserted into R. Attributes in objects are denoted by a
dot: object.attribute. Thus R. Insert denotes the Insert attribute of R.
Finally it is tested if 5 is a member of R.
2.4 Object Kinds and Construction Modes
BETA has three kinds of objects: system, component and item. The kind
of an object specifies how the objet can be used.
10(# Register:
(# Table: [100] @Integer; Top: @Integer;
Has: {Test if Key in Table{1 : Top]}
(# Key: @Integer; Result: @Boolean;
enter (Key)
do False —+ Result;
Search:
(for ine: Top repeat
(if ((Tablelina] = Key) -+ Result)
// True then leave Search
if)for)
exit (Result)
#)s
Insert: {Insert New in Table}
(# New: @Integer;
enter (New)
do (if ((New) + Has) {Check if New is in Table}
// False then {New is not in Table}
Top +1— Top;
(if (Top < Tables Range) {Tables Range = 100}
// True then New — Table[T op]
/| False then {Overflow}
init) #)s
Remove: {Remove Key from Table}
(# Key: @Integer;
enter (Key)
do Search:
(for inz: Top repeat
(if Table[ina] // Key then
(for é: Top —inz repeat
Tablelinz + i] + Tablefinz + i — 1];
for);
Top —1— Top;
leave Search
if)for) #);
do0 — Top;
#); {end Register}
R: @Register; { declaration of a Register-object}
do R; {initialize R}
(5) + ReInsert; {insert 5 into R}
(if ((5) + ReHas)//True then... {5 is in R} if)
#)
Al.
Figure 2: Hoares SmallIntSete A system object may be executed concurrently with other system
objects.
A component object (coroutine) may alternate execution with other
components.
@ An item object is a dependent action sequence contained in a sys-
tem, component or item.
In this part of the paper objects of kind item have been described. Objects
of kind component or system will be described in part 2.
Item objects may be created statically by declaration, inserted inline in
the action-part, or created dynamically by a “new”-imperative. These
three different ways of creating objects are called construction modes.
The construction mode gives rise to three sorts of items respectively called
static item, inserted item and dynamic item. The notions of kind and
construction mode are orthogonal since objects of kind component or
system may also be created either statically, inserted or dynamically.
2.4.1 Static Items
A pattern may be used to declare an item in the following way:
E: @P
B is static reference denoting an object (called a static item) generated
according to the pattern P. Such a static item is an integral part of a
surrounding object of which it is an attribute. The declaration
P1,P2: @Point
specifies two static references P1, P2.
A declaration may specify a sequence (array) of static items, called an
item-repetition:
X: [100] @P
X consists of the P-items X{1], X[2], ..., X[100].
122.4.2 Inserted Items
Consider the pattern C in the following evaluation:
E>OsA
Its execution assigns the output of H to the enter-part of an instance of
C and causes the instance to be executed. Finally the exit-part of the
C-instance is assigned to A.
The C-object (called an inserted item) will be an integral part of the
surrounding object. This inserted item will the be executed when control
reaches the evaluation imperative. The state of this C-item will be unde-
fined prior to each execution of it. The notion of inserted item is similar
to an in-line procedure call.
The evaluations
(11,22) + P1.Move
(8.142) + Power + Reciproc + (A, B)
specifies an inserted item for each of the patterns P1.Move, Reciproc and
Power.
With this semantics of inserted items, it may be seen that inserted items
cannot be used to describe recursive procedures since this will lead to an
infinite recursion. This is analogous to static items which cannot be used
for describing recursive data structures. Below the notion of dynamic
items will be introduced. Dynamic items may be used for describing
recursive data structures and recursive procedures.
2.4.3 Dynamic Items
The static and inserted items described above are static in the sense that
they are generated at the same time as and as a permanent, inseparable
part of the object in which they are declared. Storage requirements for
static and inserted items may be computed at compile time. It is possible
to generate items dynamically during a program execution. The follow-
13ing declaration specify attributes, which are dynamic references to such
items:
ETP
P is the qualification of the references. It specifies that X may denote
(refer to) a P-item, a sub-item of P (see section 3) or NONE, which means
no item. A dynamic reference is similar to a reference in SIMULA.
A dynamic P-item may be generated by execution of a “new”-imperative
&P. An object generated in this way is called a dynamic item.
A dynamic reference may be given a value in the following way:
&PO + XO; {a P-item is generated and its reference is assigned to X}
This corresponds to X ~ P New in Smalltalk.
& PO specifies that a reference to the newly created item is returned. In
contrast, an evaluation with no box, like &P, describes that the item is
executed.
An evaluation of the form &P (i.e. without a box) is similar to a pro-
cedure call in ALGOL 60 in the following sense: Each execution of &P
implies creation of an instance of P and a subsequent execution of this
instance.
In figure 3 an example of using dynamic items is given. One pattern
describes a recursive function for computing factorial. Another pattern
describes a linked list of Integers.
References may be compared in an if-imperative of the following form:
(if xo
//YO then {X and Y sefer to the same item}...
|| NONE then {X refers to no item}...
if)
2.4.4 Summary of Construction Modes
‘To sum up, objects of kind item may be generated in three different ways:
14(#
Factorial:
(HN, fac: Integer
enter N
do (if (N <1)
// True then 1 — fae
// False then ((N —1) — & Factorial) + N + fac
if
Caine
#)
Link: {Link describes a linked list}
(#suce: } Link; {tail of this Link}
elm: @Integer {head element of this Link}
Insert: {Insert an element before this Link}
(#E: @Integer; R: | Link
enterE
do&LinkO + RO; {R denotes a new instance of Link}
BE Reelm; {B= Reelm}
succOl + ResuceX; {tail of this Link = tail of R}
RO + succO {R = tail of this Link}
#)
#)
head: @Link; {A static Link item}
do0 — headselm;
(for ina: 4 repeat
ine + & Factorial headsInsert
for);
{head = (0 24 6 21)}
#)
Figure 3: Example of a recursive procedure and a recursive data structure
15P:
(#1, J: @Integer
enter (J, J)
dol +JoI
exit (I,J)
#)s
E: @P; {declaration of a static item}
1 Pi {declaration of reference to a dynamic item}
NY, M: @Integer;
do {generation of a dynamic P-item denoted by X}
&PO = XO;
{an evaluation involving static, inserted and dynamic items}
(3,4) 3 B> Pa B>&P +X >P3(N,M);
#)
Figure 4: Example of dynamic items
¢ As a statically allocated attribute, called a static item.
¢ As a statically allocated action, called an inserted item.
e As a dynamically allocated attribute or action, called a dynamic
item.
We have mentioned the similarities between inserted items and inline
procedure calls and between dynamic items and ALGOL-like procedure
activation records. We also note that a static item may be used as a
static subroutine.
In figure 4 examples are given of the three different construction modes.
The last evaluation involves two executions of the static item E, execution
of two different inserted items (specified by the two Ps), and execution of
two different dynamic items (the one denoted by X and an anonymous
one generated during the evaluation by &P).
16(#aPoint: @(4X,¥: @Real#); {a singular static item}
do 5.0 + aPoint.X; 3.0 + aPoint.¥;
{a singular inserted item modelling an ALGOL-like inner block}
(#2: @Real
do {switch the coordinates}
aPoint.X — Z; aPointeY — aPointeX;
4 aPointsY
#)
#)
Figure 5: Example of singular items
2.5 Singular Objects
When describing an object it is possible to describe its properties directly
without referring to a pattern. This corresponds to specifying the type
together with a variable in PASCAL ([PASCAL}) and to inner blocks
in ALGOL 60 and SIMULA and the “prefixed blocks” of SIMULA. An
object being described directly is called a singular object. An object
described as an instance of a pattern is called a pattern defined object.
Figure 5 is an example of a BETA program with singular objects.
2.6 Block Structure and Scope Rules
BETA is a language belonging to the ALGOL family with respect to
block structure, scope rules and type checking. In ALGOL and SIM-
ULA a procedure or block may have local procedures and/or blocks. In
BETA object descriptiors may be textually nested. Block structure is an
important mechanism for structuring individual components of a large
program. Block structure and sub-patterns are complementary mecha-
nisms for structuring objects and patterns, For more examples of using
block structure in BETA see [Madsen 86].
For large programs it is necessary to have a mechanism for separating the
program into (separately translatable) modules. It is well know that such
17a mechanism for “programming in the large” ([DeRemer and Krohn 76])
cannot be handled with block structure, which is primarily useful for
“programing in the small”, BETA has no such modularization mecha-
nism, Mechanisms for organization of large programs are considered to
be orthogonal to the BETA language. The reason is that how a program
is combined from various modules from libraries, other programmers etc.
has nothing to do with the intention of the program. The mechanism for
program modularization is described in [BETA 83a]. The idea is that any
sentential form (string of terminal and nonterminal symbols) generated
from a nonterminal of the BETA grammar may be a module. This can be
applied to any language where the syntax can be described by a context
free grammar. The modularization mechanism also supports the sepa-
ration of a BETA program into interface modules and implementation
modules.
With respect to scope rules, BETA also follows the ALGOL tradition,
since all names in textually enclosing object descriptors are visible. In
addition to the ALGOL scope rules most languages supporting classes
have a rule that protects certain attributes of an object from being ac-
cessed remotely. In SIMULA this is handled by the hidden/protected
mechanism. In Smalltalk instance variables cannot be accessed from out-
side the object. BETA contains no such protection mechanism. This is
handled by the modularization mechanism mentioned above.
183 Classification Hierarchies
Patterns may be organized in a classification hierarchy. An object de-
scription may include a super-pattern (often called prefiz-pattern or simply
prefiz). This specifies that objects generated according to the description
have all the properties described by the super-pattern. A pattern having
a super-pattern is described in the following way:
C1: c
(# Dis Dis),
enter In’
do Imp!
exit Out!
#)s
where C is the super-pattern of C1. C11 is also said to be a sub-pattern
of C. Any C'l-object will then have the same properties as C-objects in
addition to those specified between (# ... #), called the main-part of
C1.
A Cl-object will have attributes corresponding to the declarations Di,
sy Dy and Di, ..., fy. The enter-part of a Cl-object is a concatenation
of In and Inl. The exit-part of a C'1l-object is a concatenation of Out and
Out.
The action part of a Cl-object is combination of Imp and Impl. This
combination is described by means of the inner-imperative: The exe-
cution of a Cl-object starts by execution of the imperative Imp in the
C. Each execution of an inner-imperative during the execution of Imp
implies an execution of Imp’.
Consider the example in figure 6. Instances of C1 have the attributes a,
8, c, Execution of a C'l-instance implies execution of 11 — a, 22 > ¢
and 33 = b.
Execution of inner in the main-part of an object is the empty action.
For example executing an instance of the C-pattern in figure 6 will result
in execution of 11 + a, and 33 > 6. That is, execution of inner is the
empty action.
19o:
(#a,b: @Integer
dol 4;
inner
3345
#5
Cl: C(y#c: @Integer do22 — cH)
Figure 6: Example of a pattern and a sub-pattern
Record: (4 Key: @Integers#);
Person: Record(# Name: @String; Sex: @SexTypet);
Employee: Person(4 Salary: @Integer; Position: @PositionTyped);
Student: Person(# Status: @StatusT ype);
Book: Record(# Author: @Person; Title: @TitleType#t);
Figure 7: Example of sub-patterns
In figure 7 is given some pattern declarations illustrating sub-patterns.
All Record- , Person-, Employee-, Student-, and Book-objects may be
viewed as Record-objects and they all posses the attribute Key. Simi-
larly Person-, Employee-, and Student-objects may be viewed as Person-
objects and they all posses the attributes Key, Name and Sez.
The example in figure 8 illustrates the combination of action-parts. The
example contains two patterns and two evaluations. The pattern Cycle*
repeatedly executes an inner-imperative and may be used as a cycle con-
trol structure. The pattern CountCycle is prefixed by Cycle. This has
the effect that when executing an instance of CountCycle, its do-part
will also be repeatedly executed. The first evaluation illustrates the use
of CountCycle as a control structure. The effect of this is shown in the
second evaluation
2A construct of the form (L: Imp,;Impz;...;Imp, +L) is a labelled compound imperative
20Cycle: (##do (Loop: inner; restart Loop : Loop)#);
CountCycle: Cycle
(Hine: @Integer
enter (inz)
do inner;
ing +1 ina;
#)
L:(1)>
CountCycle
(HF: @Integer
do (if inz // 10 then leave L if);
ina + & Factorial — F;
{Factorial is computed for inz in (1,9]}
#)
L: (1) 3
(Hine: @Integer;
F: @Integer
enter (inz)
do
(Loop:
(if inz // 10 then leave L if);
inz + & Factorial > F;
ing +1 ings
restart Loop
: Loop)
#)#)
Figure 8: Example of combination of action-parts
21ForAll:
(# Current: @Integer;
do (for inz: Top repeat
Table{inz] — Current;
inner
for) #)
Figure 9: Iterator on the Register-pattern
Figure 9 describes a pattern ForAll which may be added as an attribute
to the Register-pattern. It defines a control abstraction that makes it
possible to step through all the elements of a Register and perform an
operation upon each clement.
This operation may be used in the following way:
R.ForAll(# do Current + DoSomething#)
Current will then step through the values of Rand each value will one by
one be assigned to DoSomething. It may be inconvenient that the name
of the index variable always has to be Current. This may changed by
adding the following attribute to ForAll:
Index : (# exit Current)
ForAll may now be used as follows:
R.ForAll(#I: @Index doI + DoSomething#)
‘The idea of combining action-parts by means of inner originates from
SIMULA where it is used for prefixing of classes. In [Vaucher 75] it is
proposed to extend this idea for prefixing of procedures
One of the differences between SIMULA/BETA and Smalltalk is the ques-
tion of “typing” of variables. In Smalltalk variables have no type and may
refer to any object. In SIMULA/BETA references are qualified by means
ofa pattern name. The qualification specifies that the reference may refer
only to objects that have been specifed by means of that pattern. The
22notion of qualification is defined as follows:
A pattern C1 is said to be qualified by a pattern A if
© Ais Cl or
© the super-pattern C' of C1 is qualified by A.
Similarly an object is qualified by a pattern A if it is an instance of A or if
a possible super-pattern used in the description of the object is qualified
by A.
Consider
O: (#...#); Bi 1G}
C1: C(# ...#)y Rl: T C1;
C2: CH ...#)s RB T 02
Here C2 is qualified by C2, C1 and C. Furthermore C1 is qualified by C1
and C. Finally C is qualified by C. The reference R may refer instances
of C, Cl and C2. The reference R1 may refer instances of C1 and C2.
Finally R2 may refer instances of C2 only.
23,KeyMaz:
(# Rec :< Record;
M: @Rec;
enter (M)
do
(if (M.Key > MazKey) //True then
M.Key + MarKey;
inner
if) #)
Figure 10: Example of a virtual pattern
4 Virtual patterns
The virtual concept was introduced in SIMULA, as was the subclass
mechanism. In BETA the virtual concept is generalized and is through
the pattern concept available for all kinds of objects, not only procedure
activation records.
A pattern attribute may be declared as virtual. This implies that only
a part of the properties of the virtual pattern is known and that the full
specification of it may be deferred. The known properties will correspond
to a prefix of the virtual pattern. This prefix is specified in the declaration
of the virtual pattern. A virtual pattern may thus be viewed as a “pattern
parameter” of the surrounding pattern. A virtual pattern declaration has
the following form:
Vi
index;
restart Search
|| False then Not Found;
if) #);
Figure 12: Example of general control abstraction
Has: Find
(4 Result: @ Boolean;
Not Found :: (#do False > Result##);
doTrue + Result
exit (Result)
Hs
Figure 13: Example of a specialization of Find
to Person.
In figure 12 is given an example of a control abstraction using a virtual
pattern, This Find pattern may be added as an attribute to pattern
Register, Find will search for an element identical to Key. If such an
element is found an inner will be executed. Otherwise the item specified
according to the virtual pattern NotFound will be executed’.
Find may be used to implement pattern Has as shown in figure 13.
In figure 14 Register has been revised by adding two virtual pattern at-
®The predefined pattern Object used in “NotFound :< Object” is assumed to prefic any
pattern, thus NotFound may be bound to any pattern. (On the other hand “Object” has no
attributes and no actions, so no information is given about a virtual qualified by “Object”.)
26tributes: Content and Overflow. Pattern Register may then be used to
define specialized Registers consisting of elements prefixed by Record.
Note that pattern Has uses the specification that Content-objects have a
Key attribute. A Student register may be declared as in figure 15.
Suppose that the pattern Record in addition to Key has a pattern at-
tribute Display, to display the value of Key in some form. Within Register
it would then be possible to have the register displayed by
(for inz: Top repeat Tablefinz]. Display for)
This will, however, only display the Key, even if the Register is a Person
or Book register. Instead the Display attribute may be declared as a
virtual pattern as in figure 16. Then the for-imperative above will have
the effect that the actual binding of Display is executed. A binding of
Display in Person is shown in figure 17.
This binding of Display is final in the sense that Display is no longer
virtual. It would be desirable to be able to extend the specification of
Display in Student and Employee to get such objects displayed too. This
is possible by using the further binding construct
Vu Al
The rules for using a further binding are the same as for using a final
binding. In a further binding the specification of the virtual pattern V is
extended to be a virtual pattern qualified by Al. V is thus still a virtual
pattern and may be further specified in sub-patterns of the surrounding
pattern.
Display may then be specified as shown in figure 18.
Now Display is bound to PersDisp, but it is still a virtual pattern. A new
further binding may then be added in Student and Employee.
‘The use of patterns and sub-patterns makes it possible to construct a
broad variety of abstractions. There are however certain limitations and
disadvantages of this approach: There is an asymmetry between the
use of inner and virtual patterns to construct control abstractions. Note
27Register:
(i Content :< Record; Over flow :< Exception;
Table: {100]@Content; Top: @Integer;
Has:
(# Subject: @Content; Result: @Boolean;
enter (Subject)
do False + Result;
Search:
(for ina: Top repeat
(if ((Tablelinz].Key = Subject-Key) — Result)
// True then leave Search
if)for)
exit (Result)
#)
Insert:
(# New: @Gontent;
enter (New)
do (if ((New) + Has) // False then
Top +1 — Top;
(if (Top < Tablesrange)
// True then New — Table[T op]
// False then Over flow
if)if) #);
Remove: .
For All:
Find:
do0 = Top;
Hs
Figure 14: The Register pattern parameterized with virtual patterns
28UpdateStatus: Find
(4 Status: @StatusT ype;
NotFound :: (4 ...4)
enter (Status)
do Status —+ Tablelindez]. Status
#)
#)
Figure 15: Example of a specialization of the Register pattern
Record:
(i Key: @Integer;
‘#do {display the Key value} inner #);
RecDisp
Figure 16: Virtual Display attribute
Person: Record
(# Name: @String; Sex: @Se2T ype;
Display :: RecDisp(#do {display Name and Sex} #)
#)
Figure 17: Binding of the virtual Display attribute
Person: Record
(# Name: @String; Sex: @SexT ype;
PersDisp: RecDisp(# ...#f);
Display ::< Pers Disp;
#)
Figure 18: Further binding of the virtual display attribute
29the pattern Find where if the desired element is found, inner is exe-
cuted, otherwise the virtual pattern NotFound is executed. In section 5
of [BETA 83b] a generalization of virtual patterns is proposed in order
to deal with these problems. In [BETA 87] the notion of virtual patterns
is further exploited.
30Part 2: MULTI-SEQUENTIAL EXECUTION
The BETA programming language supports a number of
different organizations of action sequences. These are: —
sequential action-sequences, where procedures are executed
sequentially — alternation which is a generalization of corou-
tine sequencing as found in SIMULA 67 — concurrency which
is found in languages like CONCURRENT PASCAL, CSP
and Ada. In this part of the paper the constructs for multi-
sequential execution, that is alternation and concurrency will
be described. Communication between concurrent compo-
nents takes place by synchronized execution of items. This is
similar to a rendezvous in Ada. BETA has no constructs for
guarded input/output as do CSP and Ada. Instead a combi-
nation of alternation and block structure is used.
5 Introduction
In the first part of this paper the abstraction mechanisms of BETA,
pattern, sub-pattern and virtual pattern were presented. In this second
part of the paper the treatment of action sequencing between objects in
a program execution is presented. Action sequencing appears in several
ways in programming languages. The simplest mechanism is sequential
execution, where procedures are executed sequentially and the dynamic
structure of active procedure activations is organized as a stack.
For many applications it is more natural to organize a program exe-
cution as several sequential processes. This mode of execution is called
multi-sequential execution. Several language constructs that support mul-
tiple action sequences have been proposed. In [Conway 63] the notion of
31coroutine sequencing is proposed. Coroutine sequencing is different from
sequential execution since a coroutine may temporarily suspend execu-
tion and later be resumed. This means that coroutines are useful to
support program executions with multiple action sequences. The use-
fulness of coroutines is demonstrated by the languages SIMULA and
MODULA 2 [Wirth 82]. The generator concept of the language Icon
[Griswold et al. 81] also demonstrates the usefulness of the coroutine con-
cept.
The sequencing between coroutines is deterministic and explicit, since
the programmer specifies as part of the coroutine when it shall suspend
its actions and which coroutine is to take over. A semi-coroutine always
returns to the caller. A symmetric coroutine may transfer the control to
any other coroutine.
In a number of situations a program execution has to deal with multiple
action sequences that go on concurrently. Coroutines are not suitable
to support such concurrent action sequences. In the coroutine situation,
each coroutine has exclusive access to common data and there is no need
for synchronization. However, to explicitly handle the sequencing be-
tween a large number of symmetric coroutines requires a strict discipline
of the programmer. In the concurrent situation, it is often necessary to
be able to deal with non-determinism: For example, the case in a sys-
tem with multiple processors. The needs for handling concurrent action
sequences have resulted in a number of languages that support concur-
rency: CONCURRENT PASCAL ([Brinch-Hansen 75]), CSP [Hoare 78]
and Ada [Ada 80]. In CSP and Ada, non-determinism is represented
by means of guarded input/output commands. That is, within an object
(process, task) describing one action-sequence, it is possible to wait for
one or more communications with other objects.
The BETA language supports sequential execution, alternation and con-
currency. In addition a general way of specifying compound objects has
been introduced. Alternation and compound objects are useful structur-
ing mechanisms. Used together they may among others be an alternative
to guarded commands. Below we briefly summarize the BETA constructs
treated in this part.
As mentioned in part 1, objects may be of three kinds: system, compo-
32,nent, or item. In part 1, the constructs for generation and execution of
items were described.
Objects of kind system support non-deterministic multiple action se-
quencing in the form of concurrency. Systems may be executed by means
of a concurrent-imperative, This imperative is similar to Dijkstra’s par-
begin, parend, but the constituent parts of a concurrent-imperative are
systems (like in CSP) and not arbitrary imperatives.
Systems may communicate by means of synchronized execution of items.
One system (the sender) may request another system (the receiver) to
execute an item. The receiver must execute an accept-imperative before
the communication takes place. The sender must name the receiver. The
receiver specifies that the sender must belong to some restricted set of
systems. This set may as extremes consist of one specific system or the
set of all systems.
Synchronization between systems is similar to the handshake in CSP
or rendezvous in Ada. In CSP both the sender part and the receiver
part in a communication must be named. In Ada only the sender must
name the receiver whereas the receiver accepts all systems. The BETA
approach includes these two extremes as special cases. Concurrency and
synchronization are described in section 6.
By means of textual nesting (block structure) it is possible to specify
compound systems. A system may specify concurrent or alternating ex-
ecution of one or more internal objects. Such a compound system will
then have several ongoing action sequences. External systems may com-
municate directly with the internal systems without synchronizing with
the enclosing system. Internal systems may execute items belonging to
an enclosing system. Such items are executed one at a time. In this
aspect an enclosing system is functioning similar to a monitor in CON-
CURRENT PASCAL. Few programming languages support compound
systems in a general sense. In Ada, for example, it is possible to specify
compound systems in the form of nested tasks. However, the communi-
cation with internal tasks is limited. It is not possible in Ada to call entry
procedures of internal tasks of a task. Compound systems are described
in section 7.
33,A number of activities may be modelled by means of compound systems
consisting of several concurrent action sequences. Examples of this are
machines consisting of several parts each executing an independent action
sequence. In other cases an activity may be characterized by performing
several action sequences, but at most one at a time. The activity will then
shift between the various action sequences. An example of this is a cook
making dishes. This involves several ongoing activities by the cook who
constantly shifts between those requiring his attention. An activity like
this may be described in BETA by means of objects of kind component
and a mode of execution called alternation.
Alternating execution of components is specified by means of the alternation-
imperative. Alternating execution of a list of components means that only
one of the components will execute its action-part at a time. The compo-
nents not executing actions are delayed at well defined points. Interleav-
ing (shift of execution to another component) may only take place when
a component is (1) at the beginning of its action-part, (2) attempting to
make a communication, or (3) has suspended its execution of actions.
A processor handling several devices may naturally be described by al-
ternation. The processor may be a compound system consisting of a
number of alternating components each serving its own device. The use
of components and alternation is further described in section 8.
346 Concurrent Execution of Systems
In this section generation of objects of kind system and concurrent ex-
ecution of systems is described. The following example shows a BETA
program containing three systems, Slavel, Slave2, and Master. Slavel
and Slave2 are generated according to the pattern Slave. Slavel and
Slave2 are static systems. This mode of generation is quite analogous
to the generation of static items as demonstrated in part 1 of the paper.
Master is also aa static system, but described directly without referring
to a pattern.
‘The action-part of the program consists of the concurrent-imperative
(|| Master || Stavel || Slave? ||)
A concurrent-imperative specifies concurrent execution of the systems.
‘The concurrent-imperative terminates when all the involved systems have
suspended execution of their actions. A system is suspended when it
either has executed a suspend-imperative or has finished executing its
action-part.
a
Slave: (# ...4)5
Slavel: @ || Slave;
Slave2: @ || Slaves
Master: @ || (# ...#);
do
(|| Master || Stavel || Slave? ||)
6.1 System Communication
Communication between systems takes place by means of synchronized
execution of items. A system S may request a system R to execute a
specific item belonging to R. The system R must signal that it is willing
to execute that specific item if requested by S. The program fragment in
figure 19 illustrates two communicating systems:
35do lp RIM £2...
#s
R:@||
(HM: Q(# ...with Sdo ...#)5
Figure 19: Sketch of two communicating systems
The system $ may execute a request-imperative of the form:
E1l— R>?M = E2
which means that the system R is requested to make a synchronized
execution of the item M. The parts E1 —> (called the predecessor of M)
and — E2 (called the successor of M) are optional. M is a static item
attribute of R and may be declared as follows:
M: O( ... with Sdo ...#)
‘The with-part of M specifies that M may be executed synchronized with
the system $. In order to signal that R is willing to execute M, R may
execute an accept-imperative of the form:
?M and R is
executing 2 is present), then S and R must be
synchronized during the value-transfer between M and 2. £2 is
then executed by $ independently of R.
4. S and R must be synchronized at at least one point in time during
the communication.
'S is called the sender and R the receiver.
A communication is thus similar to a rendezvous in Ada. The evaluation
of the input values (Z1 —) is carried out by the sender independently
of the receiver. During the transfer of the input values, the sender and
receiver must be synchronized. Similarly for the output values (> B2). If
no input values (output values) are present, then the sender and receiver
need only be synchronized during the transfer of the output values (input
values). If neither input values nor output values are present, then the
sender and receiver must be synchronized at at least one point in time.
‘The example in figure 20 shows a BETA program with communicating
systems. The Master-system transmits a sequence of values to the two
Slave-systems. Bach Slave-system computes the sum of the values be-
ing received. Bach value is received and accumulated by a synchronous
execution of Incr. The transmission of values is terminated by a zero.
Then the Slave-systems return the sums to the Master-system by a syn-
chronous execution of Result. Positive numbers are transmitted to Slavel
and negative numbers are transmitted to Slave2.
6.2 The Some-Construct
As described above, the with-part of an object specifies that only one
specific system may be the sender-part of a communication involving
the object. It is often desirable to specify that the sender-part of a
communication may be selected from a restricted set of systems.
37G#
Slave:
(# Sum: @Integer;
Iner: @(# I: @Integer
enter (I)
with Master
do Sum +I -+ Sum
ts
Result: @(4# with Master exit (Sum)#)
do0 > Sum;
Loop: Cycle
(do <2Iner;
(if Incr.I //0 then leave Loop if);
#)
Result;
#)s
Slavel: @ || Slave;
Slave2: @ || Slave;
Master: @ ||
(# Pos, Neg: @Integer; V: [100] @Integer;
do Readin; { read values to V }
(for inz: 100 repeat
(if True
/[ V{inz] > 0 then (V{inz]) + Slavel>?Iner
/[V{inz] <0 then (V|inz]) + Slave2>?Iner
if)for);
(0) + Slavet>?Incr; Slavel>?Result + Pos;
(0) + Slave2>?Incr; Slave2>? Result + Neg;
#)
do (|| Master || Slavel || Slave? ||)
#)
Figure 20: Example of concurrent systems
38The construct some P may be used to specify that the sender-part may
be any system which is qualified by P. (See section 3.)
This may be specified as follows:
M: Q(# ... withsome P...44)
If ?M.
The example in figure 21 illustrates the use of some. The systems using
SingleBuf must be qualified by Producer or Consumer. Only Producer.
systems may use Put and only Consumer-systems may use Get, The
description of the system Prod has the form Producer(# ...4¢), which
implies that Prod is qualified by Producer.
The above approach includes the possibilities of CSP and Ada to specify
the sender-part of a communication. In CSP one is forced to name one
specific system. In Ada all systems may appear as the sender-part of a
communication. In BETA it is in addition possible to restrict the possible
sender-systems to a set of systems belonging to a pattern.
39Producer: (4 ...4)s
Consumer: (# ...#)5
SingleBuf: @ ||
(#BufCh: @Char;
Put: @(# enter (Buf Ch) with some Producer#);
Get: @( with some Consumer exit (BufCh)#);
do Cycle(#.do SingleBuf>?Put...
Cons: @ || Consumer
(#Ch: @Char;
do ...SingleBuf>?Get + Ch {consume a character}
#)
do
(\ Prod || SingleBuf || Cons ||)
#)
Figure 21: Example of partial restrictions on cummunication partners
407 Compound Objects
Just as it is useful to be able to construct compound items it is useful to
be able to construct compound systems. It should be possible to refine a
system into more systems and in this way construct a compound system
that consists of multiple action sequences. In this section it is shown that
block structure is useful for constructing compound systems.
In BETA the actions to be performed by a system may be distributed
among several internal systems. The internal systems may be more or less
independent. They may access common data (items in an enclosing sys-
tem), communicate with each other, communicate with external systems
or control communications between external systems and the enclosing
system. Below the behavior of compound systems is described.
7.1 Execution of Global Items
Execution of an item belonging to an enclosing system may be requested
from an internal system, The actual execution of the item will be per-
formed by the system to which the item belongs. Consequently only one
global item of an enclosing system may be executed at a time. If two
or more internal systems request execution of a global item, they will
be served one at a time. The enclosing system must be executing either
a concurrent-imperative or an alternation-imperative (see section 9) in
order to execute a request from an internal system.
The example in figure 22 describes a picture, represented by the Picture-
system. The actual picture is represented by the internal static item
pictureData, The operations upon pictureData are the items Update and
Get. The picture is constantly being displayed on a screen. This is
performed by the internal system Display. The picture may be changed by
means of external requests. The internal system Control handles possible
external requests and updates the picture. The systems Display and
Control need not synchronize as the Display-system always displays the
latest version of the picture. The operations upon pictureData must be
indivisible. The Display-system reads the picture by requesting execution
of the global item Get. Similarly the Controlsystem updates the picture
41(#
Picture: @ ||
«5 {representation of the picture}
{operation to update the picture}
{read the picture}
Display: @ || (#f ...do Cycle(# do Get + Sereen>?showst)#);
Control: @ ||
(Hrequest: @(# do ...;Update;... 4);
do Cycle(# do ?X1; ...#);
Foys: @ ||
(#X1,Y1: @realPort; F: (4 ...4)
do Cycle
(#do?X2 {await output to Gsys}
BS
Gsys: @ ||
(#X2,Y2: GrealPort; G: (4 ...#)
do Cycle
(#do?X3; {await output to Heys}
+ @ |
(# X3,Y8: @realPort; H: (# ...4)
do Cycle
(#do?¥3 -+ B; ...4)
do (|| In || Pipe || Out ||)
#)
Figure 23: Example of communication with internal systems
43#
RB: @ |i
(# M: @T1Port;
N: @T2Port;
ControlM: @ | (#...do
ControlN: @ || (# ...do.
do (|| Control M || Control N ||)
#s
S$: @|| (#...do...R>?M...R>2N...#)
do (\| RI] S|)
#)s
Figure 24: Example of communication using global items
7.8 Communication Using Global Items
A global item may be accessed in an accept-imperative. This means
that an internal system may control the possible communications of an
enclosing system. As with execution of a global item, it is the system to
which the item belongs that executes the item. This again implies that
the system must be executing a concurrent- or alternation-imperative in
order that the request can be accepted. In figure 24 possible accepts of
the requests R>?M and R>?N from the S-system are controlled by the
internal systems ControlM and ControlN of the R-system.
448 Alternating Execution of Components
In the previous sections concurrent execution of systems has been de-
scribed. BETA also contains a generalization of the SIMULA coroutine
construct. Consider the following example:
(#01:0| (#... 4);
C2:@| (#. -#);
02: @| (#...suspend ... 4)
do (| C1] C2] C3)
#)
Cl, C2, and C3 are objects of kind component. Components may be
executed alternating as specified by the imperative:
(|C1|€2| C3)
Alternating execution means that at most one of the components is exe-
cuting its action part at a time. The components not executing actions
are delayed at well defined points in their action sequence. These points
are the same at which interleaving (i.e. shift of execution to another
component) may take place. Interleaving may take place (1) at the be-
ginning of the action-part of the component, (2) when the component is
attempting to make a communication, and (3) when the component has
suspended its action-sequence.
‘The example in figure 25 describes a bounded buffer implemented using
alternation. The internal components Put and Get control the communi-
cation with the Buffer-system. The imperative Pause specifies that this
is a point where interleaving may take place. Pause is not specified here,
but may be implemented as a communication with some system in the
environment, such as a timer-system.
Since the execution of the Put and Get components is alternating, each
component has exclusive access to the buffer representation. Interleaving
may only take place at ?InCh...#);
Buf: @ || Buffer;
Cons: @ || (##...do ... Buf>?0utCh + Ch... #)5
eee
Figure 25: Bounded buffer with alternating components
468.1 Coroutine Sequencing
In SIMULA, an object may also be used in a procedure-like manner by
means of the call/detach-imperatives. This use of objects is called semi-
coroutines in SIMULA. SIMULA also supports full symmetric coroutines
by means of the resume-imperative. One disadvantage of using SIMULA
coroutines (objects) as procedures is that it is not possible to transfer
parameters to and from the object at the point of a call, detach or resume.
In BETA parameter transfer to objects used as procedures and objects
used as semi-coroutines is identical. In figure 26 is shown an example of
using a component as a semi-coroutine.
The pattern nextChar describes a coroutine that reads an ASCIL-file from
a disc. The file is organized as a sequence of blocks of fixed length. 'The
last: block of the file will only be partially filled with characters. ‘The
rest of the block is filled with ASCII null characters and will contain at
least one null. The file contains at least one block. As the last character
of the file, nevtChar will return the ASCII character fileSeparator (fs).
NeztChar will in addition ensure that the last line before fs is terminated
by a lineFeed(if) by always returning a If before the final fs.
The declaration nextCh: @ | nextChar specifies the generation of a static
component. The component is an instance of the pattern nestChar and
has the name neztCh. NeatChmay be executed in an alternation-imperative.
Execution of the imperative suspend within neztCh implies that the exe-
cution of the do-part of neetCh is temporarily suspended. Control returns
to the caller of neatCh and the exit-list of nextCh is evaluated. Succes-
sive calls on nextCh will then resume the execution of neztCh at the point
following suspend.
8.2 Motivation for Alternation
As mentioned in the introduction it is often the case that an activity
may be characterized by performing several activities, but at most one
at a time. One example is a cook making dishes; another example is a
processor serving a number of devices.
ATG@
neztChar:
(#F : Ofile; B : [blockSize] @Char;
chr : @Char; inz : @Integer;
do F.readBlock + B; {a file contains at least one block}
nextBlock:
(if RendFile // False then
(for i : blockSize repeat Bli] — chr; suspend for);
FereadBlock + B;
restart neetBlock
if);
1 ings
last Block:
(if (Blinz] 4 null) // True then
Blinz] + chr; suspend ;
ing +1— ing; restart last Block
if);
If + chr; suspend; {ensure linefeed before endfile}
fa chr
exit (chr) #);
nevtCh:@ | neetChar; {declaration of a component}
ch: @Char;
do...
loop :Cyele
(#do(|nexth — ch|);
(if ch // fs then leave loop
if) #)#)
Figure 26: Example of a component modelling a semi-coroutine
48Alternation makes it possible to structure a program using components
without explicitly having to synchronize access to common data. Most
programs using alternation could be modelled by programs using concur-
rency. However concurrency implies that each system executes actions
with a positive speed. On a single processor this implies time sharing us-
ing a clock. Some implementations of concurrency avoid this by shifting
to another process only at the point of a communication. If this is the
case the program actually consists of alternating components and not of
concurrent systems. In a concurrent program no looping system system
can monopolize the processor whereas this is the case with an alternating
program.
As mentioned in the introduction guarded input/output commands may
be used to handle the non-determinism of communication in a system of
concurrent components. A component involved in communications with
more than one component may then wait for one or more communications
at the same time.
In many situations the different communications are more or less inde-
pendent. Assume that the system A communicates with the systems B,
C, D and E. Then it may be the case that the communications with
B and C are performed in sequence and the communications with D
and E are performed in another sequence, but there is no sequencing
between the two groups of communications. In such a situation it may
be more natural to describe the communication sequences by means of
alternating components. In the above example the system A can be de-
scribed as a compound system consisting of two alternating components,
one for communication with B and C and another for communication
with D and E. In the buffer example, Put takes care of a sequence
of InCh-communications and Get takes care of a sequence of OutCh-
communications.
By using alternation and compound objects instead of guarded commands
one often avoids mixing logically independent action sequences into one
action sequence. This may make the structure of the resulting program
more clear. In addition it simplifies implementation. A CSP-process and
an Ada-task may have several open communications waiting at a time.
When a communication takes place possibly other open communications
of the involved objects must be closed. In BETA each object may wait
49for at most one communication. No open communications need to be
closed when a communication takes place. Finally in CSP and Ada the
use of input and output as guards is not symmetric: It is only possible to
have input-commands (accept-statements) in a guarded command. The
possibility of allowing output-commands as guards in CSP is mentioned
in [Hoare 78]. However, symmetric use of input-/output-guards greatly
complicates the implementation.
Alternation is not an alternative to concurrency, but a supplement. A
number of activities are by nature alternating and non-deterministic and
such activities should not be modelled by concurrent systems, coroutines
or guarded commands. However experience with BETA is necessary to
find out if alternation is a general useful sequencing mechanism.
509 Conclusion
‘The BETA programming language has been developed as part of the
BETA project. The purpose of this project is to develop concepts, con-
structs and tools in the field of programming and programming languages.
BETA has been developed from 1976 on and the various stages of the lan-
guage are documented in [BETA 76-85].
The application area of BETA is programming of large software systems
including embedded as well as distributed computing systems. For this
reason a major goal has been to develop constructs that may be efficiently
implemented. Furthermore it has been attempted to develop a language
with a few basic but general constructs.
There are many reasons for proposing a new programming language.
BETA is intended to be a modern language in the SIMULA tradition.
With the present state of art it is possible to design a more simple, flexible
and powerful language based upon SIMULA. The SIMULA class/subclass
constructs have only been successfully carried over to languages intended
for exploratory programming, such as Smalltalk and its successors FLA-
VORS ([Cannon 82]) and LOOPS ([Bobrow and Stefik 83]). These lan-
guages are “typeless” since variables are not qualified by a class like in
SIMULA and BETA. The advantages of “types” should be well known:
the compiler can catch errors that otherwise would have been discovered
one at a time on run-time, the program is easier to understand, and more
efficient code can be generated, No language has succesfully combined the
class/subclass constructs with constructs for handling concurrency and
alternation. CONCURRENT PASCAL was an attempt, but is lacking
subclasses and virtuals.
SIMULA is a system description and a programming language. The
DELTA language ([DELTA]) is a system description language only, al-
lowing description of full concurrency, continuous change and compo-
nent interaction, developed from a SIMULA conceptual platform. BETA
started from the system concepts of DELTA, but is a programming lan-
guage, drawing upon a large number of contributions to programming
research in the 1970s.
51BETA supports the object oriented perspective on programming. A ma-
jor part of the BETA project has been to develop the basic concepts
underlying object oriented programming. In this paper, however, only
the the BETA programming language has been described. The basic
concepts will be the subject of another paper.
‘The pattern construct is a very general abstraction mechanism. In prac-
tice most patterns are either used as classes, procedures, functions or
types. Few patterns are useful for more than one of these purposes. For
abstract super-patterns* it often appears that no decision is made about
the use of its sub-patterns. The main advantage of having only one ab-
straction mechanism is a uniform treatment of abstraction mechanisms
and their instances. A consequence of having only one abstraction mech-
anism is that hierarchical classification is also available for patterns used
as procedures, functions or types. Another consequence is that the vir-
tual concept is not only available for procedures. Virtual patterns may
model SIMULA-like virtual procedures and Smalltalk methods. In addi-
tion they may model virtual classes which are not available in SIMULA
and Smalltalk. Virtual patterns may also be used for modelling formal
procedures and formal types.
BETA has evolved for many years. Experience from use will probably in-
fluence the language further. Certain parts of the language will definitely
be further developed.
¢ The value concept of BETA needs to be further developed. Some
ideas are described in [BETA 83b]. The notion of enumeration
types from Pascal should be supported. Consider
color = (red, green, white)
In BETA color, red, green, and white will be modelled as patterns.
Red, green, and white will be sub-patterns of color. It should also be
possible to specialize a pattern like red into sub-patterns pink and
ruby. This will make it possible to describe a hierarchy of types
and values.
¢ BETA does not support multiple inheritance. Currently no pro-
‘In Smalltalk terminology, an abstract super-pattern (super-class) is a pattern (class) that is
only used as a super-pattern, That is, no instances are created.
52posal for supporting multiple inheritance has been found accept-
able. The main problem is to replace the inner mechanism for com-
bination of action parts. The solution proposed in [Thomsen 86] is
a promising approach.
In addition to object oriented programming, BETA supports pro-
cedural programming and to a limited extent also functional pro-
gramming. Work is going on to improve the support for functional
programming. In addition support for logic programming will be in-
cluded. All these programming styles will not be supported equally
well. The overall perspective will be object oriented. The functional
and logical programming will primarily be aimed at describing mea-
surable properties of objects and transitions between meaningful
states.
In section 4 on virtual patterns, it was mentioned that there is
an asymmetry between the use of inner and virtual patterns. In
a future version of BETA, the generalization of virtual patterns
proposed in [BETA 83b] will be incorporated.
BETA has no constructs for modularization and protection of data
representation (see section 2.6). Instead a general language inde-
pendent mechanism has been developed ([BETA 83a]) based on the
context-free grammar of a language. The idea is that a program
may be split into arbitrary fragments (modules). A fragment may
be a string of terminal and nonterminal symbols generated from
any nonterminal of the grammar. By defining a partial ordering
between the fragments, it is possible to perform separate context-
sensitive analysis (static semantics). The method may be used to
split a module into an interface-part and an implementation-part
thereby providing protection of data representation. Finally the
mechanism may be used as a basis for constructing a system for
handling different versions/variants of a program.
For a large class of systems, e.g. operating systems, database sys-
tems, the possibility of exchanging components during the life span
(execution) of the system is a natural and inherent property of
the system. In order to do this it is necessary to have a model
of a machine that includes both the program execution and the
processor performing the program execution. Work is going on to
53develop such a model together with language constructs for express-
ing this in BETA. A machine is viewed as an ensemble making a
performance (program execution) according to a play (program)
described in some language (programming language).
e
A set of attributes (patterns and references) realizing concepts and
phenomena from a given application area may be viewed as a lan-
guage for describing systems belonging to that application area.
Often it would be desirable to describe such systems using another
syntax than that of BETA, For this purpose a BETA programming
system should contain a tool that given a set of attributes and a
description of the syntax will produce a new front end of the BETA
compiler.
Despite the above list we think that BETA has reached a state where it
may be usable for programming computer systems.
An experimental version of BETA has been implemented on various Mo-
torola 68000 based machines including Macintosh, SUN and Sysware
SUS. Work is going on to design and implement a programming environ-
ment for BETA. This takes place in a number of projects in Scandinavia
((Mjglner] [Scala}).
Acknowledgement. The BETA project was initiated in 1976 as part of
what was then called The Joint Language Project (JLP). People from The
Regional Computing Center, Aarhus University, Computer Science De-
partment, Aarhus University, Institute for Electronic Systems, Aalborg
University Centre and The Norwegian Computing Center, Oslo partici-
pated in the JLP-project. The initiative for the JLP was taken in the
autumn of 1975 by Bjarner Svejgaard, Director of The Regional Com-
puting Center.
In addition to the JLP team members, a large number of people especially
from Oslo and Aarhus have participated in our discussions. Bruce Moon,
University of Canterbury, and Dag Belsnes, The Norwegian Computing
Center have been most influential. Also the team members of Scala and
Milner have contributed.
The work reported here has been supported by The Royal Norwegian
Council for Scientific and Industrial Research, grant no. ED 0223.16641
54(the Scala project), and by The Danish Natural Science Research Council
grants no. 11-3106 and FTU 5.17.5.1.25.
Finally we want to thank the referees and the editors of this book for
their assistance in improving the readability of this paper. In particular
we want to acknowledge the contributions of Peter Wegner.
5510 References
1, [Ada] Ada Reference Manual. Proposed Standard Document, United States De-
partment of Defense, July 1980.
2, [ALGOL] P. Naur (ed.): Revised Report on The Algoritmic Language ALGOL 60.
Regnecentralen. Copenhagen, 1962.
3. [BETA 76] B.B. Kristensen, 0.L. Madsen, B. Moller-Pedersen, K. Nygard: BETA
Project Working Notes 1-8. Norwegian Computing Center, Oslo and Computer
Science Department, Aarhus University, Aarhus, 1976-1982.
4. [BETA 83a] B.B, Kristensen, O.L Madsen, B. Mgller-Pedersen, K. Nygaard: Syn-
tax Directed Program Modularization. In: Interactive Computing Systems (ed.
P. Degano, E. Sandewall), North-Holland, 1983.
5. [BETA 83b] B.B. Kristensen, O.L. Madsen, B. Mgller-Pedersen, K. Nygard:
Abstraction Mechanisms in the BETA Programming Language. Proceedings of the
Tenth ACM Symposium on Principles of Programming Languages, January 24-26
1988, Austin, Tezas.
6. [BETA 83c] O.L. Madsen, B. Mgller-Pedersen, K. Nygaard: From SIMULA 67
to BETA. Proceedings of the Eleventh SIMULA 67 User’s Conference, September
1983, Paris. Norwegian Computing Center, 1983.
7. [BETA 85] B.B. Kristensen, O.L. Madsen, B. Mgller Pedersen, K. Nygaard: Multi-
sequential Execution in the BETA Programming Language. Sigplan Notices, Vol.
20, No. 4, April 1985.
8. [BETA 87] B.B. Kristensen, O.L. Madsen, B. Mgller-Pedersen, K. Nygaard: Clas-
sification of Actions or Inheritance also for Methods. Proceedings of the Second
European Conference on Object Oriented Programming, Paris, June 1987.
9. [Bobrow and Stefik 83] D.G. Bobrow, M. Stefik: The LOOPS Manual. Xeroz
Corporation 1983.
10. [Brinch-Hansen 75] P. Brinch-Hansen: The Programming Language Concurrent
PASCAL. IEEE Transactions on Software Engineering SE-1, 2 (June 1975), 149-
207.
11. [Cannon 83] H. Cannon: Flavors, A Non-Hierarchical Approach to Object-Oriented
Programming. Draft 1982.
12, [CLU] B. Liskov, A. Snyder, R. Atkinson, C. Schaffert: Abstraction Mechanisms
in CLU. Comm. ACM 20, 8 (1977), 564-576.
13. [ Conway 63] M.E. Conway: Design of a Separable Transition — Diagram Compiler.
Comm. AOM 6, 7 (1963), 396-408.
5614.
15.
16.
1.
18.
19.
20.
21.
22,
23.
24,
(DELTA 75] E. Holbeck Hansen, P. Haandlykken, K. Nygaard: System Description
and the DELTA Language. Norwegian Computing Center, Oslo, 1975.
{DELTA 81] P. Haandlykken, K. Nygard: The DELTA System Description Lan-
guage: Motivation, Main Concepts and Experience from use. In: Software Engi-
neering Environments (ed. H. Hunke), GMD, North-Holland, 1981.
[DeRemer and Krohn] F.L. DeRemer, H. Krohn: Programming-in-the-Large versus
Programming-in-the-Small. IEEE Transactions on Software Engineering, SB-3, 1
(Jan 1977), 69-84.
[Dijkstra 75] E. W. Dijkstra: Guarded Commands,Nondeterminacy, and Formal
Derivation of Programs. Comm. ACM 18, 8 (1975), 1-82.
[Griswold et al. 81] R.E. Griswold, D.R. Hanson, J.T. Korb: Generators in ICON.
AOM Transactions on Programming Languages and Systems 3, 2 (April 81), 144-
161.
[Hoare 72] C. A. R. Hoare: Proof of Correctness of Data Representation. Acta
Informatica 4 (1972), 271-281.
[Hoare 78] C.A.R Hoare: Communicating Sequential Processes. Comm. ACM 21,
8 (1978), 666-677.
[Madsen 86] O.L. Madsen: Block Structure and Object Oriented Languages. Sig-
plan Notices, October 1986. (Also in: B.D. Shriver, P. Wegner (ed.): Research
Directions in Object Oriented Programming, MIT Press, 1987).
[Mjslner] H.P. Dahle, M. Lofgren, O.L. Madsen, B. Magnusson: ‘The Mjglner
Project — A Highly Efficient Programming Environment for Industrial Use. Mjol-
ner report no. 1, Oslo, Malmg, Aarhus, Lund 1986.
The Mjglner project is a joint venture between Elektrisk Bureau a.s., Oslo, Tele-
logic AB, Malmg and Sysware aps, Aarhus; in cooperation with The Norwegian
Computing Center, Oslo, University of Lund, Lund, Aalborg University Centre,
Aalborg, and Aarhus University, Aarhus. It has been initiated by Nordforsk (the
Nordic cooperative organization fo applied research), Copenhagen, which also co-
ordinates the project. The project is partly funded by a grant from The Nordic
Fund for Technology and Industrial Development. The purpose of the project
is to develop a programming environment supporting object-oriented design and
programming.
[PASCAL] N. Wirth: The Programming Language PASCAL. Acta Informatica 1
(1971), 95-63.
[Scala] The Scala project is a joint venture between University of Oslo, Norwegian
Computing Center, Elektrisk Bureau a/s and Norsk Data a/s, funded by NTNF.
‘The purpose of the project is further development of the BETA language, imple-
mentation of a BETA environment (in cooperation with the Mjglner project), and
implementation of BETA on ND machines.
5725.
26.
27.
28.
29.
[SIMULA] 0.J. Dahl, B. Myrhaug, K. Nygard: SIMULA 67 Common Base Lan-
guage. Norwegian Computing Center, Oslo, 1968, 1970, 1972, 1984.
[Smalltalk] A. Goldberg, D. Robson: Smalltalk 80: The Language and its Jmple-
mentation, Addison Wesley 1983.
[Thomsen 1986] K.S. Thomsen: Multiple Inheritance, A Structuring Mechanism
Jor Data, Processes and Procedures. Computer Science Department, Aarhus Uni-
versity, DAIMI PB-209, 1986.
[Wirth 82] N. Wirth: Programming in MODULA 2. Springer Verlag, Berlin, New
York, 1982.
[Vaucher 75] J. Vaucher: Prefixed Procedures: A Structuring Concept for Opera-
tions. Infor, vol. 13, no. 3, October 1975.
58Appendix
In this appendix a summary of the BETA constructs will be given. The following ab-
breviations are used: P, PO: pattern title (name), Dj: declaration, In, Out, B;, range:
evaluation, OS: pattern title or object descriptor, Imp, In: imperative, X, Xi: object,
T, Tz: item, Cy: component, $;: system. Constructs marked by a * are not used in this
paper.
Object descriptor | PO
(H# Di Das... Dy
enterIn
doImp
exit out
#)
Declarations
pattern P: PUP...)
virtual pattern Vic P
further binding Vie P
final binding VuP
static item reference T1: @0S
dynamic item reference T2: P
static component reference | C1: @| OS
dynamic component reference* | C2: t | P
static system reference $1: @ || OS
dynamic system reference* Su t ||P
object repetition B: [range].
59‘Evaluations
inserted item
dynamic item
inserted component*
dynamic component*
inserted system*
dynamic system"
object execution
object reference
assignment evaluation
evaluation list
os
&Os
|os
&| 0s
os
&| 08
x
xa
Els B25...4 En
(Bi, Bay) Bn)
Imperatives
tepetition | (for ina:
selection | (if 20
if)
label L: Imp (
range repeat Imp for)
// Bl then I1
// B2 then 12
// Bn then In
L: 11; 125..n iL)
jumps restart L leave L
alternation | (|C1|C2
|... [En))
concurrency | (|) $1] $2|| ... || S|)
Communication
communication request
communication accept
RS?T