diff --git a/chapters/interface.tex b/chapters/interface.tex index e760b03bd..6cb7cdc93 100644 --- a/chapters/interface.tex +++ b/chapters/interface.tex @@ -585,45 +585,51 @@ \section{Function-Compatibility or Function-Subtyping for Functions}\label{funct \section{Type Compatible Expressions}\label{type-compatible-expressions} -Certain expressions consist of an operator applied to two or more type compatible subexpressions (\lstinline!A! and \lstinline!B!), including binary operators, e.g. \lstinline!A + B!, \lstinline!if!-expressions, e.g.\ \lstinline!if x then A else B!, and array expressions, e.g.\ \lstinline!{A, B}!. -The resulting type of the expression in case of two type compatible subexpressions \lstinline!A! and \lstinline!B! is defined as follows: +Certain expressions consist of an operator applied to two or more subexpressions (\lstinline!A! and \lstinline!B!). +This includes: +\begin{itemize} +\item \lstinline!if!-expressions, e.g.\ \lstinline!if x then A else B!. +\item Array expressions, e.g.\ \lstinline!{A, B}! +\item Binary operators if both operands are of simple types, e.g.\ \lstinline!A + B!. +Binary operators for other types are only defined for operator records, \cref{overloaded-binary-operations}, and do not necessarily require that the operands are type compatible with each other. +\end{itemize} +If the subexpressions satisfy the following restrictions they are called type compatible expressions. +Otherwise the expression is illegal. +The type of the full expression (e.g.\ \lstinline!if x then A else B!) is also defined below. \begin{itemize} \item - If \lstinline!A! is a record expression \lstinline!B! must also be a record expression with the same named elements. The type compatible expression is a record comprised of named elements that are compatible with the corresponding named elements of both \lstinline!A! and \lstinline!B!. - In an array expression the two records may contain elements with different sizes, but apart from that they must be of compatible types. + If \lstinline!A! is a record expression, \lstinline!B! must also be a record expression with the same named elements. + In an expression that is not an array expression those elements must be type compatible. + In an array expression the two records may contain elements with different sizes, but apart from that they must be type compatible. That generates a heterogenous array of records, see \cref{arrays}. -\item - If \lstinline!A! is an array expression then \lstinline!B! must also be an array expression, and \lstinline!ndims(A)! = \lstinline!ndims(B)!. - The type compatible expression is an array expression with elements compatible with the elements of both \lstinline!A! and \lstinline!B!. - If both \lstinline!size(A)! and \lstinline!size(B)! are known and \lstinline!size(A)! = \lstinline!size(B)! then this defines the size of the type compatible expression, otherwise the size of the expression is not known until the expression is about to be evaluated. - In case of an \lstinline!if!-expression the size of the type compatible expression is defined based on the branch selected, and for other cases \lstinline!size(A)! = \lstinline!size(B)! must hold at this point. -\item - If \lstinline!A! is a scalar expression of a simple type \lstinline!B! must also be a scalar - expression of a simple type. -\item - If \lstinline!A! is a \lstinline!Real! expression then \lstinline!B! must be a \lstinline!Real! or \lstinline!Integer! expression - and the type compatible expression is \lstinline!Real!, compare \cref{standard-type-coercion}. + The type of the full expression is a record comprised of named elements that are type compatible with the corresponding named elements of both \lstinline!A! and \lstinline!B!. +\item The rules for array expressions depend on the operation (the rules for binary operators are given in \cref{scalar-vector-matrix-and-array-operator-functions} +and for array concatenation in \cref{array-concatenation}). +The rules for the remaining case of \lstinline!if!-expressions and array-expressions are: +\begin{itemize} + \item If \lstinline!A! is an array expression then \lstinline!B! must also be an array expression, and \lstinline!ndims(A)! = \lstinline!ndims(B)!. + The type of the full expression is an array expression with elements compatible with the elements of both \lstinline!A! and \lstinline!B!. + If both \lstinline!size(A)! and \lstinline!size(B)! are known and \lstinline!size(A)! = \lstinline!size(B)! then this defines the size of the full expression, otherwise the size of the full expression is not known until the expression is about to be evaluated. + In case of an \lstinline!if!-expression the size of the full expression is defined based on the branch selected, and for other cases \lstinline!size(A)! = \lstinline!size(B)! must hold at this point. + \item If \lstinline!A! is a scalar expression of a simple type \lstinline!B! must also be a scalar expression of a simple type. +\end{itemize} +\item If \lstinline!A! is a \lstinline!Real! expression then \lstinline!B! must be a \lstinline!Real! or \lstinline!Integer! expression. + The type of the full expression is \lstinline!Real!, compare \cref{standard-type-coercion}, unless the operator is a relational operator (\cref{equality-relational-and-logical-operators}) where the type of the full expression is \lstinline!Boolean!. \item If \lstinline!A! is an \lstinline!Integer! expression then \lstinline!B! must be a \lstinline!Real! or \lstinline!Integer! expression. - For exponentiation and division the type compatible expression is \lstinline!Real! (even if both \lstinline!A! and \lstinline!B! are \lstinline!Integer!) see \cref{element-wise-exponentiation} and \cref{division-by-numeric-scalars}, in other cases the type compatible expression is \lstinline!Real! or \lstinline!Integer! (same as \lstinline!B!), compare \cref{standard-type-coercion}. + For exponentiation and division the type of the full expression is \lstinline!Real! (even if both \lstinline!A! and \lstinline!B! are \lstinline!Integer!) see \cref{element-wise-exponentiation} and \cref{division-by-numeric-scalars}, for relational operators the type of the full expression is \lstinline!Boolean!. + In other cases the type of the full expression is \lstinline!Real! or \lstinline!Integer! (same as \lstinline!B!), compare \cref{standard-type-coercion}. \item - If \lstinline!A! is a \lstinline!Boolean! expression then \lstinline!B! must be a \lstinline!Boolean! expression and - the type compatible expression is \lstinline!Boolean!. + If \lstinline!A! is a \lstinline!Boolean! expression then \lstinline!B! must be a \lstinline!Boolean! expression and the type of the full expression is \lstinline!Boolean!. \item - If \lstinline!A! is a \lstinline!String! expression then \lstinline!B! must be a \lstinline!String! expression and the - type compatible expression is \lstinline!String!. + If \lstinline!A! is a \lstinline!String! expression then \lstinline!B! must be a \lstinline!String! expression and the type of the full expression is \lstinline!String!, unless the operator is a relational operator (\cref{equality-relational-and-logical-operators}) where the type of the full expression is \lstinline!Boolean!. \item - If \lstinline!A! is an enumeration expression then \lstinline!B! must be an enumeration - expression and the type compatible expression is enumeration - expression, and all enumeration expressions must be defined in terms - of an enumeration type with the same enumeration literals in the same - order. + If \lstinline!A! is an enumeration expression then \lstinline!B! must be an enumeration expression and the type of the full expression is enumeration expression, unless the operator is a relational operator (\cref{equality-relational-and-logical-operators}) where the type of the full expression is \lstinline!Boolean!. + The enumeration expressions must be defined in terms of an enumeration type with the same enumeration literals in the same order. \item - If \lstinline!A! has an \lstinline!operator record! base class then \lstinline!B! must also have an \lstinline!operator record! base class, and it must be the same, and otherwise neither \lstinline!A! nor \lstinline!B! may have an \lstinline!operator record! base class. - This is also the \lstinline!operator record! base class for the expression e.g.\ for \lstinline!if (cond) then A else B!. + For array and \lstinline!if!-expressions, if \lstinline!A! has an \lstinline!operator record! base class then \lstinline!B! must also have an \lstinline!operator record! base class, and it must be the same, and otherwise neither \lstinline!A! nor \lstinline!B! may have an \lstinline!operator record! base class. + This is also the \lstinline!operator record! base class for the full expression e.g.\ for \lstinline!if (cond) then A else B!. \item - If \lstinline!A! is derived from \lstinline!ExternalObject! then \lstinline!B! must also be derived from - \lstinline!ExternalObject! and they must have the same full name; and otherwise - neither \lstinline!A! nor \lstinline!B! may be derived from \lstinline!ExternalObject!. The common full - name also defines the type of the expression, e.g.\ for \lstinline!if (cond) then A else B!. + If \lstinline!A! is derived from \lstinline!ExternalObject! then \lstinline!B! must also be derived from \lstinline!ExternalObject! and they must have the same full name; and otherwise neither \lstinline!A! nor \lstinline!B! may be derived from \lstinline!ExternalObject!. + The common full name also defines the type of the full expression, e.g.\ for \lstinline!if (cond) then A else B!. \end{itemize}