<simple_type_desig> -> <idn> | 'null' | 'bool' | 'char' | 'int' | 'real' | 'string' | 'any'

A parameterized type has one or more type parameters. A type designator for such a type denotes an instantiation by providing an actual type for each type parameter:

<parm_type_desig> -> <parm_type> "[" <type_list> "]"where

<parm_type> -> <idn> | array | sequence | vector | maybe <type_list> -> <type_designator> ["," <type_designator>]*

The specification (9.3) of a parameterized type can use where clauses to require that actual parameters have certain methods. An instantiation of a parameterized type is legal provided it has the right number of actual parameters, and the actual parameters satisfy the restrictions of the where clauses. For example, consider a user-defined parameterized type, "set[T]"; since sets do not contain duplicate, the specification for "set" permits instantiation only if the argument type provides an equality method (which allows duplicates to be recognized):

set = type [T] where T has equal: proc (T) returns (bool)Here are some instantiations of "set":

set[int] % supplies the int equal method for T's equal set[array[int]] % supplies the array[int] equal method for T's equal set[int,bool] % not legal - compile-time error set[employee] % legal only if employee has an equal methodThe third instantiation is not legal because it does not supply the right number of parameters. The last instantiation will be legal only if type "employee" has an "equal" method; otherwise there will be a compile-time error.

Some methods of a parameterized type may place additional constraints on a parameter by having where clauses of their own. Such a method is optional: if an instantiation satisfies its requirements, the resulting type will have the method, otherwise it will not. When such a parameterized type is instantiated, methods are selected to satisfy the constraints of the optional methods if possible. The result is a type with all the non-optional methods, plus any of the optional methods whose constraints are satisfied. For example, "array" (B.8) has an optional "copy" method that requires that the actual parameter have a "copy" method. Here are some instantiations of "array":

array[int] % has a copy method array[employee] % may not have a copy methodIf type "employee" does not have a "copy" method, the second instantiation results in an "array" type that does not have a "copy" method.

<routine_type_desig> -> proc <nonparam_proc_sig> | iter <nonparam_iter_sig> <nonparam_proc_sig> -> "(" [<type_list>] ")" [<returns>] [<signals>] <nonparam_iter_sig> -> "(" [<type_list>] ")" <yields> [<signals>] <type_list> -> <type_designator> ["," <type_designator>]*These type designators indicate the kind of routine, and the types and numbers of the arguments, results, and exceptions. For example:

proc(int, int) returns (bool) signals (negative) iter(stree[int]) yields (int)

Tagged types include the "record", "struct", and "oneof" types. They are special parameterized types that possess named fields and are designated by the following special form:

<tagged_type_desig> -> <tagged_type> "[" <field> ["," <field>]* "]" <tagged_type> -> 'record' | 'struct' | 'oneof' <field> -> <idn_list> ":" <type_designator>These type designators provide a name for each field and give its type. For example

record[x, y: int, s: string]defines a "record" type. Records of this type have three fields: two "int" fields named "x" and "y", and a "string" field named "s".

theta-questions@lcs.mit.edu