Contraction

Meaning

Certain language constructions which can be cumbersome for the programmer to write can be “contracted” into equivalent forms. The resulting shorter form is called a contraction. The constructions that can be contracted are:

See for example the following collateral declaration of several variables of the same name, followed by it’s corresponding contraction:

int size, int offset, int value := 1024;
int size, offset, value := 1024;

In the contracted form above, the same actual declarer (int) is shared among all the declared variables. The elaboration is still collateral, as implied by the comma separator.

The same can be applied to identity declarations. If we turn the variables above into constants, we have:

int size = 0, int offset = 0, int value = 1024;
int size = 0, offset = 0, value = 1024;

Note that you cannot mix variable declarations and constant declarations in the same contraction. If you tried to do:

int alignment = 1, int value := 1024;
int alignment = 1, value := 1024;

The first collateral declaration is perfectly valid, but the resulting contraction is not. The reason is that in the variable declaration for value the mode at the left is an actual declarer that generates a new name to hold the value, whereas the mode at the left in the identity declaration for alignment is a formal declarer. This becomes more clear if we explicit the generator in the variable declaration:

int alignment = 1, loc int value := 1024;
int alignment = 1, value := 1024; # BAD #

Identity declarations of routines can become clunky:

proc([]real,real)real waverage = ([]real numbers, real weight) real:
begin
 ...
end

The corresponding contracted form, where the actual declarer is shortened to proc, would be:

proc waverage = ([]real numbers, real weight) real:
begin
 ...
end

Note however that the contraction form of a routine declaration is less expressive than the uncontracted form. In the contracted form it is required for the right hand side to be a routine text. That is not the case in the uncontracted form, in which the right hand side can be any unit yielding a routine of the expected mode, like in:

proc(int,int) transformer = (op = add
                             | int(int a, int b)int: a + b
                             | int(int a, int b)int: a * b);

Finally, collateral declarations of the priority of operators can also be contracted in the expected way:

prio isoneof = 6, prio ismanyof = 6;
prio isoneof = 6, ismanyof = 6;

Syntax

Simplified [RR 4.1.1.b:c]:

b) COMMON joined definition of PROPS:
     COMMON joined definition of PROPS, and also token, joined definition of PROP.
c) COMMON joined definition of PROP:
     COMMON definition of PROP.

Note that and also token is the comma symbol in most representations.

The rules above are used in the syntax of all the constructs mentioned in this article. For example the following simplified rule [RR 4.3.1.a] implements priority declarations:

a) priority declaration of DECS:
     priority token, priority joined definition of DECS.

Where priority plays the role of COMMON and DECS of PROPS. The rules for the other constructions are built the same way, so we are not including them here.

See Also