.sr sect_except Section`12 .sr sect_for_stmt Section`11.5.2 .sr sect_decl_w_init Section`8.2.2 .sr sect_update_sugars Section`11.2 . .chapter "Assignment and Invocation" .para The two fundamental actions of CLU are assignment of computed objects to variables, and invocation of procedures (and iterators) to compute objects. All other actions are merely compositions of these two. Since the correctness of assignments and invocations depends on a type-checking rule, we describe that rule first, then assignment, and finally invocation. .section "Type Inclusion" .para CLU is designed to allow compile-time type-checking. The type of each variable is known by the compiler. Furthermore, the type of objects that could result from the evaluation of an expression (invocation) is known at compile-time. Hence, every assignment can be checked at compile-time to make sure that the variable is only assigned objects of its declared type. The rule is that an assignment 2v*`:=`2E* is legal only if the set of objects defined by the type of 2E* (loosely, the set of all objects that could possibly result from evaluating the expression) must be included in the set of all objects that could be denoted by 2v*. .para Instead of speaking of the set of objects defined by a type, we generally speak of the type and say that the type of the expression must be 2included in* the type of the variable. If it were not for the type any, the inclusion rule would be an equality rule. This leads to a simple interpretation of the type inclusion rule: .show 2 .fi .ir +500m The type of a variable being assigned an expression must be either the type of the expression, or any. .ir -500m .nf .eshow .section "Assignment" .para Assignment is the means of causing a variable to denote an object. Some assignments are implicit, i.e., performed as part of the execution of various mechanisms of the language (most notably procedure invocation, iterator invocation, exception handling, and the tagcase statement). All assignments, whether implicit or explicit, are subject to the type inclusion rule. The remainder of this section discusses explicit assignments. .para The assignment symbol ":=" is used in two other syntactic forms that are not true assignments, but rather abbreviations for certain invocations. These forms are used for updating structures such as records and arrays (see sect_update_sugars). .subsection "Simple Assignment" .para The simplest form of assignment is: .show idn := expression .eshow In this case the expression is evaluated, and the resulting object is assigned to the variable. The expression must return a single object (whose type must be included in that of the variable). Examples of simple assignments are: .show 5 x := 1 s(1)% x's type must include int, i.e., it must be int or any y := string$substr (s, 5, n)t(1)% y's type must include string a := array [int]$new ()t(1)% a's type must include array [int] p := array [int]$create(3)t(1)% p's type must include array [int] z := (foo = bar) t(1)% z's type must include bool .eshow It is also possible to declare a variable and assign to it in a single statement; this is called a declaration with initialization, and was discussed in sect_decl_w_init. .subsection "Multiple Assignment" .para There are two forms of assignment that assign to more than one variable at once: .show idn, etc := expression, etc .eshow and .show idn, etc := invocation .eshow .para The first form of multiple assignment is a generalization of the simple assignment. The first variable is assigned the first expression, the second variable the second expression, and so on. The expressions are all evaluated (from left to right) before any assignments are performed. The number of variables in the list must equal the number of expressions, no variable may occur more than once, and the type of each variable must include the type of the corresponding expression. .para This form of multiple assignment allows easy permutation of the objects denoted by several variables: .show 2 x, y := y, x i, j, k := j, k, i .eshow and similar simultaneous assignments of variables that would otherwise require temporary variables: .show 2 a, b := (a + b), (a - b) quotient, remainder := (u / v), (u // v) .eshow Notice that there is no form of this statement with declarations. .para The second form of multiple assignment allows us to retain the objects resulting from an invocation returning two or more objects. The first variable is assigned the first object, the second variable the second object, and so on. The order of the objects is the same as in the return statement of the invoked routine. The number of variables must equal the number of objects returned, no variable may occur more than once, and the type of each variable must include the type of the corresponding expression. .para Here are two examples of this statement, one without declarations, and one with: .show 2 first, last, balance := acct$query (acct_no) x, y, z: real := vector$components (v) .eshow .section "Invocation" .para Invocation is the other fundamental action of CLU. In this section we discuss procedure invocation; iterator invocation is discussed in sect_for_stmt. However, up to and including passing of arguments, the two are the same. .para Invocations take the form: .show primary ( lbkt expression, etc rbkt ) .eshow A primary is a slightly restricted from of expression, which includes variables and routine names, among other things. (See next section.) .para The sequence of activities in performing an invocation are as follows: .nlist The primary is evaluated. It must evaluate to a procedure or iterator. .nnext The expressions are evaluated, from left to right. .nnext New variables are introduced corresponding to the formal arguments of the routine being invoked (i.e., a new environment is created for the invoked routine to execute in). .nnext The objects resulting from evaluating the expressions (the actual arguments) are assigned to the corresponding new variables (the formal arguments). The first formal is assigned the first actual, the second formal the second actual, and so on. The type of each object must be included in the type of the corresponding formal argument. .nnext Control is transferred to the routine at the start of its body. .end_list An invocation is considered legal in exactly those situations where all the (implicit) assignments involved in its execution are legal. .para commentary It is permissible for a routine to assign to a formal argument variable; the effect is just as if it assigned to any of its other variables. From the point of view of the invoked routine, the only difference between its formal argument variables and its other local variables is that the formals are initialized by its caller. .para When an invoked procedure terminates, it returns zero or more result objects, agreeing in number, order, and type with the information in the procedure header. However, procedures can terminate in two ways: they can terminate 2normally*, returning zero or more objects, or they can terminate 2exceptionally*, signalling an exceptional condition. When a procedure terminates normally, the result objects become available to the caller, and will (sometimes) be assigned to variables. When a procedure terminates exceptionally, the flow of control will not go to the point of return of the invocation, but rather will go elsewhere as described in sect_except. .para Here are some examples of invocations: .show 2 p () s(1)% invoking a procedure taking no arguments array [int]$create (-1)t(1)% invoking an operation of a type routine_table [index] (input)t(1)% invoking a procedure fetched from an array .eshow