In the last section, we discussed the consequences of the
uniting coercion; that is, how values of various
modes can be united to values of united modes. This raises the
question of how a value of a united mode can be extracted since its
constituent mode cannot be determined at
compile-time. There is no de-uniting coercion in Algol 68. The
constituent mode or the value, or both, can be determined using a
variant of the case clause discussed in chapter 4 (see
section 4.6). It is called
a conformity clause. For our discussion, we
shall use the declaration of u
in
section 8.1 (u
has mode STRINT
).
The constituent mode of u
can be determined by the
following:
CASE u IN (INT): print("u is an integer") , (STRING): print("u is a string") ESAC
If the constituent mode of u
is INT
, the
first case will be selected. Notice that the mode
selector is enclosed in parentheses and followed by
a colon. Otherwise, the conformity clause is just like the case
clause (in fact, it is sometimes called a conformity case
clause). This particular example could also have
been written
CASE u IN (STRING): print("u is a string") OUT print("u is an integer") ESAC
This is the only circumstance when a CASE
clause can
have one choice. Usually, however, we want to extract the value. A
slight modification is required:
CASE u IN (INT i): print(("u identifies the value",i)) , (STRING s): print(("u identifies the value ",s)) ESAC
In this example, the mode selector and identifier act as the left-hand side of an identity declaration. The identifier can be used in the following unit (or enclosed clause).
The two kinds of conformity clause can be mixed. For example, here
is one way of using the procedure ucis
:
CASE ucis(c,s) IN (VOID): print("The character was not found"), (INT p): print(("The position was",p)) ESAC
We mentioned in the last section that operators with united-mode operands can be declared. Here is one such:
MODE IC = UNION(INT,CHAR); OP * = (IC a,b)IC: CASE a IN (INT ai): (b|(INT bi): ai*bi, (CHAR bc): ai*bc), (CHAR ac): (b|(INT bi): ac*bi, (CHAR bc): ABS ac*ABS bc) ESAC
In each of the four cases, the resulting product is united to the mode
IC
.
You can have more than one mode in a particular case. For example:
MODE ICS = UNION(INT,CHAR,STRING); OP * = (ICS a,INT b)ICS: CASE a IN (UNION(STRING,CHAR) ic): (ic|(CHAR c): c*b,(STRING s): s*b), (INT n): n*b ESAC
Note that conformity clauses do not usually have an OUT
clause
because the only way of extracting a value is by using the
(MODE id):
construction. However, they do have their uses. See
the standard prelude for more examples of conformity clauses.
Although read and print use united modes in their call, you cannot read a value of a united mode or print a value of a united mode (remember that united modes do not introduce new values). You have to read a value of a constituent mode and then unite it, or extract the value of a constituent mode and print it.
MODE IRC = UNION(INT,REAL,COMPL), MIRC= UNION([]INT,[]REAL,[]COMPL)are used in this and the following exercises. Write a procedure which takes a single parameter of mode
MIRC
and which yields the sum of all the elements of its parameter as a
value with mode IRC
.
Ans*
whose header is
declared as
OP * = (IRC a,b)IRC:Use nested conformity clauses. Remember that there are 9 separate cases. Ans
Sian Mountbatten 2012-01-19