Type Designators



next up previous contents index
Next: Type Equality Up: Types and Parameterized Previous: Built-in Types

Type Designators

There are four different kinds of types in Theta, each with its own particular type designator form. These forms are explained in the following sections. Type designators are also defined by equates (4.6).

Simple Types

Simple types are defined by non-parameterized type specifications (9). They include all non-parameterized user-defined types and several of the built-in types. A simple type is designated by its name:

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

Parameterized Type Instantiations

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 method
The 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 method
If type "employee" does not have a "copy" method, the second instantiation results in an "array" type that does not have a "copy" method.

Routine Types

There are two kinds of routines, procedures and iterators (see Section 6.1). Routine type designators have the following special form:
<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

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".



next up previous contents index
Next: Type Equality Up: Types and Parameterized Previous: Built-in Types



theta-questions@lcs.mit.edu