## 6.10 Type Inference

Stan is strongly statically typed, meaning that the implementation type of an expression can be resolved at compile time.

### Implementation Types

The primitive implementation types for Stan are

`int, real, vector, row_vector, matrix.`

Every basic declared type corresponds to a primitive type; see the primitive type table for the mapping from types to their primitive types.

**Primitive Type Table.** *The table shows the variable declaration types of Stan and their corresponding primitive implementation type. Stan functions, operators, and probability functions have argument and result types declared in terms of primitive types plus array dimensionality.*

type | primitive type |
---|---|

`int` |
`int` |

`real` |
`real` |

`matrix` |
`matrix` |

`cov_matrix` |
`matrix` |

`corr_matrix` |
`matrix` |

`cholesky_factor_cov` |
`matrix` |

`cholesky_factor_corr` |
`matrix` |

`vector` |
`vector` |

`simplex` |
`vector` |

`unit_vector` |
`vector` |

`ordered` |
`vector` |

`positive_ordered` |
`vector` |

`row_vector` |
`row_vector` |

A full implementation type consists of a primitive implementation type and an integer array dimensionality greater than or equal to zero. These will be written to emphasize their array-like nature. For example, `int[]`

has an array dimensionality of 1, `int`

an array dimensionality of 0, and `int[ , ,]`

an array dimensionality of 3. The implementation type `matrix[ , , ]`

has a total of five dimensions and takes up to five indices, three from the array and two from the matrix.

Recall that the array dimensions come before the matrix or vector dimensions in an expression such as the following declaration of a three-dimensional array of matrices.

`matrix[M, N] a[I, J, K];`

The matrix `a`

is indexed as `a[i, j, k, m, n]`

with the array indices first, followed by the matrix indices, with `a[i, j, k]`

being a matrix and `a[i, j, k, m]`

being a row vector.

### Type Inference Rules

Stan’s type inference rules define the implementation type of an expression based on a background set of variable declarations. The rules work bottom up from primitive literal and variable expressions to complex expressions.

#### Literals

An integer literal expression such as `42`

is of type `int`

. Real literals such as `42.0`

are of type `real`

.

#### Variables

The type of a variable declared locally or in a previous block is determined by its declaration. The type of a loop variable is `int`

.

There is always a unique declaration for each variable in each scope because Stan prohibits the redeclaration of an already-declared variables.^{3}

#### Indexing

If `x`

is an expression of total dimensionality greater than or equal to \(N\), then the type of expression `e[i1, ..., iN]`

is the same as that of `e[i1]...[iN]`

, so it suffices to define the type of a singly-indexed function. Suppose `e`

is an expression and `i`

is an expression of primitive type `int`

. Then

if

`e`

is an expression of array dimensionality \(K > 0\), then`e[i]`

has array dimensionality \(K-1\) and the same primitive implementation type as`e`

,if

`e`

has implementation type`vector`

or`row_vector`

of array dimensionality 0, then`e[i]`

has implementation type`real`

, andif

`e`

has implementation type`matrix`

, then`e[i]`

has type`row_vector`

.

#### Function Application

If `f`

is the name of a function and `e1,...,eN`

are expressions for \(N \geq 0\), then `f(e1,...,eN)`

is an expression whose type is determined by the return type in the function signature for `f`

given `e1`

through `eN`

. Recall that a function signature is a declaration of the argument types and the result type.

In looking up functions, binary operators like `real * real`

are defined as `operator*(real,real)`

in the documentation and index.

In matching a function definition, arguments of type `int`

may be promoted to type `real`

if necessary (see the subsection on type promotion in the function application section for an exact specification of Stan’s integer-to-real type-promotion rule).

In general, matrix operations return the lowest inferable type. For example, `row_vector * vector`

returns a value of type `real`

, which is declared in the function documentation and index as `real operator*(row_vector,vector)`

.

Languages such as C++ and R allow the declaration of a variable of a given name in a narrower scope to hide (take precedence over for evaluation) a variable defined in a containing scope.↩