Copyright © 1996, 1997 Lucent Technologies Inc. All rights reserved.

9.8 alt statement

The alt statement transfers control to one of several groups of statements depending on the readiness of communication channels. Its syntax resembles that of case:


labelopt alt { qual-statement-sequence }
However, the qualifiers take a form different from those of case. In alt, each qualifier must be a *, or an expression containing a communication operator <- on a channel; the operator may specify either sending or receiving. For example,
	outchan := chan of string;
	inchan := chan of int;
	alt {
		i := <-inchan =>
			sys->print("Received %d\n", i);
		outchan <- = "message" =>
			sys->print("Sent the message\n");
	}
The alt statement is executed by testing each of the channels mentioned in the qual-list expressions for ability to send or receive, depending on the operator; if none is ready, the program blocks until at least one is ready. Then a random choice from the ready channels is selected and control passes to the associated set of statements.

If a qualifier of the form * is present, then the statement does not block; if no channel is ready the statements associated with * are executed.

If two communication operators are present in the same qualifier expression, only the leftmost one is tested by alt. If two or more alt statements referring to the same receive (or send) channel are executed in different threads, the requests are queued; when the channel becomes unblocked, the thread that executed alt first is activated.

As with case, each qualifier and the statements following it up to the next qualifier together form a separate separate scope, like a block; declarations within this scope disappear at the next qualifier (or at the end of the statement.) Thus, in the example above, the scope of i in the arm

		i := <-inchan =>
			sys->print("Received %d\n", i);
is restricted to these two lines.

As mentioned in the specification of the channel receive operator <- in §8.2.7, that operator can take an array of channels as an argument. This notation serves as a kind of simplified alt in which all the channels have the same type and are treated similarly. In this variant, the value of the communication expression is a tuple containing the index of the channel over which a communication was received and the value received. For example, in

	a: array [2] of chan of string;
	a[0] = chan of string;
	a[1] = chan of string;
	. . .
	(i, s) := <- a;
	# s has now has the string from channel a[i]
the <- operator waits until at least one of the members of a is ready, selects one of them at random, and returns the index and the transmitted string as a tuple.

During execution of an alt, the expressions in the qualifiers are evaluated in an undefined order, and in particular subexpressions may be evaluated before the channels are tested for readiness. Therefore qualifying expressions should not invoke side effects, and should avoid subparts that might delay execution. For example, in the qualifiers

	ch <- = getchar() =>	# Bad idea
	ich <- = next++ =>	# Bad idea
getchar() may be called early in the elaboration of the alt statement; if it delays, the entire alt may wait. Similarly, the next++ expression may be evaluated before testing the readiness of ich.

05/Jun/97