## Types

A type defines the set of possible values of an expression or a variable. Its syntax is defined as follows.

- The `ElementaryType` block contains types that do not build on other types. They are explained further in Elementary types.

- The `ContainerType` block contains types that can store values of a single other type, the 'list', 'set', and 'dictionary' type. These types are further explained in Container types.

- The `TupleType` block describes 'tuples', a type that can hold values of several other types.

- The `ChannelType` blocks describes communication channels that connect processes with each other, see Channel type for more explanation.

- The `DistributionType` block contains the stochastic distribution type, explained in Distribution type.

- The `FunctionType` can hold a function definition. It allows you to pass a function to a process or another function. It is further explained in Function type.

- The `ProcessType` can hold a process definition. It allows you to pass a process definition to a another process. It is further explained in Process type.

The `TypeName` is the name of a type defined with a `type` definition (explained in Type definitions). For example:

    type lot = real;

    model M():
        lot x;

        ...
    end

The `lot x` variable declaration (explained in Local variables) uses the type definition of `lot` at the first line to define the type of variable `x`.

The `EnumTypeName` is similar, except it uses an enumeration definition (see Enumeration definitions) as type. For example:

    enum FlagColours = {red, white, blue};

    model M():
        FlagColours x = white;

        ...
    end

The `FlagColours x` variable declaration defines that variable `x` has the type of the enumeration, and can hold its values.

### Elementary types

The elementary types do not depend on other types to define their set of allowed values. They have the following syntax:

As you can see, they are mostly just a single keyword. The `ConstantExpression` nodes in the `matrix` type line are integer expressions with a fixed (and known) value before execution of the program. More information about the elementary types is provided below.

#### Boolean type

The `bool` keyword denotes the boolean data type. The allowed values are `false` and `true`. While it is allowed to store boolean values in other data types, their most frequent use is in expressions of statements that decide what to do, for example, the condition in the `while`, `if` or select statement (see While loop statement, Choice statement and Select statement). Expressions with booleans are explained in Boolean expressions.

#### Integer type

The `int` keyword denotes the integer data type, integer numbers from `2147483647` to `-2147483648` (a standard signed 32 bit number). Values outside that range give undefined behavior. Expressions with integers are explained in Integer expressions.

#### Real type

The `real` keyword denotes the real number data type, real numbers between `4.94065645841246544e-324` to `1.79769313486231570e+308` positive or negative (a standard 8 bytes IEEE 754 number). As normal with floating point numbers in computer systems, many values are missing from the above range. Expect rounding errors with each calculation. Expressions with real numbers are explained in Real number expressions.

#### String type

The `string` keyword denotes strings, sequences of characters. It contains all printable ASCII characters U+0020 to U+007E, and 'tab' (U+0009) and 'new line' (U+000A). Expressions with strings are explained in String expressions.

#### File type

The `file` keyword denotes a file at the file system of the computer. It allows reading and writing values of many data types (not all data types can be read or written). Expressions with files are explained in File handle expressions. How to work with files is explained in Input and output.

#### Instance type

The `inst` keyword denotes an instance type, it can store a running process. Its use is to check whether the stored process has ended. The Finish statement gives more details and provides an example.

#### Timer type

The `timer` keyword denotes a count-down timer. Variables of this type measure time that has passed since their initialization. Expressions with timers are given in Timer expressions, a tutorial about using timers can be found in Timers.

#### Matrix type

The `matrix` type takes two constant expressions that define the number of rows and the number of columns of the matrix. The main purpose of the data type is to allow temporary storage of matrices so they can be passed on to other software. The Chi language also has expressions to write literal matrices, see Matrix expression for details.

#### Void type

The `void` type denotes that no data is involved. Values of type `void` do not exist. The type is allowed at two places in the Chi specification, namely:

- As data type of synchronization channels. Further explanation can be found at Communication statements and Channel type.

- As exit type of Model definitions and Process definitions, to express that it may return an exit value from an Exit statement without arguments.

### Container types

The main function of container types is to organize and hold a collection of values of another type (the element type). The syntax diagram of the container types is as follows.

The language has three container types, lists (explained in List type), sets (explained in Set type), and dictionaries (explained in Dictionary type).

#### List type

The list type has an ordered collection of values from its element type as its value. Duplicate element values are allowed.

The syntax of a list type is given below.

It starts with the keyword `list`, optionally followed by a parenthesized (non-negative) integer expression denoting the initial number of element values in the collection, and finally the type of the element values.

The default size of the collection is the value of the integer expression, or 0 if there is no such expression. The value of the elements in the initial list value depends on the type of the elements.

A few examples:

    list bool    # A list of boolean values, initial value is <bool>[]
    list (2) int # A list of integer values, initial value is [0, 0]

For a discussion of operations on values of this type, see List expressions.

#### Set type

The set type has an unordered collection of values from its element type as its value. Duplicate element values are silently discarded.

The syntax of the set type is given below.

The set type starts with a `set` keyword, followed by the type of its elements. Its initial value is the empty set. An example:

    set real  # A set of real numbers, initial value <real>{}.

For a discussion of operations on values of this type, see Set expressions.

#### Dictionary type

The dictionary type has an unordered collection of values of its key type, so called keys. The keys are unique in the collection. In addition, the dictionary has a value of its value type associated with each key.

The syntax of a dictionary type is given below.

The syntax starts with a `dict` keyword, and the key type and value type between parentheses, separated by a colon. The initial value of a dictionary type is the empty dictionary. An example:

    dict (bool : int)  # A dictionary with boolean keys, and integer values.
                       # Initial value <bool:int>{}.

For a discussion of operations on values of this type, see Dictionary expressions.

### Tuple type

A tuple contains a fixed number of values of (possibly) different types. It has the following syntax:

A tuple type starts with the keyword `tuple`, followed by the list of its fields between parentheses. Each field has a name and a type. Sequences of fields with the same type can share their type description, which reduces the amount of text of the tuple type. Tuple types must have at least two fields.

Examples:

    tuple(int a, b)      # A tuple containing fields 'a' and 'b', both of type int
    tuple(int a; int b)  # A tuple containing fields 'a' and 'b', both of type int

    tuple(lot x; real start) # A tuple with a 'lot' and a 'real' type.

The first two examples are equivalent, the first form is just a bit shorter in notation. The third example is more common fields of different types that are kept together in the modeled system. Expressions with tuples are discussed in Tuple expression.

### Channel type

The channel type defines the direction and the type of values transported. The syntax of the channel type is as follows.

The `chan` keyword denotes a channel type is being created. It may be followed by allowed directions of transport, a `!` means that sending values is allowed but not for receiving, and a `?` means that receiving values is allowed and sending is not allowed. Finally `!?` means both sending and receiving is allowed. The latter is also selected when no direction is specified. The language silently discards allowed directions. A channel usable for both sending and receiving may be used as a channel for sending only (dropping the ability to receive at that point). It does not allow adding directions, a receive-only channel cannot be used for sending. It can also not be used as a channel for sending and receiving, even if then latter is only used for receiving values (that is, sending is never done).

The type of data that is transported with a communication is given by the `Type` block. Signalling channels (that only synchronize without transporting data) are indicated by the `void` keyword. The only expressions available for channels are the equality tests, and a function to create new channels, see Channel expressions for details.

### Distribution type

The distribution type represents a stochastic distribution. It has the following syntax:

A stochastic distribution allows modeling of random behavior, but with a known chance distribution. The `Type` block in the `DistributionType` diagram defines the type of values drawn. For a discussion of expressions for the distribution type, see Distribution expressions.

### Function type

The function type can hold a function. Its syntax is as follows.

A function type starts with the keyword `func` followed by the return type of the function and the type of the formal parameters. The purpose of the function type is to pass functions to processes or other functions, for example, the predicate function in `sort` and `insert`, see List functions.

### Process type

The process type is similar to the function type (discussed in Function type), except this type can hold a process definition. It has the following syntax:

The type starts with the keyword `proc` followed by the formal parameters of the process definition to store between parentheses. Expressions with process types are explained in Process expressions.