In the previous section, we declared mutliple names. The bounds of the multiple to which the name can refer are included in the generator. In subsequent assignments, the bounds of the new multiple to be assigned must be the same as the bounds given in the generator. In Algol 68, it is possible to declare names which can refer to a multiple of any number of elements (including none) and, at a later time, can refer to a different number of elements. They are called flexible names. Here is an identity declaration for a flexible name:
REF FLEX[]INT fn = LOC FLEX[1:0]INT
There are several things to note about this declaration. Firstly,
the mode of the name is not REF[]INT
, but REF
FLEX[]INT. The FLEX means that the
bounds of the multiple to which the name can refer
can differ from one assignment to the next. Secondly, the bounds of
the name generated at the time of the declaration are
[1:0]
. Since the upper bound is less than the lower
bound, the multiple is said to be flat; in
other words, it has no elements at the time of its
declaration6.6.
Thirdly, FLEX
is present on both sides of the identity
declaration (but in the last section of this chapter we shall see a
way round that).
We can now assign multiples of integers to fn
:
fn:=(1,2,3,4)
The bounds of the multiple to which fn
now refers are
[1:4]
. Again, we can write
fn:=(2,3,4)
Now the bounds of the multiple to which fn
refers are
[1:3]
. We can even write
fn:=7
in which the right-hand side will be rowed to yield a
one-dimensional multiple with bounds [1:1]
, and
fn:=()
giving bounds of [1:0]
.
In the original declaration of fn
the bounds were
[1:0]
. The compiler will not ignore any bounds other than
[1:0]
, but will generate a name whose initial bounds are
those given. So the declaration
REF FLEX[]INT fn1 = LOC FLEX[1:4]INT
will cause fn1
to have the bounds [1:4]
instead of
[1:0]
.
The lower bound does not have to be 1
. In this
example,
REF[]INT m1 = LOC[-1:1]INT; FOR i FROM LWB m1 TO UPB m1 DO m1[i]:=i+3 OD; REF FLEX[]INT f1 = LOC FLEX[1:0]INT := m1
the bounds of f1
after the initial assignment are
[-1:1]
.
If a flexible name is sliced or trimmed, the resulting name is called a transient name because it can only exist so long as the flexible name stays the same size. Such names have a restricted use to avoid the production of names which could refer to nothing. For example, consider the declaration and assignation
REF FLEX[]CHAR c1 = LOC FLEX[1:0]INT; c1:="abcdef";
Suppose now we have the declaration
REF[]CHAR lc1=c1[2:4]; #WRONG#
followed by this assignment:
c1:="z";
It is clear that lc1
no longer refers to anything
meaningful. Thus transient names cannot be assigned without being
dereferenced, nor given identifiers, nor used as parameters for a
routine (whether operator or procedure). However there is nothing to
prevent them being used in an assignment. For example,
REF FLEX[]CHAR s=LOC[1:0]CHAR:= "abcdefghijklmnopqrstuvwxyz"; s[2:7]:=s[9:14]
where the name yielded by s[9:14]
is immediately dereferenced.
Note that the bounds of a trim are fixed even if the value trimmed is a
flexible name. So the assignment
s[2:7]:="abc"
would produce a run-time fault.
REF FLEX[]CHAR s = LOC FLEX[1:0]CHARapplies to the following: Ans
s
?
s
?
Sian Mountbatten 2012-01-19